NoWar
NoWar

Reputation: 37633

How to reset <input type='file' /> in ASP.NET MVC

I just checked all options to reset/clean <input type='file' /> based on

Clearing <input type='file' /> using jQuery

And all of them are not working.

What I do in my page is submit new file and update page in a normal way.

HTML

<form>
 <input type="file" name="file" id="fileUploader" class="btn btn-sm btn-default" />
</form>

And then I have AJAX link to delete uploaded file. So I delete it in Session and in AJAX callback do like

 //Reset
 var uploader = $("#fileUploader");
 window.reset = function (uploader) {
            e.wrap('<form>').closest('form').get(0).reset();
            e.unwrap();
 }
 uploader.reset();

 // Clear all file fields:
 // $("input:file").clearInputs();

 // Clear also hidden fields:
 //$("input:file").clearInputs(true);

 //$row.replaceWith($row = $row.val('').clone(true));

But after this when I do F5 / Update HttpPost happens and it has posted file.

How to fix it?

P.S. And even if I do the following no joy...

 $('#inputFileForm').html("");

                $('#inputFileForm').append(
                    //  <input type="file" name="file" id="fileUploader" class="btn btn-sm btn-default" />
                    $('<input/>').attr('type', 'file').attr('name', 'file').class("btn btn-sm btn-default")
           );

Upvotes: 0

Views: 3841

Answers (2)

code4coffee
code4coffee

Reputation: 677

I'm going to step outside of the box for a moment and offer a solution to your problem that uses the FormData() object. It will store multiple files as a key/value. You'll want to make sure your target audience can support it (check Can I Use for reference). Per MDN,

XMLHttpRequest Level 2 adds support for the new FormData interface. FormData objects provide a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest send() method. [Source: MDN]

First, you'll want to instantiate the object to store your files. We'll create a new FormData() object:

var formData = new FormData();

Next, you'll want to iterate through each file in your file input box:

// your input
var myInput = document.getElementById("fileUploader");
for (i = 0; i < myInput.files.length; i++) {
  // iterate through each file in the input
  // and append it to the new FormData() object
  formData.append(myInput.files[i].name, myInput.files[i]);
  // files[i].name will assign the key of "myfile.png"
  // files[i] will assign the value of your your file
}

Now you have all of your files in one object that can be uploaded directly via XMLHttpRequest or $.ajax. For example:

var xhr = new XMLHttpRequest();
xhr.open('POST', ajaxPostPath);
xhr.send(formData);
xhr.onreadystatechange = function () {
   if (xhr.readyState == 4 && xhr.status == 200) {
      // hooray! it worked!
   }
}

Now, all you need to do is instantiate a new FormData() object each time you need to submit.

So, if you have a submit button...

$(document).ready(function() {
   $("#mySubmitBtn").on("click", function() {
      var myInput = document.getElementById("fileUploader");
      for (i = 0; i < myInput.files.length; i++) {
          formData.append(myInput.files[i].name, myInput.files[i]);
      }
      var xhr = new XMLHttpRequest();
      xhr.open('POST', ajaxPostPath);
      xhr.send(formData);
      xhr.onreadystatechange = function () {
      if (xhr.readyState == 4 && xhr.status == 200) {
         // hooray! it worked!
      }
    }
   });
});

Again, this is entirely another route to take with this but it'll allow you to completely have control over what files are being sent to the server without having to worry about the inconsistencies of IE/Chrome/FF and resetting of the File input type. If you'd like to see an example, I have a semi readable script you can look at here.

Upvotes: 1

adeneo
adeneo

Reputation: 318162

The only sure way to clear a file input is to replace the element, as some browsers (mostly IE) will not allow you to reset the value of a file input

var input = $("#fileUploader");

input.replaceWith(input.clone(true));

This keeps the events but clears the input value (values are not cloned)

Upvotes: 3

Related Questions