33

Ich verwende Twitter Bootstrap-Modale, mit den Standardoptionen, wo Sie auf den Hintergrund klicken oder [Esc] drücken können, um das Modal zu schließen.Twitter Bootstrap/jQuery - Wie kann man vorübergehend verhindern, dass das Modal geschlossen wird?

Wenn ich jedoch eine Ajax-Operation im Modal einleite, möchte ich das Modal in irgendeiner Weise schließen. Also deaktiviere ich Tasten und verberge die Schließen-Schaltfläche des Modals, aber ich kann nicht herausfinden, wie man den Hintergrund und die [Esc] -Taste deaktiviert.

Ich habe versucht:

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

Aber dies scheint nicht im laufenden Betrieb zu arbeiten.

Ich muss auch den Hintergrund und die Tastatur wieder aktivieren, sobald der Ajax-Vorgang abgeschlossen ist.

Antwort

17

Hinweis: Diese Lösung zielt twitter bootstrap 2.x! Genaue Unterschiede siehe Bootstrap 3 unter this answer.


Erweiterung Bootstrap-modale Funktionalität ohne Originalquelle zu ändern.

Dank @David und seinem Vorschlag bei How to Extend Twitter Bootstrap Plugin habe ich es endlich zur Arbeit gebracht. Es ist eine leicht modifizierte Version seiner Lösung mit modaler "Sperre" hinzugefügt. Ich poste es als eine zusätzliche Antwort, da ich denke, dass es ein Ausgangspunkt für andere sein könnte, die wie ich mit diesem Problem hart gekämpft haben.

// 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); 

Mit dieser Technik ist es nicht nessecary sein sollte bootstrap.js, und die gleiche Funktionalität zu verändern, kann leichter unter Bootstrap-Projekten gemeinsam genutzt werden. Diese Methode sollte für alle anderen Bootstrap-Plugins gelten. Habe bisher zwar nur mit Knopf versucht, aber ich kann nicht sehen warum es nicht sollte.

siehe Arbeits Geige ->http://jsfiddle.net/Sz7ZS/

+0

Nachdem ich diese Methode angewendet habe, scheint der Hintergrund (der graue Hintergrund) zu verschwinden. Ich muss manuell $ ('# thisModal') .modal ({background: true}); um es zu benutzen. Ist das ein Fehler oder ist dies der einzige Weg? –

+0

