Viblo CTF
+1

Multiple Bootstrap Modals with next/prev buttons

Modal là component trong bootstrap cho phép hiển thị 1 popup với kích thước và hiệu ứng tùy chỉnh. Mục đích của Modal để show nội dung trong trạng thái ẩn, khi cần sẽ click vào 1 thành phần của DOM để hiển thị nó, hoặc ngay khi vào trang, nếu bạn muốn người dùng focus luôn vào nội dung nào đó trước tiên thì sẽ gọi luôn Modal lên khi page load, ví dụ những trang thương mại điện tử đang có event sale off chẳng hạn.

Example:

<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
  Launch demo modal
</button>

<div id="myModal"  class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
        <h4 class="modal-title">This is Modal</h4>
      </div>
      <div class="modal-body">
        <p>Modal body</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

Button ở trên sẽ call modal với id #myModal ở dưới đang ở trang thái hidden thông qua data-attribue là -target=”id đến modal cần mở”

Các thuộc tính khác, tạm không quan tâm. Chi tiết bạn tham khảo https://viblo.asia/maiptn226/posts/RnB5pnBJZPG

Okey, với yêu cầu đơn giản thì là như vậy, show ra 1 popup, sau đó tắt nó đi. Tuy nhiên thực tế mình thấy nhu cầu nó không chỉ có như vậy. Trường hợp yêu cầu sẽ tới như thế này không phải là ít.

“Tôi muốn khi vào trang show ra một PopUp có nội dung là sơ đồ web, vì trang web của chúng tôi khá là nhiều level, à ngoài ra tôi cũng muốn mở ra môt popup khác cho khách hàng thấy được riêng khu vực này của website đang bảo trì, một cái nữa Faq khi vào trang web…”

Vậy nghĩa là khi client vào web, sẽ show ra thứ tự 3 cái modal, tuy nhiên ta không biết được khi nào thì họ đọc xong cái này để close lại và show ra cái còn lại…

Solution là add thêm 1 nút next cho modal, họ có thể next trực tiếp sau khi đọc xong, hoặc tắt đi luôn ko show ra cái nào cả nếu họ thật sự không quan tâm lắm.

Trường hợp ví dụ thứ 2 điển hình hơn là khi client đăng ký user, họ click vào sigIn, modal mở ra với form đăng nhập. Nhưng họ chợt nhớ ra rằng mình chưa có tài khoản, vậy có 2 cách, 1 là tắt modal đi, click vào SigUp để đăng ký và mở ra 1 modal với form đăng ký. 2 là trong form đăng nhập, có luôn nút “Click to Sigup”. Click vào thì ra trang đăng ký.

Solution là click vào button đăng ký thì close form đăng nhập và lập tức mở modal form đăng ký → giảm thao tác. Okey về ux. Cách làm thì hẳn là có nhiều nhưng mình xin giới thiệu cách đơn giản với bootstrap framework thôi.


Tạo một modal thứ nhất :

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal1">
  Player 1
</button>
 
<!-- Modal -->
<div class="modal fade" id="myModal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Modal title 1</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default btn-prev">Prev</button>
        <button type="button" class="btn btn-default btn-next">Next</button>
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

Tương tự có các modal thứ và 3 như sau:

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal2">
  Player 2
</button>
<!-- Modal -->
<div class="modal fade" id="myModal2" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
     Nội dung cho Modal 2
 </div>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal3">
  Player 3
</button>
<!-- Modal -->
<div class="modal fade" id="myModal3" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  Nộ dung cho Modal 3
</div>

Javascript:

// Duyệt qua tất cả các id có bắt đầu bằng myModal → các modal step nên có kiểu id hoặc class hợp lý
$("div[id^='myModal']").each(function(){
  var currentModal = $(this);
  //click next
    currentModal.find('.btn-next').click(function(){
    currentModal.modal('hide');
//hide modal hiện tại    
    currentModal.closest("div[id^='myModal']").nextAll("div[id^='myModal']").first().modal('show');
 // Đây chính là code xử lý phần next modal, click btn-next -> close modal hiện tại --> tìm các modal tiếp theo --> trigger modal đầu tiên tiếp theo với .modal('show')
//Call back khi close modal hiện tại sẽ next tới tất cả cả modal còn lại và lấy cái tiếp theo đầu tiên cho nó show lên và cứ như vậy.
  });
 
  //click prev
    currentModal.find('.btn-prev').click(function(){
    currentModal.modal('hide');
    currentModal.closest("div[id^='myModal']").prevAll("div[id^='myModal']").first().modal('show');
// Tương tự với nút preview nếu bạn cần.
  });
});

Các button có thể không cần thiết, tùy nhu cầu của bạn. Thực tế nút next và preview đã trigger các event show/hide modal rồi.

Mình tạo 1 demo đơn giản show kết quả như demo bên trên ở đây : CodePen https://codepen.io/adambui/pen/KmJwdw Cám ơn đã đọc!


All Rights Reserved