This is my specific use case: I want to catch a click on the file dialog's "Cancel" button. The reason is that I work with Promises a lot, and I want the promise to be resolved when a file was selected, but rejected (or resolved with null) when the dialog is cancelled.
However, every "solution" to this problem that I found here and in other places was pretty much just a (mostly unreliable) workaround, like catching the body
s focus event.
My own workaround would be saving the current Promises reject function in a (module-local) global variable and calling it when the function is called a second time, so the Promise could at least be fulfilled when a file is selected in a second dialog.
The question is: Is there a modern, usable way to handle this case, that is not a workaround? If so, what is it?
This is my current code, using TypeScript and JQuery:
export function selectJsonFile() {
return new Promise<File>((resolve, reject) => {
let $input = $(`<input type="file" accept=".json">`);
$input.hide().change(() => {
let file = (<HTMLInputElement>$input[0]).files[0];
if (file)
resolve(file);
else
reject();
$input.remove();
}).appendTo($("body")).click();
});
}
And here is a pure-JS version I just wrote to generalize it a bit:
export function selectJsonFilePureJS() {
return new Promise((resolve, reject) => {
let input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", ".json");
input.style.display = "none";
input.onchange = () => {
let file = input.files[0];
if (file)
resolve(file);
else
reject();
input.remove();
};
document.body.appendChild(input);
input.click();
});
}
Now, is there an actually good way of handling this? I could not find any.