Focus of Bootstrap Modal dialog when opening two nested modal lost - javascript

I have two modal which was opened in nested way. The ESCAPE keyboard only works in the closing of the second dialog. The first dialog does not close via keyboard unless I click on the dialog again to regain the focus. I am trying to restore the focus of the modal to the first dialog. So the user can do a consecutive [ESCAPE] - [ESCAPE] key to close both dialog. Both have tabindex="-1".
First dialog was called inside the main js file.
$('#firstDialog').modal({
cache: false,
backdrop: 'static'
}, 'show');
Second dialog was called inside an event of a button in the first dialog
$('#secondDialog').modal({
cache: false,
backdrop: 'static'
}, 'show');
I tried the following, to manually set the activeElement when second dialog is closed. It does not seem to work.
$('#secondDialog').on('hidden.bs.modal', function(){
document.activeElement = $('#firstDialog')[0];
});
I referred the solution in the following thread on setting the activeElement. Any ideas what object does bootstrap need to be focused to have the escape back automatically?
https://github.com/twbs/bootstrap/issues/4854

Found out the answer minutes after formulating the question. Anyway, if others have any better solution than this, please give me a suggestion. My thought is it should work by default.
$('#secondDialog').on('hidden.bs.modal', function(){
$('#firstDialog').focus();
});

Related

best practice for opening and/or initializing jquery ui dialog

There are two ways to open a jquery dialog:
1) Set the autoOpen=true when initializing a dialog
2) After initialization (with autoOpen = false), call $("#id").dialog("open");
At the moment, in my code, whenever a user clicks a button, a modal dialog opens by using the first method. On "Ok" or "Cancel" the dialog is closed $(this).dialog("close");
Is it bad that on every click the dialog is opened using autoOpen=true ? In other words, is it bad that the dialog is reinitialized on every click ?
From a performance, point of view, will reinitializing the dialog on every click cause problems such as dialog events being registered multiple times ?
What is the jquery best practice for this ?
Code:
$("#button").on("click",function(){
$("#dialogHello").dialog({
modal: true,
autoOpen: true,
buttons: [
{ "text" : "Ok", "click" : function() { $(this).dialog("close"); } },
{ "text" : "Cancel", "click" : function(){ $(this).dialog("close"); } }
]
});
});
By observing the DOM, I noticed that the html elements that jquery ui dialog injects in the DOM are not duplicated if the jquery ui dialog is re-initialized on every call. If the jquery ui dialog DOM elements already exists then they are simply reused.
The following thread :
jQuery draggable - what happens if it is applied twice to an element?
Explains that the jquery events won't be registered several times on the same element if it already exists. For example, in my scenario, if I re-initialize the jquery ui dialog on every call then there won't be incrementing events being registered.
I generally initialize my dialogs once with autoOpen set to false, and then 'open' them whenever they are needed. I'll possibly update the dialog content before opening if needed.
If for some reason you do feel the need to re-init it each time, then you should at least use the 'destroy' method first to avoid causing problems and bloat.

Event when tinymce plugin dialog is closed

tinymce.PluginManager will open a dialog using windowManager.open(). The dialog can be closed manually by using windowManager.close(). This is described by http://www.tinymce.com/wiki.php/api4:class.tinymce.Plugin. The dialog can also be closed by clicking the "X" in the top right corner.
I would like to execute some script whenever the dialog is closed. Seems to me there are two options.
Option 1. Ideally, I can add a callback which would execute whenever ever the dialog is closed. I have searched the documentation, but cannot find out whether this is possible.
Option 2. When ever I manually close the dialog using windowManager.close(), I can add the desired script directly before doing so. It is when the user clicks the X has got me stumped.
Trigger the event which happens when I click the 'x' button on a TinyMCE modal dialog (like the advimage dialog) describes adding an event handler to the X button being clicked. Problem is the event cannot be associated until the dialog is open, and there doesn't seem to be an on open dialog event I can do it at.
How can I execute code whenever the TinyMCE plugin dialog is closed? Thank you
$(".mceClose").click(function() {
alert('Handler for .click() called.');
});
To be precise you should add onClose function as the following:
tinyMCE.activeEditor.windowManager.open({
...
onClose: function() {
}
});
It cost me a lot of time to find right solution. Hope it will help.
As described in API reference, close method fires onClose event. So you can try something like:
tinymce.activeEditor.windowManager.onClose.add(function() {...})

