How can I go about detecting if the file input dialog is currently open?
I'm trying to integrate some file upload functionality into a popup (bootstrap style) model on a web app I'm building. As part of the model's behaviour, if escape is pressed, the model is closed.
This is all good till I open a file input dialog from the open model, if I hit escape to close the input dialog, it'll also close the model.
A super simplified version of what I'm trying to achieve http://jsfiddle.net/ckevy/1/
Try solving it like this:
When a user clicks on the file selection input, give it focus: $(el).focus()
.
Then, anytime a user hits ESC, look if the $(':focus') element is the file selection input. In that case, blur() that input and do not close the modal. Worst case – the user wants to close the modal, presses ESC and nothing happens [1]. Thinks "wtf", presses ESC again and modal closes as it should. Just make sure that the file selection input does get focus in all possible cases – tabbing through inputs, etc. If you use a third party uploader and what I've said doesn't work – look into how that uploader wraps the file selection in a custom link or button, and what actually receives the click event in different cases (e.g. when you tab, the input might receive the event, when you click, it could be the link). Overall, it's manageable to have this working with the caveat I've described.
This works with expanded -s too similarly (just check that a select is not focused when ESC is hit).
You won't be able to detect all the cases when you need to blur()
the file selection input. It's not a cross-browser solution. Even FF needs adjustments to work. I've been testing on webkit with positive results, in other browsers it might not work.
In my case works this code on jQuery:
// esc must close popup
$("body").keyup(function(e) {
if (27 == e.keyCode) {
hidepopup();
}
});
// input in popup
var $file = $("input:file");
// keyup will be catched for input, not for body
$file.bind("click", function(e) {
$(this).focus();
});
// keyup catching will be changed back to body after selecting file
$file.bind("change", function(e) {
$(this).blur();
});
// we catched esc keyup, so change esc catching back to the body
$file.keyup(function(e) {
if (27 == e.keyCode) {
$(this).blur();
// i don't know, why it works with return false, because i am not js programmer ), but cancelBubble or e.preventDefault is not working
return false;
}
});
I do not believe you actually have direct control over the dialog itself. In some browsers such as FF people have been able to manipulate the dialog to an extent but this does not apply to all browsers and all browser versions.
The easiest way to do this is to disable the shortcut key on the model dialog before opening the file window.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With