I'm calling an Alertify Confirmation dialog while running a Bootstrap 4 Modal, and the problem is that the tab focus is not working in the first, while it is stucking in the last.
I believe it is something to do with the "tabindex=-1" which is added to the modal class Div based on Bootstrap 4 standards, so I've tried more than one concept trying resolving the problem, and still not working...
One of the concepts that I've thought will work was to toggle the "tabindex=-1" from the "modal" class div elements during the Alertify onshow and onclose events, and still not working!
let mymessage = "Update entry?";
alertify.confirm().set({title: "Confirm!"})
.set({labels: {ok:"Yes", cancel:"No"}})
.set("defaultFocus", "ok");
.set({onshow:function(){$(".modal").attr("tabindex","-2");}})
.set({onclose:function(){$(".modal").attr("tabindex","-1");}});
// Show confirmation message
alertify.confirm(mymessage, function(e){
if(e){
editRow();
} else {
alertify.notify("Entry update has been canceled!");
}
}).bringToFront();
Take a look at the tab sequence is still in the Modal Div while it is missing from the Alertify Confirmation dialog!
I will be appreciated for any support!
The following code resolves the issue:
let mymessage = "Update entry?";
// custom OK and Cancel label to Yes and No
alertify.confirm().set({title: "Confirm!"})
.set({labels: {ok:"Yes", cancel:"No"}})
.set("defaultFocus", "ok")
.set({onshow:function(){$(".modal").removeAttr("tabindex");}})
.set({onclose:function(){$(".modal").attr("tabindex","-1");
}});
// Show confirmation message
alertify.confirm(mymessage, function(e){
if(e){
editRow();
} else {
alertify.notify("Editing entry has been canceled!");
}
});
Related
I am upgrading a modal from Bootstrap 3 to 4. I have some code which will update the options (specifically the backdrop and keyboard options) of an open modal. In Bootstrap 3 I had accomplished this by running:
$('.modal').data('bs.modal').options.backdrop = newBackdropValue;
$('.modal').data('bs.modal').options.keyboard = newKeyboardValue;
When I upgraded this to Bootstrap 4 I got the error that options was undefined. I then tried moving this to use _config as that seems to where these options are now housed but it didn't actually update the behavior of the modal.
In looking into the Bootstrap 4 code I noticed that on show it calls the _setEscapeEvent which seems to put a listener on the keyboard but I couldn't find public functions which removed this listener.
Would appreciate any insights into how people had done this before I start rooting around and trying to use private methods on the Modal.
for disable
$('#modal').off('keydown.dismiss.bs.modal');
for enable
$('#modal').on('keydown.dismiss.bs.modal', function(event) {
if (event.which === 27) {
event.preventDefault();
$('#detailselector').modal('hide')
}
});
You should be able to use the _config object in the data to update the modal. Just make sure it's done before the modal is shown...
Demo: https://codeply.com/go/DhB7TXVdfc
$('#myModal').on('show.bs.modal',function(){
// change the options that were set in data-attributes
$('#myModal').data("bs.modal")._config.backdrop = false;
$('#myModal').data("bs.modal")._config.keyboard = false;
});
Remember too that the modal must have tabindex="-1" in order for the ESC keyboard option to work!
The scenario I'm trying to solve is to disable that the escape-button closes the dialog AFTER the modal has been instaniated (the dialog is set to a loading state). So in other words after I have instaniated my modal like this:
(this.$el).modal("show");
The user presses a submit button and the dialog is set to a loading state and I want to disable the escape-button since the user should not be able to close the dialog in this state.
I have tried this:
(this.$el).modal({ keyboard: false });
But it does not work, it seems that Bootstrap only reads those options when it instaniates the modal dialog...
So my question is if it is possible to get a hold of the actual bootstrap modal-instance to be able to change the options-object? According to the documentation it should be possible (or have I misunderstood the docs?), but I cannot figure out how.
Here is what it says in the documentation (http://getbootstrap.com/javascript/):
If you'd like to get a particular plugin instance, retrieve it directly from an element:
$('[rel="popover"]').data('popover').
Any ideas?
Ok, I figured out how to get ahold of the modal dialog instance after some experimentation:
var bootstrapModalInstance = this.$el.data("bs.modal");
And then I could set the options on the instance like this:
bootstrapModalInstance.options.keyboard = !this.model.isSyncing;
Sadly enough, this did not solve the problem since the escape-key-event-listener is setup during the modal instaniation like this:
From bootstrap.js
Modal.prototype.escape = function () {
if (this.isShown && this.options.keyboard) { // The event listener is setup on initalization
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide() // !!! Does not check the instance options.keyboard flag status, so I had to add && this.options.keyboard here
}, this))
} else if (!this.isShown) {
this.$element.off('keydown.dismiss.bs.modal')
}
}
And as I wrote in the code comment above adding the instance options.keyboard check in the event listener solved the issue.
I have one page which has two cq dialogs.Assume it is dialog A and dialog B. Each dialog has 4 panels (CQ.Ext.Panel).
It is working independently. The issue here is when I do the toggle between these two dialogs, dialog A is having dialog B values and dialog B is having dialog A. I am just thinking to clear all the things while closing the dialog. I tried to clear panel values and get the component and removed like `Ext.getCmp(‘comp-name').removeAll();
I just overridden the CQ.Dialog.CANCEL behavior
{
text: "Custom Button",
handler: function() {
Ext.getCmp('comp-name').removeAll();
}
}
But these approaches are not fixing the issues. Could anyone help me to fix this issue?
Your description is not very clear but if this is the problem with component composition this link could be the approach. https://adobe-consulting-services.github.io/acs-aem-commons/features/cqinclude-namespace.html
Edit:
Check the bottom of this post for a solution, but now it introduces a new problem.
I'm using the most recent version of PageDown with Bootstrap 3.
This series of events causes the following error:
Uncaught TypeError: Cannot call method 'removeChild' of null
At which point the wmd-background mask is visible and over takes my page.
The error happens after step 4:
Open the custom modal dialog
Close the custom modal dialog (Using ok or cancel does not matter)
Open the custom modal dialog
Close the custom modal dialog (Using ok or cancel does not matter)
Here's the custom javascript code:
var insert_image = $("#insert-image");
var submit_image = $("#insert-image-submit");
var insert_image_close = $("#insert-image-close-x, #insert-image-close");
var file_url = $("#file_url", insert_image);
var file_local = $("#file_local", insert_image);
editor.hooks.set("insertImageDialog", function(callback) {
submit_image.on("click", function(event) {
event.preventDefault();
console.log("submit image");
insert_image.modal("hide");
return callback(file_url.val().length > 0 ? file_url.val() : null);
});
insert_image_close.on("click", function() {
console.log("cancel");
return callback(null);
});
insert_image.modal("show");
return true;
});
editor.run();
I did not see any solutions posted to this specific problem. I also tried hooking into Bootstrap's modal events and tried to either append my own or hide/show the wmd-background mask but I can't figure out a solution that results with no errors and has no extra background mask.
I should add too that I also have data-backdrop="" set in my html for when I build the modal dialog but this doesn't do anything other than prevent the background from being extra dark.
Solution:
I patched the library and changed:
Old broken version:
background.parentNode.removeChild(background);
New semi-working version:
if (document.contains(background)) { background.parentNode.removeChild(background); }
New problem:
The callback for both submit and cancel keep occurring more and more, as you open and close the form.
I get 1 then 2 then 4 then 6 then 10 console.log messages each time I close the form as I keep opening and closing it manually.
I fixed this temporarily by adding this to the top of the editor hook:
submit_image.unbind("click")
insert_image_close.unbind("click")
This seems like a hack, surely there's a better way to handle memoizing an event handler rather than unbind it + rebind it?
I have the following function that will show a modal:
confirmModal: function (message) {
// CODE TO SHOW MODAL HAS BEEN REMOVED FOR THIS QUESTION //
}
And because it's been namespaced it's called like: uiModal.confirmModal('Test message');
Inside the modal I have two buttons:
<button class="cancel">Cancel</button>
<button class="ok">Ok</button>
Now what I want to do is two things:
When I do something like: onsubmit="confirm('Are you sure?');" or onclick="confirm('Are you sure?');" it will show the modal instead of an alert box. Note that it needs to work for both links and form submits.
The two buttons in the modal need to either cancel or allow the request to happen. I have already got the cancel to close the modal fine so it's just a case of allowing or denying the request to happen.
Can anyone help? I've looked at some other questions on here and seen bits about using window.location($(this).attr('href')) but that would only work on links and not for the submit of a form.
I've also looked at doing window.confirm = uiModal.confirmModal('message'); but how would I use that in my example of an onclick or onsubmit
Thanks
This doesnt work because confirm is a blocking call (the javascript won't continue when the box is open), while your modal dialog isn't.
You can solve it by doing something like:
// have some temp var that holds confirmation state
var isConfirmed = false;
$("form").submit(function () {
// when someone tries to submit the form, verify whether it's confirmed
if (!isConfirmed) {
// show modal dialog
// prevent direct submit
return false;
}
});
// when hitting the OK button in the modal, change the confirmation state
$(".modal .ok").click(function () {
isConfirmed = true;
// and re-submit the form
$("form").submit();
});