0

Today I accidentally found out that when you have a input with type file, and when you have chosen a file and then click the file button again but this time click cancel, the origin file is replaced and the file input remain no file chosen, which is pretty annoying especially I have something like a image preview with original image, and when the users do something like I mentioned before, they end up with nothing being uploaded.

<input type="file" />

I'm thinking using a hidden input to save the original file, like

<input type="file" id="origin"> <!--this would be hidden and  save the file--> 
<input type="file" ><!--show it to the user-->

and when I upload the image, I select the origin one and upload it..It's any better way to handle this situation?

Déjà vu
  • 774
  • 2
  • 9
  • 31
Kesong Xie
  • 1,316
  • 3
  • 15
  • 35
  • 1
    Why the JavaScript and jQuery tags? I see none. – j08691 Aug 26 '14 at 13:34
  • I think this is as designed. You actually can't programmatically set the value of an `input` with type `file`. For example, on MDN [You can't set the value of a file picker from a script;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input). Also see: http://stackoverflow.com/questions/1017224/dynamically-set-value-of-a-file-input – Matt Burland Aug 26 '14 at 13:43

2 Answers2

1

I was able to find a work around for Chrome's annoying removing file when cancel pressed that has existed for years...

JSFiddle: https://jsfiddle.net/dqL97q0b/1/

<!doctype html><html><head></head><body>

<h2>Fix for Chrome Removing File when 'cancel' clicked</h2>

Upload Image: <input id="imageUpload" type="file" onclick="fileClicked(event)" onchange="fileChanged(event)">
<br/><br/>
<label for="videoUpload">Upload Video:</label> <input id="videoUpload" type="file" onclick="fileClicked(event)" onchange="fileChanged(event)">
<br/><br/>
<div id="log"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
    //This is All Just For Logging:
    var debug = true;//true: add debug logs when cloning
    var evenMoreListeners = true;//demonstrat re-attaching javascript Event Listeners (Inline Event Listeners don't need to be re-attached)
    if (evenMoreListeners) {
        var allFleChoosers = $("input[type='file']");
        addEventListenersTo(allFleChoosers);
        function addEventListenersTo(fileChooser) {
            fileChooser.change(function (event) { console.log("file( #" + event.target.id + " ) : " + event.target.value.split("\\").pop()) });
            fileChooser.click(function (event) { console.log("open( #" + event.target.id + " )") });
        }
    }

    var clone = {};

    // FileClicked()
    function fileClicked(event) {
        var fileElement = event.target;
        if (fileElement.value != "") {
            if (debug) { console.log("Clone( #" + fileElement.id + " ) : " + fileElement.value.split("\\").pop()) }
            clone[fileElement.id] = $(fileElement).clone(); //'Saving Clone'
        }
        //What ever else you want to do when File Chooser Clicked
    }

    // FileChanged()
    function fileChanged(event) {
        var fileElement = event.target;
        if (fileElement.value == "") {
            if (debug) { console.log("Restore( #" + fileElement.id + " ) : " + clone[fileElement.id].val().split("\\").pop()) }
            clone[fileElement.id].insertBefore(fileElement); //'Restoring Clone'
            $(fileElement).remove(); //'Removing Original'
            if (evenMoreListeners) { addEventListenersTo(clone[fileElement.id]) }//If Needed Re-attach additional Event Listeners
        }
        //What ever else you want to do when File Chooser Changed
    }
    </script>
</body></html>

Most of the JSFiddle is just for logging.

The Way it works is if the file Chooser has a value when onClick happense then a Clone of the file chooser is made and stored in the var clone{}; based on the file chooser's id. Then when a Change Event happense and the file Chooser value is "" (Which would only happen on Chrome) then we replace the Original file Chooser with the clone.

Nick Timmer
  • 425
  • 2
  • 12
0

For security reasons, you can't set the value of an input with type file. The best you might be able to do is intercept the change event and store the value in a separate variable, but this still will give you a "No file chosen" next to your input.

For example:

var selected;

$("input").change(function() {
    var now = $(this).val();
    if (now){
        selected = now;
        $("#selected")[0].innerHTML = now;
    }
});

http://jsfiddle.net/v0j6e385/

It is pretty annoying that canceling doesn't restore the original value (at least in Chrome).

Update: a little experimentation with IE and Firefox and it appears this problem is restricted to Chrome. Firefox and IE won't clear the selected value if you hit cancel. Not sure what the standards actually say about that.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171