Bootstrap modal doesn't show after prevented from being opened - javascript

I'm using Bootstrap 3 to create modal form. Before user click button to open the modal, there is a field validation.
If it is valid then modal is shown, otherwise prevent the modal from being shown.
The problem is on the second chance, user click the button and the modal won't display.
How to solve this problem?
Code to show modal and prevent modal from being shown: jsfiddle
$("#btnLookupClient").click(function (e) {
if ($("select[name='OfficeID'] option:selected").index() <= 0) {
alert("Please select office");
$("#OfficeID").focus();
$("#clientModal").on("show.bs.modal", function (e) {
return e.preventDefault() // stops modal from being shown
});
} else {
var url = '#Url.Content("~/Client/Search?officeID=")' + $("#OfficeID").val();
$.get(url)
.done(function (data) {
$("#lookup-client-container").html(data);
$("#clientModal").modal(show = true, backdrop = true);
});
}
});

Use one() instead of on().
$("#clientModal").one("show.bs.modal", function (e) {
return e.preventDefault() // stops modal from being shown
});
See here : http://jsfiddle.net/akcbj4n5/1/
Also reference : Difference between jQuery.one() and jQuery.on()

when the alert gets shown you are binding the preventDefault to the event that shows the modal so it will never be shown again, even when the validation passes.
I'd suggest using the .one() function instead of .on() http://api.jquery.com/one/
Also you're modal will fire without having to call it in javascript because you set the toggle to modal and the target to the modal id.

Related

Disable click outside of bootstrap modal area only for a few second [duplicate]

