6

I have a input file selector and I want to know when the modal is closing if a file is not selected. I only know the change which only works when a file is selected or changes

<input type="file" id="selector">
$("#selector").on("change", function() {
    //Changed
});

2 Answers2

2

Try this

    <input type='file' id='testfile' style='display:none' />
    <button onclick='document.getElementById("testfile").click()'>Upload</button>

<script>
var testfile = document.getElementById('testfile')

testfile.onclick = focus();

function focus()
{
    document.body.onfocus = invoke();

}

function invoke()
{
    if(testfile.value.length)
    {
    alert('has file');
    }
    else {alert('empty')}
</script>
2

When the dialog is opened, it gets focus, so the browser window loses focus. The focus will be back when the dialog is closed. You have to subscribe focus event on window, but as window can lose and get focus because of a lot of reasons, you have to keep a flag if the dialog have been opened.

Following code works in:

  • Chrome 63.0.3239.84 x64 on Windows 7
  • Internet Explorer 11.0.9600.18860 on Windows 7
  • Opera 12.18 1872 x32 on Windows 7

and does NOT work in:

  • Firefox 58.0b11 (64-bit) on Windows 7

function now() {
  return window.performance ? performance.now() : +new Date
}

var isFileDialogOpened = false;

var input = document.querySelector('input');

input.addEventListener('click', function (e) {
  console.log('clicked', now())
  isFileDialogOpened = true
})

input.addEventListener('blur', function (e) {
  console.log('input blur', now())
  isFileDialogOpened = true
})

window.addEventListener('focus', function (e) {
  if (isFileDialogOpened) {
    console.log('closed (window got focus)', now())
    isFileDialogOpened = false
  }
})
<input type=file>
Qwertiy
  • 19,681
  • 15
  • 61
  • 128
  • This is true if you want to know if the dialog was closed. Its not enough if you want to know i user did select something or maybe clicked cancel – Antoniossss Aug 27 '20 at 10:16
  • @Antoniossss, for that purpose you have `change` event. – Qwertiy Aug 27 '20 at 10:39
  • If there would be no delay between closing dialog, regaining focus and `change` event then I would agree - but since there is a undetermined delay, you have no reliable way of knowing that input was "touched" (in angular's reactive forms terms) without introducing delays of your own. If you will base on focus only - input will be "touched" before value is appied and can render validation errors (actually that is my case).If rely on onChange - no way of knowing that cancel is pressed (and input should be touched).Wanna use both? rely on both events and some `setTimeout` delays - making ui laggy – Antoniossss Aug 27 '20 at 11:18
  • I have created an example ilustrating the issue https://plnkr.co/edit/4gKen9xlC6HSCty4?open=lib%2Fscript.js - you will see brief error message when you select the file - this is exactly what you will get when using reactive forms in AG (actually this is little bit custom made because plain AG controll will go to touched state after focus lost - here, it would be on dialog open -which I want to avoid). To avoid flickering, im delaying "close notification" by whole 500 ms - which totally sux and still might fail as it is time dependent - but thats the best i could to. – Antoniossss Aug 27 '20 at 11:34
  • On Ubuntu 21.10, the change event fires first and then only focus. – doox911 Oct 19 '21 at 11:03
  • @НебытьрабомнаРуси, and what does it mean? – Qwertiy Oct 19 '21 at 12:14