I'm using Bootstrap Modal. I declare it, I call it, I show it...everything seems to be ok.
But what if I have an already existing modal previously shown with "keyboard" property to false and I want to change it on the go? I mean something like:
First, I create a Modal doing this (as you can see, I declare the modal putting keyboard property to false):
$('#myModal').modal({
show: false,
backdrop: true,
keyboard: false
});
But then I declare this event handler, that means that if "something" happens, I want the keyboard property to be set to true.
$('#myModal').on('shown', function(e) {
if (something){
$('#myModal').modal({keyboard: true});
}
}
So, when I go
$("#myModal").show();
The event handler is not doing what it is supposed to, as I am not getting to close the modal once Escape key is pressed. But I am completely sure that "something" is true and I have checked and re-checked that $('#myModal').modal({keyboard: true}) is executed.
Any clue as to why this isn't updating the value of configuration option?
To change configuration settings on already initiated Bootstrap plugin, such as the Modal, you need to access the plugin object attached to the element, like $('#pluginElement').data['somePlugin'] and then set the options in it.
For the Modal, you need:
$('#myModal').data('modal').options.keyboard = true;
JSFiddle Demo (old)
For Bootstrap 3 (as mentioned in comments by #Gerald ), you need bs.modal:
$('#myModal').data('bs.modal').options.keyboard = true;
Waiting Modal Example
A bit beyond the scope of the OP, but this is now twice I have searched for the same solution (my memory is crap) and twice that I came across this question which led me to my eventual answer. My issue was how to make an already init'ed and displayed modal, which was "closeable", into an "uncloseable" model. In the rare even that another user needs this answer, here is what I did based on the accepted answer:
*bootstrap3 used
$('#modal').off('keyup.dismiss.bs.modal'); // disable escape key
$('#modal').data('bs.modal').options.backdrop = 'static';
$('#modal button.close').hide();
Notice that I didn't change the options.keyboard property to false (followed by calling escape()) as suggested above. I could not get that to work, so after looking the Bootstrap source, I saw that all it was doing was simply removing an event listener for 'keyup.dismiss.bs.modal'.
To re-enabled things (in my scenario, when the model is hidden):
$('#modal').on('hidden.bs.modal', function (e) {
$(this).data('bs.modal').escape(); // reset keyboard
$(this).data('bs.modal').options.backdrop = true;
$('button.close', $(this)).show();
});
This seems COMPLETELY clumsy and will for sure break in coming versions of Bootstrap, but works for now...
Cheers :)
For bootstrap4
To disable closing modal on escape button:
$('#myModal').off('keydown.dismiss.bs.modal');
To disable closing modal on clicking on backdrop:
$('#myModal').data('bs.modal')._config.keyboard = false;
As warned by nocturnal, this may break in the future versions of bootstrap.
For Bootstrap 4.1
The options property should be replaced with _config.
E.G.
const modal = $('#modal');
/*
|------------------------------------------------------------------------------
| Now, let us assume you already opened the modal (via js or data attribute).
| If you want to access the options and modify.
|------------------------------------------------------------------------------
*/
// [Not Required] Let us see what the object is like.
console.log( modal.data('bs.modal')._config );
// Override the options to lock modal.
modal.data('bs.modal')._config.backdrop = 'static';
modal.data('bs.modal')._config.keyboard = false;
// [optional] You can also hide all data-dismiss buttons too.
modal.find("[data-dismiss='modal']").hide();
// Revert all actions above.
modal.data('bs.modal')._config.backdrop = true;
modal.data('bs.modal')._config.keyboard = true;
modal.find("[data-dismiss='modal']").show();
Setting backdrop and esckey not to close the modal when the modal is already open
$('div[name="modal"]').data('bs.modal').options.backdrop = 'static';
$('div[name="modal"]').off('keydown.dismiss.bs.modal');
Unset the backdrop and key esc purpose to not close the modal
$('div[name="user_profile_modal"]').data('bs.modal').options.backdrop = true;
$('div[name="user_profile_modal"]').data('bs.modal').escape();
You can also add an attribute in your HTML tag: data-keyboard="false"
<div id="myModal" class="modal hide fade" data-keyboard="false" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>
It works for me!
Another option if you do not know if the modal has already been opened or not yet and you need to configure the modal options (Bootstrap 3):
var $modal = $('#modal');
var keyboard = false; // Prevent to close by ESC
var backdrop = 'static'; // Prevent to close on click outside the modal
if(typeof $modal.data('bs.modal') === 'undefined') { // Modal did not open yet
$modal.modal({
keyboard: keyboard,
backdrop: backdrop
});
} else { // Modal has already been opened
$modal.data('bs.modal').options.keyboard = keyboard;
$modal.data('bs.modal').options.backdrop = backdrop;
if(keyboard === false) {
$modal.off('keydown.dismiss.bs.modal'); // Disable ESC
} else { //
$modal.data('bs.modal').escape(); // Resets ESC
}
}
Thanks #nokturnal
For me this method works the best
$('#modal').on('hide.bs.modal', function () {
return false;
});
It prevents modal from closing by any possible scenario:
pressing escape key
clicking outside the modal
clicking close button
and even using of $('#modal').modal('hide')
Related
I have a few different modals on a page, and it all works as it should, but if a user makes some input on form fields in a modal and then accidentally clicks outside of the modal (which closes it), they loose their changes, since if the user clicks the same button they pressed to open the modal, the data they entered will be overwritten with data pulled from the database.
So I'd like to have a function for "reopen last closed modal" that simply shows the modal again in it's last used state - with whatever data was in it.
Essentially like a Ctrl-Z for accidentally closing a modal.
It's really simple if you know the ID of the modal. Such as:
$('#myModal1').modal('show'); });
But because I have several different modals available on a page, and I don't want to have a bunch of "restore" buttons, I need to be able to detect the ID of the last closed modal.
If there's not a simpler way, I could capture the ID each time a modal is closed, and then use that ID if the modal needs to be reopened without changing its data. Something like this:
$('#myModal1').on('hidden.bs.modal', function (e) {
var LastModal = '#myModal1';
})
$('#myModal2').on('hidden.bs.modal', function (e) {
var LastModal = '#myModal2';
})
function reOpen() {
$(LastModal).modal('show');
}
But I'm guessing there's a way that's simpler and doesn't require me to state all my modals ID's in JS/jQuery. Any ideas?
I've made a few tweaks, and this is working well for me now, with essentially no other hassle than a few short lines of code in my script file.
var LastModal;
$('.modal').on('hidden.bs.modal', (e) => {LastModal = $(e.target).attr('id'); })
function reOpen() { $('#'+LastModal).modal('show');}
Just use the style class "modal" for your modals, and to call the "reOpen", just have something like:
<span onclick='reOpen();'>Reopen</span>
Thanks #marekful for your suggestion!
Also, if you want to access this (or any other function) by pressing Ctrl+Z, you can add this:
// press Ctrl+Z to restore modal
$(document).keydown(function(evt){
if (evt.keyCode==90 && (evt.ctrlKey)){
evt.preventDefault();
reOpen();
}
});
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!
I'm working in a project using bootstrap framework and I read there are different ways to open a modal window, in my case I open it with javascript with this code:
$('#formVenta').modal({backdrop: 'static', keyboard: false});
I did this because the client asked me to avoid close the modal when click outside but now he wants to press click outside and close the modal again but when there is no content inside a specific div inside my window
<div id="content_goes_here"></div>
I think to solve this in this way
$(document).click(function(e) {
//check if modal is open
if ($('#formVenta').is(':visible')) {
//check if div has content
if ($('#content_goes_here').html().length > 0) {
//do something
}
}
});
The problem I see is that there are text input outside that div and If I want to search something it will close when I make click in the input because there will be not content yet inside the div and I want to avoid this issue.
Is there a way where only when I make click outside the modal window check if the div is empty and make the opposite of the way I opened the window in this case the opposite of this?
$('#formVenta').modal({backdrop: 'static', keyboard: false});
for example change the value of the property backgrop.
I hope you can help me, thanks.
sorry it took a while to find the right properties but here is the best example
$('#formVenta').data('bs.modal').options.backdrop = false; or
$('#formVenta').data('bs.modal').options.backdrop = static;
you can take a look at the current properties you have set by doing
alert(JSON.stringify($('#myModal3').data('bs.modal').options)); or change the alert to console.log()
so you can put an event on the div for when it changes to run the validation function and inside of the validation function you can change the options of the modal with the above code
How do I stop an already open and instantiated bootstrap modal from closing on
Esc keypress
clicking on modal backdrop
I know about the backdrop = static option. But its before initializing the modal. Here I have the modal all nice and initialized. And its working all fine and dandy. Now in a user flow, I am supposed to prevent the modal from being "close-able".
Update 1: Just to clarify, I don't want that modal window to be unclosable (if thats even a word) from the beginning. I just want to modify the behaviors based on user activity and only for a specific flow. If the user doesn't follow that activity flow, I want the modal to retain the original behavior of being able to close on backdrop click.
So I found the following solution.
Bootstrap v3.xx
jQuery('#paymentous').data('bs.modal').options.keyboard = false;
jQuery('#paymentous').data('bs.modal').options.backdrop = 'static';
Bootstrap v2.xx
$('#paymentous').data('modal').options.keyboard = false;
$('#paymentous').data('modal').options.backdrop = 'static';
This will prevent an already instantiated model with backdrop option set to false (the default behavior), from closing.
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.