Can I change backdrop to 'static' while my modal is open?
I have modal with form submit button. When I click this button I show loading spinner on my modal and that is the moment when I want to change backdrop to static
I tried $('#myModal').modal({backdrop: 'static', keyboard: false}), but I can still close my modal by clicking the backdrop or using escape button.
Second step should be changing backdrop back to true, but I didn't try this yet, because first I need to set backdrop to static.
I could set backdrop to static on modal show, but I want to avoid this and change it after submit.
Any ideas?
Ok I solved this. Maybe it is not the best solution, but it is working for my special case.
I added $('#myModal').off('click'); just after I show loading spinner on submit. This prevents from closing modal with mouse click.
There was a problem with disabling escape button, because browsers stops page loading when user press this button. So I decided to hide the spinner to unlock the form with this code:
$(document).on('keydown',function(e) {
if (e.keyCode == 27) {
$('#myLoadingSpinner').hide();
}
});
Edit:
I found another solution for backdrop:
$('#myModal').data('bs.modal').options.backdrop = 'static';
I tried this also for keyboard = false, but it doesn't work.
I had a modal that could be opened 2 different ways. When the user opened it one way, I wanted them to be able to close the modal. When they opened it the other way I didn't want them to be able to close it.
I found this question and used the solution from the original poster. I also tried adding keyboard which now works:
$('#myModal').data('bs.modal').options.backdrop = 'static';
$('#myModal').data('bs.modal').options.keyboard = false;
I had a different JavaScript object returned and thus the following solution:
$myModal.data("bs.modal")._config.backdrop = value;
The simplest method I've come up with is attaching to the hide.bs.modal event and calling preventDefault(). This doesn't technically set the backdrop to static, but it achieves the same effect in a toggleable manner.
let $myModal = $('#myModal');
function preventHide(e) {
e.preventDefault();
}
// if you have buttons that are allowed to close the modal
$myModal.find('[data-dismiss="modal"]').click(() =>
$myModal.off('hide.bs.modal', preventHide));
function disableModalHide() {
$myModal.on('hide.bs.modal', preventHide);
}
function enableModalHide() {
$myModal.off('hide.bs.modal', preventHide);
}
(Disclaimer, I didn't test making buttons allowed to hide the modal, as that wasn't my scenario. If it doesn't work, just call .modal('hide') from the click() callback.)
You can disallow closing of a modal when clicking outside of it, as well as on esc button. For example, if your modal ID is signUp:
jQuery('#signUp').on('shown.bs.modal', function() {
jQuery(this).data('bs.modal').options.backdrop = 'static';
jQuery(this).data('bs.modal').options.keyboard = false;
});
I found, that in Bootstrap 5 this is slightly different:
modal = new bootstrap.Modal($('.modal'));
modal._config.backdrop = 'static'; // or true

How to catch event when user clicks outside of bootstrap modal dialog?

Scenario:
I click on a button
Ajax call is made to the server
data is returned and modal is shown
Problem:
When user clicks on the close button or the "X" in the corner I catch this event by assigning a class to these two elements and assigning an event to this class.
Code:
$(document).on("click", ".dialogTankClose", function() {
//some code
})
My problem is that i can't figure out how to catch when the user clicks outside of the dialog or presses "escape".
$(document).on("click", "modalCloseEvent",function(){
// how to catch this?
})
How can I catch this?
The Bootstrap modal raises an event when it closes, which you can hook to: hidden.bs.modal. This event fires no matter how the modal is closed. Try this:
$('#bootstrapModal').on("hidden.bs.modal", function() {
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
});
You can use a delegated event handler if the modal is dynamically added to the DOM:
$(document).on("hidden.bs.modal", '#bootstrapModal', function() {
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
});
More information in the Bootstrap documentation
You can use 'hidden.bs.modal' modal method to run custom code while modal is getting unload / hide from document.
$('#your-modal-ID').on('hidden.bs.modal', function (e) {
console.log("Hey !! I am unloading... ");
});

Instantly display a modal when the form is submitted (before validation)

I'm using a bootstrap validator from (https://github.com/1000hz/bootstrap-validator/blob/master/js/validator.js) and I'm trying to instantly display a modal 'loading' box when the submit button is pressed on a form. I've achieved this by doing the following:
$('form').on('submit', function (event) {
showLoadingModal();
if (!event.isDefaultPrevented()) {
event.preventDefault();
submitForm(this);
} else {
hideLoadingModal();
}
});
However I'm getting a problem where there is a small gap of time (under a second) between clicking the button and the modal being displayed. I'm assuming this delay is caused by the time taken validating all the fields on the form of which there are quite a lot.
This therefore leads me to believe that the validator 'form submit' is being executed before my code and I should be doing something different to call the showLoadingModal()
Edit:
I've added some logging into the js to work out what happens and when. I've also moved the showLoadingModal() into a 'button clicked' event to ensure it happens before form submit. Here's the order my messages get displayed:
button clicked
before show modal
after show modal
form submitted
about to validate
<--Modal appears now-->
set a delay of 300ms before submitting your form
var event;
var formobj;
('form').on('submit', function (event) {
showLoadingModal();
event = event; //save event to be used later
formobj = this;
setTimeout(function()
{
if (!event.isDefaultPrevented()) {
event.preventDefault();
submitForm(formobj );
} else {
hideLoadingModal();
}
},300);
return false; //Prevent normal submission of the form so that the dialog box is visible
});
I am assuming submitForm(this) is the function that does the form posting causing the page to reload
Just a thought, hope it helps!

Jquery ui dialog not closing with `Escape` keypress

When a user opens dialog, there are a bunch of ajax requests that have to be processed and therefore i have a second dialog that just displays loading information and closes once all the requests have been processed.
I am not able to close the user opened dialog with Escape key once it has opened. I have to click on the the dialog itself before I can use escape.
I have tried the following to assign the user opened dialog the focus after the loading dialog closes but to no avail, I still have to click on the dialog before it can close with the escape key.
$(document).ajaxStart(function () {
// IF loading dialog is not allready being shown show it.
if ($("#LoadingData").dialog('isOpen') === false) {
$("#LoadingData").dialog('open');
}
});
$(document).ajaxStop(function () {
//Close the loading dialog once the requests have finished
$("#LoadingData").dialog('close');
//Find the user opened dialog
$('.cmdialog').each(function () {
if ($(this).dialog('isOpen')) {
$(this).trigger('click');//set focus to dialog
// have also replaced .trigger('click') with .focus() but to no avail
}
}).on('click', function() {
//if click is triggerd set the focus of the dialog.
if ($(this).prop('id') != 'LoadingData') {
$(this).focus();
}
});
});
I have also tried setting the focus to the first element within the dialog with $('#DialogName:first-child').focus() and $('#DialogName:first-child').trigger('click') but this is also not working.
Any ideas as to why the focus is not set? Or am I misunderstanding/incorrectly using .focus() and .trigger('event')?
Thanks :)
Try the below code for close the dialog when Escap key is pressed:
$(document).keyup(function(e) {
if (e.keyCode == 27) { $("#LoadingData").dialog('close'); } // esc
});
I had the same issue, and found pretty elegant solution, in case you want to close dialog before actually clicking inside it:
$("#LoadingData").dialog({
...,
focus: function () {
$('#LoadingData').closest('.ui-dialog').focus();
}
});
So, we just need to set focus to parent .ui-dialog container, and in that case Esc will work for all cases. Disadvantage of $(document).keyup solution, if you have nested dialogs, Esc button will close your most top dialog and bottom one too.
the focus event is sent to an element when it gains focus. This event is implicitly applicable to a limited set of elements, such as form elements (, , etc.) and links. docs here
You can try moveToTop method of the dialog, maybe it will help
And in your code, I think, you should bind "click" event before triggering it.
The following code should work even for multiple modals open:
$(document).on('keydown','.modal-dialog',function(event){
if (event.keyCode == 27) {
$(this).closest('.modal-dialog').find('[data-dismiss="modal"]').click();
}
});

