Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Twitter Bootstrap / jQuery - How to temporarily prevent the modal from being closed?

I am using Twitter Bootstrap modals, with the default options where you can click the backdrop or press [Esc] to close the modal.

However, when I initiate an ajax operation in the modal I want to disable the modal from being closed in any way. So I disable buttons and hide the modal's close button but I can't figure out how to disable the backdrop and the [Esc] key.

I tried:

$('#myModal').modal({     backdrop: 'static',     keyboard: false }); 

But this doesn't seem to work on the fly.

I will also need to re-enable the backdrop and keyboard once the ajax operation is finished.

like image 670
BadHorsie Avatar asked Nov 16 '12 17:11

BadHorsie


2 Answers

Note: This solution is targeting twitter bootstrap 2.x! See this answer (just below) for differences according to bootstrap 3.


Extending bootstrap modal functionality without modifying original source.

Thanks to @David and his suggestion at How to Extend Twitter Bootstrap Plugin I finally got it to work. It is a slightly modified version of his solution with modal "lock" added. I post it as a additional answer since I think it may could be a starting point for others that like me have struggled hard with this issue.

// save the original function object var _superModal = $.fn.modal;  // add locked as a new option $.extend( _superModal.defaults, {     locked: false });  // create a new constructor var Modal = function(element, options) {     _superModal.Constructor.apply( this, arguments ) }  // extend prototype and add a super function Modal.prototype = $.extend({}, _superModal.Constructor.prototype, {     constructor: Modal      , _super: function() {         var args = $.makeArray(arguments)         // call bootstrap core         _superModal.Constructor.prototype[args.shift()].apply(this, args)     }      , lock : function() {         this.options.locked = true     }      , unlock : function() {         this.options.locked = false     }      , hide: function() {         if (this.options.locked) return         this._super('hide')     } });  // override the old initialization with the new constructor $.fn.modal = $.extend(function(option) {     var args = $.makeArray(arguments),     option = args.shift()      // this is executed everytime element.modal() is called     return this.each(function() {         var $this = $(this)         var data = $this.data('modal'),             options = $.extend({}, _superModal.defaults, $this.data(), typeof option == 'object' && option)          if (!data) {             $this.data('modal', (data = new Modal(this, options)))         }         if (typeof option == 'string') {             data[option].apply( data, args )         }     }); }, $.fn.modal); 

With this technique it should not be nessecary to alter bootstrap.js, and the same functionality can more easily be shared among bootstrap projects. This method should be applicable to all the other bootstrap plugins. Have so far only tried with button though, but I cant se why it shouldnt.

see working fiddle -> http://jsfiddle.net/Sz7ZS/

like image 60
davidkonrad Avatar answered Oct 05 '22 09:10

davidkonrad


There is an easier way to do it. This bootstrap pull request explains a little more. The solution disables all methods for closing the modal (keyboard, mouse click, close button).

All you have to do to disable closing the modal is:

$('#myModal').data('bs.modal').isShown = false; 

To enable closing again:

$('#myModal').data('bs.modal').isShown = true; 

Example

Here is some sample code that works in conjunction with a jQuery get:

// disable closing the modal $('#myModal').data('bs.modal').isShown = false;  // Send an HTTP GET request to the server - replace this with getJSON, post or ajax as needed $.get( "ajax/test.html", function( data ) {   // enable closing the modal   $('#myModal').data('bs.modal').isShown = true;    // Do something with the data   $( ".result" ).html( data ); }); 
like image 30
qingu Avatar answered Oct 05 '22 08:10

qingu