@TianLoon. Habe die Antwort mit einer Benachrichtigung über die Bootstrap-Version und eine [jsfiddle] (http://jsfiddle.net/Sz7ZS/) mit Bootstrap 2.3.2 (die "populärste" 2.x-Version) aktualisiert. In der Geige erscheint der Hintergrund - vielleicht hast du ihn versehentlich auf undurchsichtig 0, weiß oder so eingestellt? – davidkonrad

+0

DANKE SO VIEL FÜR DIESES !!!!! –

9

Sie sind nicht die einzige, die diese Funktion fehlt. Ich denke bootstrap ist manchmal zu "minimalistisch", die Leute dahinter haben die Idee viel sollte in der "implementation layer" gemacht werden, aber es ist nutzlos wenn die Bootstrap jQuery Plugins selbst es unmöglich machen!

Sie haben die Funktionalität selbst zu implementieren, wie dies:

in bootstrap.js v2.1.1 modal an Linie beginnt 61.

in Modal.prototype, fügen Sie zwei Funktionen, lock und unlock, so sieht es aus wie folgt aus (zeige ich hier nur den Anfang modal.prototype, becuase es zu viel Code ist)

Modal.prototype = { 

     constructor: Modal 

     //add this function 
    , lock: function() { 
     this.options.locked = true 
     } 

     //add this function 
    , unlock: function() { 
     this.options.locked = false 
     } 

    , toggle: function() { 
    ... 
    ... 

Then, auch in Modal.prototype, finden die Funktion hide, und fügen Sie eine Zeile, so dass es so aussieht (wieder nur oben Versteck zeigte ist)

, hide: function (e) { 
    e && e.preventDefault() 

    var that = this 

    //add this line 
    if (that.options.locked) return 

    e = $.Event('hide') 
    ... 
    ... 

Und schließlich verändern $.fn.modal.defaults zu:

$.fn.modal.defaults = { 
     backdrop: true 
    , keyboard: true 
    , show: true 
    , locked: false //this line is added 
    } 

Jetzt haben Sie die Funktion "Sperren/Entsperren" in Ihrem Bootstrap-Modal und verhindern, dass der Benutzer das Modal in kritischen Momenten schließt.

Beispiel:

Dies ist eine veränderte Version von "Live-Demo" von http://twitter.github.com/bootstrap/javascript.html#modals

<!-- Button to trigger modal --> 
<a href="#myModal" role="button" class="btn" data-toggle="modal">Launch demo modal</a> 

<!-- Modal --> 
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> 
    <div class="modal-header"> 
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 
    <h3 id="myModalLabel">Modal header</h3> 
    </div> 
    <div class="modal-body"> 
    <p>One fine body…</p> 
    </div> 
    <div class="modal-footer"> 
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button> 
    <button class="btn btn-primary" onclick="$('#myModal').modal('lock');">lock</button> 
    <button class="btn btn-primary" onclick="$('#myModal').modal('unlock');">unLock</button> 
    </div> 
</div> 
<script type="text/javascript"> 

ich zwei Tasten eingefügt haben, "sperren" und "Entriegeln" - wenn sie angeklickt, sie setzen das Modal im gesperrten oder normalen Modus (die Einstellungen, mit denen es initialisiert wird)

Bearbeiten, in Ihrem Fall müssen Sie nur lock/onlock aufrufen, wenn tun Ajax:

$("myModal").modal('lock'); 
$.ajax({ 
    url: url, 
    ... 
    ... 
    , success(html) { 
     ... 
     ... 
     $("#myModal").modal('unlock'); 
    } 
}); 
+0

Das funktioniert gut, aber können Sie dies implementieren, indem Sie den Bootstrap-Kerncode erweitern, anstatt ihn zu ändern? – BadHorsie

+0

Ja, endlich herausgefunden :) Danke an @david und danke an dich. – davidkonrad

6

Dank @davidkonrad auf das für Ihre Arbeit. Ich habe versucht, dies auch zu implementieren und es scheint, dass die Dinge mit Bootstrap geändert haben 3. Jetzt statt:

_superModal.defaults

es nun an den Konstruktor angebracht ist, so dass Sie

_superModal.Constructor.DEFAULTS

zu tun

Auch der Konstruktor hat sich geändert, was bedeutete, dass ich ihn kopieren und modifizieren musste, was nicht ideal ist. Stattdessen habe ich den folgenden Code entwickelt, der funktioniert und den Konstruktor nicht kopiert. Er sollte narrensicherer sein, wenn die Bootstrap-Änderungen sich ändern. Haben Sie gehen:

// save the original function object 
var _superModal = $.fn.modal; 

// add locked as a new option 
$.extend(_superModal.Constructor.DEFAULTS, { 
    locked: false 
}); 

// capture the original hide 
var _hide = _superModal.Constructor.prototype.hide; 
// console.log('HIDE:', _hide); 

// add the lock, unlock and override the hide of modal 
$.extend(_superModal.Constructor.prototype, { 
    // locks the dialog so that it cannot be hidden 
    lock: function() { 
     // console.log('lock called'); 
     // console.log('OPTIONS',this.options); 
     this.options.locked = true; 
    } 
    // unlocks the dialog so that it can be hidden by 'esc' or clicking on the backdrop (if not static) 
    ,unlock: function() { 
     // console.log('unlock called'); 
     this.options.locked = false; 
    } 
    // override the original hide so that the original is only called if the modal is unlocked 
    ,hide: function() { 
     // console.log('hide called'); 
     if (this.options.locked) return; 

     _hide.apply(this, arguments); 
    } 
}); 

Also, um das modale zu sperren:

$('#dlg').modal('lock');

und zu entsperren:

$('#dlg').modal('unlock');

Yay!

+0

Das scheint bei mir nicht zu funktionieren; Es stoppt das Schließen des Modals, während ich beim Ausfüllen des Formulars darauf klicke, aber sobald das Formular abgeschickt wird und ich .modal ("unlock") anrufe, wird sich das Modal verstecken ... Ich rufe nicht an .modal ("verstecken"), nur entsperren. Nicht sicher, wie das möglich wäre. irgendwelche Ideen? thx – Wesley

+1

Welche Version von Bootstrap verwenden Sie? – ragamufin

+0

Vielen Dank dafür. –

10

Es gibt einen einfacheren Weg, es zu tun. This Bootstrap Pull-Anfrage erklärt ein wenig mehr. Die Lösung deaktiviert alle Methoden zum Schließen des Modales (Tastatur, Mausklick, Schließen).

Alles, was Sie tun müssen, um zu deaktivieren, die modale Schließen ist:

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

wieder schließen zu aktivieren:

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

Beispiel

Hier einige Beispielcode, der in arbeitet Verbindung mit einem jQuery erhalten:

// 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); 
}); 
8

Sie eine Variable erstellen können isBlocked, dass Sie festlegen können, während Sie AJAX wahr nennt, dann können Sie es auf bootsrap modal verstecken Veranstaltung auf diese Weise überprüfen:

$('#myModal').on('hide.bs.modal', function (e) { 
     //Prevent modal from closing is isBlocked is true 
     if(isBlocked) return e.preventDefault(); 
}) 

Ich denke, diese Art und Weise ist einfacher als Bootsrap erstreckt , hoffe, es hilft jemandem: D

+0

definitiv der sauberste Weg, dies zu erreichen. +1 – con

Verwandte Themen