Close colorbox popup with a button and trigger the confirm box?

I have a confirm box on my colorbox("are you sure you want to leave?").
This triggers when i close the popup. This works when i click on the "cboxClose" div on the popup.
I am trying to show this confirm box on a button click. But the popup just closes right away without showing the confirm box.
My question is how do i trigger the the confirm box when i click on a cancel button. i tried several ways
//This just closes the pop up without showing the confirm box
$('#btnCancel').click(function () {
parent.$.colorbox.close(); });
//doesn't work
$('#btnCancel').click(function () {
$('#cboxClose').click()
});
COLORBOX
onComplete: function () {
$("#cboxClose").click(function (e) {
// stop any other script from firing
e.stopPropagation();
if (confirm('are you sure you want to leave?')) {
$.colorbox.close();
// ensure that the binding is removed when closed
$("#cboxClose").unbind();
}
});
} // close oncomplete
The issue here is that colorbox registers a click handler on the cboxClose element. As a result, neither stopping bubbling nor preventing the click (by returning false in a click handler) will have any effect because the colorbox handler is already registered. The only way of stopping that handler from being run is to unbind it. However, to do that you need a reference to the handler, which you won't get without modifying the colorbox code.
In any case, that's what's going on and why the code you have above doesn't work. Another option for you would be to override the colorbox close function (which is the public colorbox method that is called by colorbox's close button handler). All you need is this:
$.colorbox._close = $.colorbox.close;
$.colorbox.close = function() {
if(confirm("Close?")) {
$.colorbox._close();
}
}
The down side (which may not be an issue in your situation) is that this will affect all colorboxes on the page.
I solved this issue by making this method and binding it to the cancel button
var originalClose = $.colorbox.close;
$.colorbox.close = function (e) {
var response;
var formChanged = localStorage.getItem("isFormChanged");
var saveClicked = localStorage.getItem("saveClicked");
if (formChanged == "true" && saveClicked == "false") {
response = confirm('Do you want to close this window? All your changes will not be saved');
if (!response) {
return
}
}
originalClose();
};
<input type="button" value="Cancel" id="btncancel" onclick="parent.$.colorbox.close()"/>

Categories

Resources