How to pass javascript array to form and get the values in php?

Asked

Viewed 1,124 times

0

I have a form that creates a list of selected images before sending through an input type='file'

However how can I pass the Array Javascript to the form and submit it by clicking on action?

I need to rescue the array sent in php in php itself

var nomess = [];

function handleFileSelect() {
    var output = document.getElementById("resultt");
    arquivos = $("#imagem").prop("files");
    var nomes = $.map(arquivos, function(val) { return val.name; });

    //new
    var filesStr = "";
    for (let i = 0; i < arquivos.length; i++) {
        var extensao = nomes[i].split('.').pop().toLowerCase();
        if(extensao == "doc" || extensao == "docx"){
            icone = "http://www.programari.com.br/assets/images/icons/word.png";
        }else if(extensao == "jpg" || extensao == "jpeg"){
            icone = "http://www.programari.com.br/assets/images/icons/jpg.png";
        }else if(extensao == "png"){
            icone = "http://www.programari.com.br/assets/images/icons/png.png";
        }else if(extensao == "xml"){
            icone = "http://www.programari.com.br/assets/images/icons/xml.png";
        }else if(extensao == "gif"){
            icone = "http://www.programari.com.br/assets/images/icons/gif.png";
        }else if(extensao == "pdf"){
            icone = "http://www.programari.com.br/assets/images/icons/pdf.png";
        }else if(extensao == "bmp"){
            icone = "http://www.programari.com.br/assets/images/icons/bmp.png";
        }else if(extensao == "txt"){
            icone = "http://www.programari.com.br/assets/images/icons/txt.png";
        }else if(extensao == "xlsx" || extensao == "xls"){
            icone = "http://www.programari.com.br/assets/images/icons/xls.png";
        }else{
            icone = "http://www.programari.com.br/assets/images/icons/file.png";
        }
        nomess.push(arquivos[i]);
        filesStr += "<li>" + arquivos[i].name + "<button onclick='removeLiy(this)' style='background-color:white; border:0'><i class='fas fa-trash' style='color:red; font-size: 24px; padding: 8px 0px 0px 3px;'></i></button><img src='"+icone+"' height='24' />" + "</li>";
    }

    console.log(nomess);

    document.getElementById("imagem").value = "";
    document.getElementById("resultt").innerHTML += filesStr;

}

function removeLiy(e) {
        nomess = nomess.filter(function(imagem) {
        return imagem.name !== e.parentNode.innerHTML.split("<button")[0];

        console.log(nomess);

    })
    e.parentNode.parentNode.removeChild(e.parentNode);
    console.log(nomess);

}

document.getElementById('imagem').addEventListener('change', handleFileSelect, true);
<form id="formExemplo" action="nova-acao/salvar'" method="post" enctype="multipart/form-data" data-toggle="validator" role="form">

    <div class="col-md-4 form-group">

        <input type="file" onchange="handleFileSelect" name="imagem" id="imagem" style="" multiple="multiple">

    </div>

</form>

  • You just want to send input file values to the page that receives PHP or exactly want to pass in js to send?

  • i wanted to take the js array and somehow create or populate an input file, soon after when I click submit it should send the other fields and this with the arrays. these arrays are images with no extension restriction...

  • @Eliseu B. you know how it should be done?

  • sorry for the delay, the solution below meets your need, if it works please give the vote of reply accepted.

3 answers

2

I handled here exclusively the task of adding a new input type="file" already "populated", as it seems you need.

Every new file added in input name="imagem", is performed a clone of it within the <form> and reset the "original input value".

You can check by running here: https://jsfiddle.net/emanuelpoletto/doc85uxe/18/

You can hide the new input via CSS. I just didn’t do it there to help with the teaching of the answer. So the behavior is visible. I hope it helps.

