33

Twitter Bootstrap modellerini kullanarak, arka planı tıklatabileceğiniz varsayılan seçeneklerle veya modemi kapatmak için [Esc] tuşuna basın. Ancak, modelde bir ajax işlemi başlattığımda, modelin herhangi bir şekilde kapatılmasını engellemek istiyorum. Düğmeleri devre dışı bırakıyorum ve modalın kapat düğmesini gizledim ama arka planı ve [Esc] tuşunu nasıl devre dışı bırakacağımı anlayamıyorum.Twitter Bootstrap/jQuery - Modalın kapatılmasını nasıl geçici olarak engelleyebiliriz?

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

Ama bu anında çalışmak için görünmüyor:

denedim.

Ayrıca ajax işlemi bittiğinde zemini ve klavyeyi yeniden etkinleştirmem gerekiyor.

cevap

17

Not: Bu çözüm twitter bootstrap 2.x hedefliyor! Önyükleme 3'e göre farklar için bkz. this answer (hemen aşağıda).


orijinal kaynağını değiştirerek olmadan önyükleme modal işlevselliği genişletme.

@David ve önerisi sayesinde How to Extend Twitter Bootstrap Plugin nihayet işe koyuldum. Bu modal "kilit" ekledi onun çözüm biraz değiştirilmiş bir sürümüdür. Bunu ek bir yanıt olarak gönderiyorum çünkü bence bu konuyla çok uğraştığım gibi başkaları için bir başlangıç ​​noktası olabileceğini düşünüyorum. o bootstrap.js değiştirme nessecary olmamalı bu tekniğin ve aynı işlevselliği ile

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

daha kolay önyükleme proje arasında paylaşılabilir. Bu yöntem diğer tüm bootstrap eklentileri için geçerli olmalıdır. Şimdiye kadar sadece düğme ile denediniz mi, ama neden olmasın diye bir şey göremiyorum.

çalışma keman bakınız ->http://jsfiddle.net/Sz7ZS/

+0

arka plan (gri arka plan) kayboluyor gibi görünüyor. el ile $ ('# thisModal'). modal ({backdrop: true}); onu kullanmak için. Bu bir hata mı yoksa bunu yapmanın tek yolu bu mu? –

+0

@TianLoon. Bootstrap sürümü ve [jsfiddle] (http://jsfiddle.net/Sz7ZS/) bootstrap 2.3.2 (en "popüler" 2.x sürümü) kullanarak bildirimle ilgili güncellemeyi güncellediniz. Kemanda arka plan belirir - belki de yanlışlıkla 0, beyaz ya da bir şey opak olarak ayarladınız? – davidkonrad

+0

BU İÇİN ÇOK TEŞEKKÜR EDERİZ !!!!! –

9

Bu özelliği özleyen tek kişi siz değilsiniz. Bence bootstrap bazen çok "minimalist", arkasındaki insanlar "uygulama katmanında" yapılması gereken çok şey var ama jQuery önyükleme takozları kendilerini imkansız hale getirdiğinde hiçbir faydası yok!

bootstrap.js v2.1.1 modal böylece görünüyor, iki işlev, lock ve unlock ekleyin Modal.prototype içinde

hattı 61. başlar: Bu gibi

Sen, işlevsellik kendiniz uygulamak zorunda böyle

Modal.prototype = { 

     constructor: Modal 

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

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

    , toggle: function() { 
    ... 
    ... 
(ben çok fazla kodudur çünkü burada modal.prototype sadece baş göstermesi) 0 Sonra da Modal.prototype de, işlevini hide bulmak ve bu (yine derinin sadece üst gösterdi) şuna benzer şekilde

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

    var that = this 

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

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

bir satır ekleyin Ve nihayet, için $.fn.modal.defaults değiştirmek:

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

Artık, önyükleme modalınızda, anında mobili kilitleme/kilit açma işleviniz var; bu da kullanıcının modalını kritik anlarda kapatmasını engelliyor.

Örnek:

Bu değişmiş bir ben "kilit", iki düğme ekledikten 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"> 

den "Canlı Demo" versiyonu ve "kilit açma" dır - tıklandığında onlar set kipli kilitli veya normal modda (başlangıç ​​durumuna getirilen ayarlar)

'u düzenleyin, yalnızca sizin için kilit/onlock çağırmanız yeterlidir. yapıyor ajax:

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

Bu işe yarıyor, ancak bunu değiştirmek yerine çekirdek Bootstrap kodunu genişleterek uygulayabilir misiniz? – BadHorsie

+0

Evet, sonunda anladım :) @david teşekkürler ve teşekkürler. Bu yöntemi uyguladıktan sonra – davidkonrad

6

Bu sayede işin için @davidkonrad. Ben de bu uygulamaya çalışıyordu ve işlerin yerine Şimdi bootstrap 3. ile değişmiş gibi görünüyor: artık yapıcı takılır

_superModal.defaults

Eğer

_superModal.Constructor.DEFAULTS

yapmak zorunda

Ayrıca yapıcı değişti, bu da onu kopyalamak ve idealden daha azını değiştirmek zorunda kalmam anlamına geliyordu. Bunun yerine, kurucuyu kopyalayan ve kopyalayan aşağıdaki kodla geldim ve önyükleme değişiklikleri devam ederse daha da aldatıcı olmamalıdır. modal kilitlemek amacıyla Yani

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

:

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

ve kilidini açmak için: gitmek var

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

Yay!

+0

Bu benim için çalışmıyor gibi görünüyor; Form gönderilirken dışına tıklarken modalın kapanmasını durdurur, ancak form gönderilir gönderilmez, ve .modal ("unlock") olarak adlandırılır - modal gizlenir ... Arama yapmıyorum .modal ("gizle"), sadece kilidini aç. Bunun nasıl mümkün olabileceğinden emin değilim. herhangi bir fikir? thx – Wesley

+1

Hangi bootstrap sürümünü kullanıyorsunuz? – ragamufin

+0

Bunun için çok teşekkür ederim. –

10

Bunu yapmanın daha kolay bir yolu var. This bootstrap çekme isteği biraz daha açıklıyor. Çözüm, modalın kapatılmasına yönelik tüm yöntemleri devre dışı bırakır (klavye, fare tıklaması, kapat düğmesi).

Eğer modal kapanış devre dışı bırakmak için yapmanız gereken tek şey:

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

tekrar kapatarak etkinleştirmek için:

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

Örnek Burada

çalışan bazı örnek kod jQuery ile birlikte olsun:

// 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); 
}); 
Bir değişken yaptığını AJAX gerçek çağrıları yaparken, o zaman bootsrap modal gizlemek olayı bu şekilde kontrol edebilirsiniz ayarlayabileceğini isBlocked oluşturabilir
8

: Ben bu şekilde Bootsrap uzanan daha kolay olduğunu düşünüyorum

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

umarım birisine yardım eder: D

+0

kesinlikle bunu başarmanın en temiz yolu. +1 – con

İlgili konular