input type="file", clearing file after clicking cancel in chrome

google-chrome, html

Solution

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

Here is a work around, so that Chrome cannot remove the users existing file when cancel is pressed.

Code Notes: This makes a clone of the Dom Element when User opens the file chooser if there is already a file selected. Then if the user does click cancel in chrome it fires the change Event Listener and the value Will be "", so in that specific case I remove the now empty file chooser, and restore the clone.

Note: each file chooser Dom Element needs a unique id, so that the clone can be stored and retrieved properly.

Note: Most of the code is just logging, to show how things work, specifically I wanted to highlight that if you use the inline event listeners in the Dom Element such as onclick="fileClicked(event)" then you do not need to re-attach event listeners to the clone.

<!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>

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

Problem

`<input type="file"/>` The file and it path is cleared after clicking cancel in 'choose file' modal window in chrome, in FF and IE file stays untouched after pressing cancel. Is there any way to change this behavior in chrome?

Original source

Related problems