13

According to the docs:

http://getbootstrap.com/javascript/#modals

It should fire the methods "show.bs.dropdown" and "shown.bs.dropdown". But it doesn't:

http://jsfiddle.net/mQunq/3/

HTML:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">Hello world</div>
    </div>
</div>

jQuery:

// show.bs.modal doesn't work either

$('#myModal')
    .modal('show')
    .on('show.bs.modal', function() {

        alert('shown baby!');

    });
0

8 Answers 8

31

Youe need first register event then trigger it

$('#myModal')
    .on('show.bs.modal', function() {

        alert('shown baby!');

    }).modal('show');

jsfiddle

4
  • Ahh ok makes sense. I didn't know I had to register it myself, I thought the core plugin triggered it. I think that's the way it used to work with the previous version.
    – user967451
    Commented Oct 29, 2013 at 16:08
  • This answer needs more attention. I ran into a similar issue of forcing a modal open based on some conditions. Took me a bit of digging to find out this was the way to do it.
    – Shaazaam
    Commented Feb 23, 2016 at 18:11
  • Agree with @Shaazaam - there must be a dozen or so answers on stackoverflow that have not addressed the registration and triggering requirement.
    – user6743474
    Commented Mar 12, 2019 at 12:05
  • Also note that the modal is not supposed to be shown at the moment of triggering the show.bs.modal event. The correct event to be handled is shown.bs.modal. The latter one waits for CSS transitions to finish. Commented Nov 7, 2019 at 7:52
11

When it happens

Event shown.bs.modal is not fired when modal has also class "fade". Whereas show.bs.modal always works. See https://github.com/twbs/bootstrap/issues/11793

HTML:

<div class="modal fade" id="first" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">Hello world from first modal</div>
    </div>
</div>
<div class="modal" id="second" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">Hello world from second modal</div>
    </div>
</div>

jQuery:

$('.modal').on('shown.bs.modal', function() {
    //fired only in second modal
    console.info('shown.bs.modal');
});

$('.modal').on('show.bs.modal', function() {
    //fired always
    console.info('show.bs.modal');
});


Solution

For bootstrap v3.3.6 replace line 1010 with:

that.$element // wait for modal to slide in

What is the problem

Look at lines 1006-1015:

  var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })

  transition ?
    that.$dialog // wait for modal to slide in
      .one('bsTransitionEnd', function () {
        that.$element.trigger('focus').trigger(e)
      })
      .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
    that.$element.trigger('focus').trigger(e)

Without transition (no fade class) the event e is triggered right away (on that.$element). With transition, I'm not sure why exactly, but somehow the bsTransationEnd event from function emulateTransitionEnd is not handled by that.$dialog.one(). But with that.$element, everything seem to work.

3

Similar thing happened to me and I have solved using setTimeout.

Bootstrap is using the following timeout to complete showing:

c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,

So using more than 300 must work and for me 200 is working:

$('#myModal').on('show.bs.modal', function (e) {
    setTimeout(function(){
        //Do something if necessary
    }, 300);                        
})
1
  • 1
    @ShellZero 150 - depends on what's the fade-in/fade-out time for the modal. By default it's 150 ms. For safety I'd use 160 ms for setTimeout.
    – Csaba Toth
    Commented Sep 25, 2017 at 16:50
1

you forgot the "n" on shown

$(document).ready(function(){
    $('#myModal')
.modal('show')
.on('shown.bs.modal', function() {

    alert('shown baby!');

});

});
1
  • 1
    Both are events. show.bs.modal fires immediately; shown.bs.modal fires after the modal has faded in.
    – Andrew
    Commented Jan 23, 2014 at 19:30
1

Use document instead of your custom selector. Both shown.bs.modal and show.bs.modal work just fine

$(document).on('shown.bs.modal', '.modal', function() {
    alert();
});
1

In case someone stumbles upon this problem, make sure you hook the on hidden / shown event before firing the toggle of the modal. That is, declare this:

$("#selector").on("hidden.bs.modal", function () {
    // do the right thing
});     

Before calling the toggle of the modal, e.g.:

("#selector").modal("toggle");

I know this is basic, but in a convoluted code it happens.

0

I found a solution that works with .fade transitions:

$(document).on($.support.transition.end, '.modal.fade.in', function(e) {
  var $target = $(e.target);
  if ($(e.target).is(".modal-dialog")) {
    console.log("Modal Shown")
  }
});

$(document).on($.support.transition.end, '.modal.fade', function(e) {
  var $target = $(e.target);
  if (!$target.is(".modal.fade.in") && !$target.is(".modal-dialog")) {
    console.log("Modal Hidden")
  }
});
0

If your modal is dynamically created, select the closest static parent element and add your modal as a parameter for bootstrap modal events to work:

/* body is static, .modal is not */

$("body").on('shown.bs.modal', '.modal', function() {

    alert('shown');

});


$("body").on('hidden.bs.modal', '.modal', function() {

    alert('hidden');

});


$("body").on('show.bs.modal', '.modal', function() {

    alert('show');

});


$("body").on('hide.bs.modal', '.modal', function() {

    alert('hide');

});