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
});
9
  • you want to know when user press cancel button? Commented Dec 27, 2017 at 16:24
  • Yes exactly. But is an input that select files. It opens the default OS system Dialog to open a file Commented Dec 27, 2017 at 16:24
  • You are using bootstrap modal? Commented Dec 27, 2017 at 16:28
  • 2
    Take a look to How to detect when cancel is clicked on file input? Commented Dec 27, 2017 at 16:36
  • 1
    @gaetanoM please add it as an answer to accept it thank you I understand now Commented Dec 27, 2017 at 17:28

3 Answers 3

3

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>

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

6 Comments

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, for that purpose you have change event.
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
I have created an example ilustrating the issue 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.
On Ubuntu 21.10, the change event fires first and then only focus.
|
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>

1 Comment

Actually on chrome you will get "empty" even if user selects something. Chrome is so bad (will work in ff)
0

You can use the cancel feature;

element.addEventListener('cancel', () => {
   // Code here
});

An example from my own coding;

const uploadInput = document.getElementById('image-upload')

// File selected
uploadInput.addEventListener('change', () => {
       // Code here
});

// File not selected
uploadInput.addEventListener('cancel', () => {
       // Code here
});

Comments

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.