2

My current code can only remove the files from the HTML client slide, but not the actual file list. Meaning, even the file is remove visually, but when I upload it, the file is still remains uploaded.

What can I do to upload from the file list so that removed file will not upload once I hit the button Upload?

1 Answer 1

1

An HTMLInputElement with type="file" produces a FileList object that contains the list of files. The FileList object is a read only object that cannot be modified.

So while you can remove the file from your custom list array and use the shorted list to build your UL, you cannot modify the FileList that is a property of the HTMLInputElement.

So, the solution is to create a new FormData() object, populate that with your form elements, and then append the list of files to the form element individually.

Something like this should work:

var formData = new FormData();
var fileList = [];
var fileInput = document.querySelector('input[type="file"]');

fileInput.addEventListener('change', setList);
document.querySelector('form').addEventListener('submit', sendModifiesList);

function setList() {
  //Convert the FileList Object to an Array of File Objects
  fileList = Array.from(fileInput.files);
  outputList();
}


function sendModifiesList(e) {
  e.preventDefault();
  fileList.forEach(function(file) {
    formData.append('fileList[]', file);
  });
  console.log("These files will be posted: ", formData.getAll("fileList[]"));
  /*************** EDIT *************************/
  // Get the url from the form's action attribute
  let url = document.forms[0].action;
  let request = new XMLHttpRequest();
  // Create a POST request
  request.open("POST", url);
  // Set up an onload handler to report status
  request.onload = function() {
    if (request.status == 200) {
      console.log("Uploaded!");
    } else {
      console.log("Error " + request.status + " occurred when trying to upload your file.");
    }
  };
  // Send the form to the server 
  request.send(formData);
  /************ END EDIT ***********************/
};

function outputList() {
  var output = document.getElementById('fileList');
  var nodes = document.createElement('ul');
  fileList.forEach((file, i) => {
    var node = document.createElement('li');
    var filename = document.createTextNode(file.name);
    var removeLink = document.createElement('a');
    removeLink.href = 'javascript:void(0)';
    removeLink.innerHTML = 'Remove';
    removeLink.onclick = function() {
      // Remove item
      fileList.splice(i, 1);
      outputList();
    }
    node.appendChild(filename);
    node.appendChild(removeLink);
    nodes.appendChild(node);
  });
  output.innerHTML = '';
  output.appendChild(nodes);
}
<form action="/test.aspx">
  <input type="file" multiple>
  <input type="submit">
</form>
<div id="fileList"></div>

Sign up to request clarification or add additional context in comments.

6 Comments

Hi, thanks for helping out! I tried implement your solution, but the bullet lists of files did not show. I'm using Asp.NET MVC, is there something I missed? Thanks.
Hi Randy Casbun, I managed to get your codes to work. But how do I pass the files values to the Controller? Your script doesn't allow me to POST back.
@Matt - I've edited the code in the answer. Look for /*** EDIT ***/. It now 1. retrieves the form's action attribute to use as the URL to submit the form to; 2. creates an AJAX request; 3. sets up onload handler to report success; 4 Sends the form with the files attached. This will fail on stackoverflow, so you will need to replace the URL with your server's endpoint URL for your controller. That should do it.
Randy Casbun how do I call for you if I have further questions that is related to JS and jQuery?
You are welcome to find me on LinkedIn and message me there.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.