Detecting if the file input dialog is open

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.
Based on Nikita's answer. If you check for focus on the input field before firing your code it solves the issue:
$('input[type="file"]').on('keydown',function(e){
//Prevents code from firing if file browser is open
if($(this).is(':focus')){
//run code here that should only be applied when the dialog box is closed
}
});

Dojo dialog close event on X (top-right)

Im using Dojo to create a simple dialog to create a user in a system. The problem is I get the error:
Tried to register widget with `id==user_submit` but that `id` is already registered
user_submit, is a Dojo button I have to finish the form inside the dialog. When I close the dialog by clicking it and submitting the form there is no problem in opening the dialog again (in the click event on the button I have this line of code:
dijit.byId("user_submit").destroy();
but if I close the dialog through the [x]-link / button in the top-right corner I don't destroy the button and then can't open the dialog again without reloading the page.
How do I get Dojo to destroy the button or how to a overload the click-event on [X]-link / button, so I can write the destroy command for the button?
"Developer shouldn't override or connect to this method" for "onCancel" see documentation.
A better solution is:
var myDialog = new Dialog({
id: "myDialogId1",
onHide: function() {
myDialog.destroy()
}
});
Found a solution. by using dojo.connect().
myDialog.connect(myDialog, "hide", function(e){
dijit.byId("user_submit").destroy();
});
Would have postet this shortly after i posted the quistion, but I didn't have enough points, so here is the answer again, just a little late :-)
IIRC, the onClose extension event gets called when you click on the X thing, so you could try putting your cleanup code there.
You could also consider sidesteping the issue entirely. Perhaps you don't need to destroy the widget and could instead reuse the same one? You could also do a widget existence test before you create it again, destroying the old version if its still alive.
You can override onCancel() method as stated above or you can attach event to the
dijit.dialog.closeButtonNode domElement.
dijit.dialog.closeButtonNode is the name of data-dojo-attach-point attribute for close button.
Exp:
dojo.on(dijit.Dialog.closeButtonNode, "click", function(evt){
//add your logic here
});
When pressing the X on the top of the dialog the "onCancel" event is triggered.
Dispose of the element there.

CKEditor InnerHTML error

I have two CKeditor fields that are a part of the form. I have some action buttons on the page, so whenever I click either 'clear' or 'cancel' this function is fired along with other stuff:
CKEDITOR.instances['ed1'].updateElement();
CKEDITOR.instances['ed1'].setData('');
CKEDITOR.instances['ed2'].updateElement();
CKEDITOR.instances['ed2'].setData('');
That way I am cleaning the contents of the CKEditor fields. The problem is that if I click 'cancel', then go back to the page and click "clear", Internet Explorer gives an "innerHTML is null or undefined" JS error.
It works fine in other browsers and only happens if I perform the update twice in a row from different buttons. Is there a workaround for that?
CKEditor initialization onReady:
CKEDITOR.replace('ed1', { htmlEncodeOutput: true, width:"700",toolbar: 'Basic'
});
CKEDITOR.replace('ed2', { htmlEncodeOutput: true, width:"700",toolbar: 'Basic'
});
I probably should add that I use .show() and .hide() whenever I use cancel button to hide the form and show other stuff. There's no page reload.
I found the solution to this problem. The reason it was doing that because my clear method was fired using jQuery bind function and wasn't placed in the onReady function, so it was binding the events together and giving this error. The solution to this was to use unbind first.

Categories

Resources