$('#imagem').on('change', function() {
  if ($(this).val()) {
    let form = $('#formExemplo'),
      newFile = $(this).clone(),
      newName = 'imagem' + form.find('[name="imagem"]').length;
    newFile.removeAttr('id')
      .attr('name', newName)
    //.css('display', 'none');
    $('#formExemplo').append(newFile);
    $(this).val('');
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formExemplo" action="" method="post" enctype="multipart/form-data">
  <input type="file" name="imagem" id="imagem" multiple="multiple">
</form>

  • Hide the inputs of the clone ok I can easily.

  • Yes, @Richardbarcelos I turned on that step of form + javascript because it was the code you shared. I hope you can test the upload this way. I think the handling of the POST in PHP would be another topic. But if you need help I can also try to lend a hand.

  • All right, buddy, thanks. At the beginning of this post I show the java code that shows the name of the attachment, put a delete button and it deletes the array and the information as weight of the selected file, did you see? Ali tbm i delete. in that code my idea is to pass this array to form or create a Session something that I can recover in php later.. with a single $rr= $_FILES['nomess'];

  • I saw your print below (my punctuation here only allows you to comment on my own questions/answers for while hehe) If you say it’s okay to use an input type="file" without the attribute multiple to treat 1 file at a time, I can elaborate more this response to solve your demand as a whole.

  • If we use Multiple you think it doesn’t work?

  • don’t have a chat around here tbm no? rsrs

  • Using the Multiple: can be that you have multiple files in the same input. How to remove 1 single input file when necessary? Unfortunately, you don’t have the complete file paths (by analyzing your print and testing on the inspector here tbm).

  • NOT using the Multiple: you will have an input for each file. So if you want to remove 1 file, just remove the tbm input and it’s solved.

  • I understood what you said, the more you saw that I already delete the files? type if I raise 4 I can delete only the second.. saw in the log that array 2 would be deleted... you saw?

  • the Multiple is important...

  • I saw that you treat everything on array and theoretically it would work. Only you can’t bring back the array to the form because the browser does not provide the complete path of each file. The probability is that PHP will receive only the names and not the files themselves. This is the clash of your approach. Dude, I can even make another attempt here to solve maintaining the Multiple. But it might take a little while... I don’t know if I can answer today. I’ll do ASAP.

  • ASAP ? ok :) I wait

  • @Richardbarcelos elaborated a new more complete answer that solved the upload with Multiple :) The solution is to use Ajax even to submit the files. Check out: https://answall.com/a/363895/45707

  • OK just saw now, I’ll check and return

Show 9 more comments

0

inserir a descrição da imagem aqui

@emanuelpoletto Here I show that the array is with the file information.. no?

  • I want to click include actions and send the attachments from the list

0

Browsers cannot handle a filelist input[type=file]. We can maintain your approach by generating the array with the files. But you can’t return the same array after the input[type=file], altering or even keeping intact the list of files.

The solution is to send these files via Ajax. The rest of the form can be submitted normally or by Ajax as well, whatever.

Based on the code of the question, I drafted that answer that does just that:

  • captures the list of files each change of input;
  • sends the list of files via Ajax on submit of form;
  • submits the "rest" of the form normally after uploading the files.

var form = document.getElementById('formExemplo'),
    formSubmit = false,
    files = [],
    filesSentOk = 0,
    filesSentError = 0;

document.getElementById('imagem').addEventListener('change', function(event) {
  let output = document.getElementById('result');

  for (let i = 0; i < this.files.length; i++) {
    let name = this.files[i].name,
        ext  = name.split('.').pop().toLowerCase(),
        icon = 'http://www.programari.com.br/assets/images/icons/';

    switch (ext) {
      case 'jpg'  :
      case 'png'  :
      case 'xml'  :
      case 'gif'  :
      case 'pdf'  :
      case 'bmp'  :
      case 'txt'  :
      case 'xls'  : icon += ext; break;
      case 'doc'  :
      case 'docx' : icon += 'word'; break;
      case 'jpeg' : icon += 'jpg'; break;
      case 'xlsx' : icon += 'xls'; break;
      default     : icon += 'file';
    }
    icon += '.png';

    files.push(this.files[i]);
    output.innerHTML += '<li>' + name + '<button onclick="removeLiy(this)" style="background-color:white; border:0"><i class="fas fa-trash" style="color:red; font-size: 24px; padding: 8px 0px 0px 3px;"></i></button><img src="' + icon + '" height="24" /></li>';
  }

  this.value = '';
});

function removeLiy(el) {
  let index = Array.from(el.parentNode.children).indexOf(el);

  files.splice(index, 1);
  el.parentNode.remove();
}

form.addEventListener('submit', function(event) {
  if (formSubmit) {
    return;
  }

  event.preventDefault();

  files.forEach(function(file) {
    sendFile(file);
  });

  var interval = setInterval(function() {
    if ((filesSentOk + filesSentError) >= files.length) {
      clearInterval(interval);
      if (filesSentError <= 0) {
        formSubmit = true;
        form.submit();
      } else {
        alert('Erro ao enviar arquivo(s). Confira o console log.');
      }
    }
  }, 500);

  return false;
});

function sendFile(file) {
  let formData = new FormData(),
      request = new XMLHttpRequest();

  request.onreadystatechange = function() {
    // if (this.readyState == 4 && this.status == 200) {
      let states = [
        'request not initialized',
        'server connection established',
        'request received',
        'processing request',
        'request finished and response is ready'
      ];
      console.log('File: ' + file.name + '; State: ' + this.readyState + ' (' + states[this.readyState] + '); Status: ' + this.status + ' (' + this.statusText + ')' );
      if (this.readyState == 4) {
        if (this.status == 200) {
          filesSentOk++;
        } else {
          filesSentError++;
        }
      }
      // console.log('Response: ' + this.responseText);
    // }
  };

  formData.set('imagem', file);
  request.open('POST', form.getAttribute('action'));
  request.send(formData);
};
<link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet"/>
<form id="formExemplo" action="http://example.com" method="post" enctype="multipart/form-data">
    <div class="col-md-4 form-group">
        Input de texto para teste: <input type="text" name="campo_qualquer_para_teste" value="Lorem ipsum dolor sit amet">
        <br><br>
        <input type="file" name="imagem" id="imagem" multiple="multiple">
        <br><br>
        <input type="submit" value="Enviar">
    </div>
</form>
<ul id="result"></ul>

IMPORTANT: There is no validation, either on the front or back end. For example, if Ajax returns that the request was successfully sent and obtained HTTP status 200 from the server does not necessarily mean that the upload was successful. The ideal is to increase the necessary validations before running in production :)

  • Nice to then increment something visual that signals "loading" to the user by clicking on Ubmit to let them know what’s going on while the files are going up. You can even flag the files one by one as they go up. The upload via Ajax is running asynchronous there, so the files will go up in parallel and consequently faster ;)

  • With this format I send the other form fields separately? in this case I save the attachments and then the other fields?

  • Exact. In this approach, in the form Submit it sends the files (one by one) and finally sends all the rest of the form, all in sequence, in a single click. You only have to handle this in the back end. The number of requests PHP will receive depends on the amount of files added ;)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.