33

Tôi đang sử dụng các phương thức Bootstrap Twitter, với các tùy chọn mặc định, nơi bạn có thể nhấp vào phông nền hoặc nhấn [Esc] để đóng phương thức.Twitter Bootstrap/jQuery - Làm thế nào để tạm thời ngăn chặn phương thức bị đóng?

Tuy nhiên, khi tôi bắt đầu hoạt động ajax theo phương thức, tôi muốn vô hiệu hóa phương thức bị đóng theo bất kỳ cách nào. Vì vậy, tôi vô hiệu hóa các nút và ẩn nút đóng của phương thức nhưng tôi không thể tìm ra cách tắt phông nền và phím [Esc].

tôi đã cố gắng:

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

Nhưng điều này dường như không làm việc một cách nhanh chóng.

Tôi cũng sẽ cần phải bật lại phông nền và bàn phím khi thao tác ajax kết thúc.

Trả lời

17

Note: Giải pháp này được nhắm mục tiêu twitter bootstrap 2.x! Xem this answer (ngay bên dưới) để biết các khác biệt theo bootstrap 3.


Mở rộng chức năng modal bootstrap mà không thay đổi nguồn gốc.

Nhờ @David và đề xuất của anh ấy theo số How to Extend Twitter Bootstrap Plugin Tôi cuối cùng cũng làm việc đó. Nó là một phiên bản sửa đổi một chút của giải pháp của mình với phương thức "khóa" được thêm vào. Tôi đăng nó như là một câu trả lời bổ sung kể từ khi tôi nghĩ rằng nó có thể có thể là một điểm khởi đầu cho những người khác mà như tôi đã đấu tranh khó khăn với vấn đề này.

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

Với kỹ thuật này không cần thiết phải thay đổi bootstrap.js và cùng một chức năng có thể dễ dàng được chia sẻ giữa các dự án khởi động. Phương pháp này nên được áp dụng cho tất cả các plugin bootstrap khác. Cho đến nay chỉ thử với nút mặc dù, nhưng tôi không thể se tại sao nó không nên.

thấy fiddle làm việc ->http://jsfiddle.net/Sz7ZS/

+0

sau khi tôi áp dụng phương pháp này, phông nền (nền màu xám) dường như biến mất. tôi cần phải tự $ ('# thisModal'). phương thức ({backdrop: true}); để dùng nó. đây có phải là một sai lầm hay đây là cách duy nhất để làm điều đó? –

+0

@TianLoon. Đã cập nhật câu trả lời với thông báo về phiên bản bootstrap và [jsfiddle] (http://jsfiddle.net/Sz7ZS/) bằng cách sử dụng bootstrap 2.3.2 (phiên bản 2.x phổ biến nhất). Trong bối cảnh, phông nền xuất hiện - có thể bạn đã vô tình đặt nó thành mờ 0, màu trắng hay gì đó? – davidkonrad

+0

THANK YOU SO MUCH CHO NÀY !!!!! –

9

Bạn không phải là người duy nhất thiếu tính năng đó. Tôi nghĩ rằng bootstrap đôi khi quá "tối giản", những người đứng đằng sau có ý tưởng rất nhiều nên được thực hiện trong "lớp thực hiện", nhưng nó là không sử dụng khi các plugin jQuery bootstrap tự làm cho nó không thể!

Bạn phải thực hiện các chức năng chính mình, như thế này:

trong bootstrap.js v2.1.1 phương thức bắt đầu tại dòng 61.

trong Modal.prototype, thêm hai chức năng, lockunlock, vì vậy nó trông như thế này (tôi chỉ hiển thị ở đây là bắt đầu của modal.prototype, bởi vì nó quá nhiều mã)

Modal.prototype = { 

     constructor: Modal 

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

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

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

Sau đó, cũng trong Modal.prototype, tìm ra chức năng hide, và thêm một dòng để nó trông như thế này (một lần nữa, chỉ có đầu ẩn được thể hiện)

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

    var that = this 

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

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

Và cuối cùng, thay đổi $.fn.modal.defaults tới:

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

Bây giờ bạn có chức năng khóa/mở khóa trực tiếp trong phương thức khởi động, ngăn người dùng đóng phương thức ở những thời điểm quan trọng.

Ví dụ:

Đây là một phiên bản sửa đổi của "Live Demo" từ 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"> 

Tôi đã chèn hai nút "lock" và "unlock" - khi nhấn vào, họ đặt các phương thức trong chế độ khóa hoặc bình thường (các thiết lập nó được khởi tạo với)

Sửa, trong trường hợp của bạn, bạn chỉ cần gọi khóa/onlock khi làm ajax:

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

Điều này hoạt động tốt, nhưng bạn có thể thực hiện điều này bằng cách mở rộng mã Bootstrap cốt lõi, thay vì sửa đổi nó? – BadHorsie

+0

Có, cuối cùng đã tìm ra :) nhờ @david và cảm ơn bạn. – davidkonrad

6

Cảm ơn @davidkonrad cho công việc của bạn về vấn đề này. Tôi đã cố gắng để thực hiện điều này là tốt và nó có vẻ như mọi thứ đã thay đổi với bootstrap 3. Bây giờ thay vì:

_superModal.defaults

nó bây giờ được gắn vào các nhà xây dựng, do đó bạn phải làm

_superModal.Constructor.DEFAULTS

Ngoài ra các nhà xây dựng đã thay đổi có nghĩa là tôi đã phải sao chép nó và sửa đổi nó là ít hơn lý tưởng. Thay vào đó, tôi đã đưa ra đoạn mã sau hoạt động và không sao chép hàm khởi tạo và nên được đánh lừa bằng chứng nếu bootstrap thay đổi trong tương lai. Có một đi:

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

Vì vậy, để khóa các phương thức:

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

và để mở khóa:

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

Yay!

+0

Điều này dường như không hiệu quả đối với tôi; Nó dừng phương thức đóng khi tôi nhấp vào bên ngoài khi biểu mẫu được gửi, nhưng ngay khi biểu mẫu được gửi và tôi gọi .modal ("mở khóa") - phương thức sẽ ẩn ... Tôi không gọi .modal ("ẩn"), chỉ mở khóa. Không chắc chắn làm thế nào mà có thể. bất kỳ ý tưởng? thx – Wesley

+1

Bạn đang sử dụng phiên bản bootstrap nào? – ragamufin

+0

Cảm ơn bạn rất nhiều vì điều này. –

10

Có cách dễ dàng hơn để thực hiện việc này. This yêu cầu kéo bootstrap giải thích thêm một chút. Giải pháp này vô hiệu hóa tất cả các phương thức để đóng phương thức (bàn phím, nhấp chuột, nút đóng).

Tất cả bạn phải làm gì để vô hiệu hóa đóng modal là:

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

Để kích hoạt đóng cửa một lần nữa:

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

Ví dụ

Dưới đây là một số mẫu mã mà làm việc trong kết hợp với jQuery nhận được:

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

Bạn có thể tạo một biến isBlocked mà bạn có thể thiết lập trong khi làm AJAX gọi là true, sau đó bạn có thể kiểm tra nó trên bootsrap phương thức ẩn sự kiện theo cách này:

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

Tôi nghĩ rằng cách này là dễ dàng hơn mở rộng Bootsrap , hy vọng nó sẽ giúp một ai đó: D

+0

chắc chắn là cách sạch nhất để đạt được điều này. +1 – con

Các vấn đề liên quan