104

i'm using the modal example from the bootstrap 3 docs. the modal works. however i need to access the show.bs.modal event when it fires. for now i'm just trying:

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

Nothing happens, the event does not fire. What am I doing wrong??? This doesn't make sense to me.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
m4rlo
  • 1,153
  • 2
  • 7
  • 8

22 Answers22

131

use this:

$(document).on('show.bs.modal','#myModal', function () {
  alert('hi');
})
Ali
  • 1,528
  • 1
  • 10
  • 12
  • 11
    This solved my problem. But I placed it outside the document.ready function. When I placed within document.ready, It was not working. Might help someone. – Harish Kanakarajan Jul 14 '16 at 09:17
  • 3
    This should be the accepted answer as it works perfectly with dynamically created ajax modals via `$(data).modal('show');`. – kjdion84 Jul 15 '17 at 23:03
  • 2
    This would fire for each modal you have on the document. To target only specific modal you could use `$(document).on('hidden.bs.modal', function (e) { if (e.target.id === 'my-modal-id') { alert('hi'); } });`. Id here comes from ` – przno May 09 '18 at 13:52
  • 4
    @przno No it wouldn't, the second argument is the selector which specifies the element. – Tom Aug 23 '18 at 13:52
  • 3
    When you use `$(document).on(...` you attach your listener to *document* context, and its no matter if your target elemnts is exists or not. You should add event name as first argument and callback fanction as last, but you can add a query selector as second argument – Ali Jan 03 '20 at 01:00
87

Make sure you put your on('shown.bs.modal') before instantiating the modal to pop up

$("#myModal").on("shown.bs.modal", function () { 
    alert('Hi');
});
$("#myModal").modal('show'); //This can also be $("#myModal").modal({ show: true });

or

$("#myModal").on("shown.bs.modal", function () { 
    alert('Hi');
}).modal('show');

To focus on a field, it is better to use the shown.bs.modal in stead of show.bs.modal but maybe for other reasons you want to hide something the the background or set something right before the modal starts showing, use the show.bs.modal function.

Pierre
  • 8,397
  • 4
  • 64
  • 80
  • @kjdion84 - there where you create them, you should bind the events. `var amodal = $("
    "); amodal.on(...,myfunc).modal('show');
    – Pierre Jul 16 '17 at 09:28
  • You don't have to bind any events if you use `$(document).on()`. – kjdion84 Jul 16 '17 at 09:33
  • 3
    ^This solves my problem. Also, `show.bs.modal` is different from `shown.bs.modal`. The former fires when the modal is about to show. The latter when it has been shown. Big different. – Max Feb 06 '18 at 22:45
  • @KUMAR it is the event which bootstrap is calling when you call `.modal('show')`. There are four events it calls for modals: [`show.bs.modal`, `shown.bs.modal`, `hide.bs.modal`, `hidden.bs.modal`] - show is when it is going to show, shown when it is showing, the same for hide and hidden. https://getbootstrap.com/docs/3.4/javascript/#modals-events – Pierre Sep 15 '20 at 05:26
26

Wrap your function in $(document).ready(function() { }), or more simply, $(function() {. In CoffeeScript, this would look like

$ ->
  $('#myModal').on 'show.bs.modal', (event)->

Without it, the JavaScript is executing before the document loads, and #myModal is not part of the DOM yet. Here is the Bootstrap reference.

Robert Sinclair
  • 4,550
  • 2
  • 44
  • 46
Chloe
  • 25,162
  • 40
  • 190
  • 357
14
$(document).on('shown.bs.modal','.modal', function () {

/// TODO EVENTS

});
Zeekoi Inc.
  • 141
  • 1
  • 2
  • 2
    somehow this was the most helpful answer to me. it seems like working with `.modal` instead of referencing the modals id was the solution... thanks! – mabu Jan 29 '18 at 15:35
  • This is the best answer as it is nonspecific and will trigger on any modal being shown rather than when just a set modal triggers. – IDED Apr 05 '19 at 09:28
12

Try this

$('#myModal').on('shown.bs.modal', function () {
   alert('hi');
});

Using shown instead of show also make sure you have your semi colons at the end of your function and alert.

Trevor
  • 16,080
  • 9
  • 52
  • 83
  • 8
    Both 'show.bs.modal' and 'shown.bs.modal' should work for my purposes, they are both listed as valid events in the bootstrap docs. still doesn't work. – m4rlo Oct 09 '13 at 18:43
  • 1
    Have you verified that your jQuery is working e.g. $(document).ready(function(){alert('test');}); – Trevor Oct 09 '13 at 18:46
  • yes if i put an alert outside the show event, just within document.ready, then it fires. – m4rlo Oct 09 '13 at 18:47
  • Try making an example of you code here http://bootply.com/new and see if it works. If it doesn't work share your link and I can take a look at it. – Trevor Oct 09 '13 at 18:47
  • Make sure you have your `bootstrap.js` file loaded. – Trevor Oct 09 '13 at 18:54
  • thx for your help trevor -- it is rly still a mystery to me why it won't work. everything on my site is just like in your example. and i have a lot of experience with jquery/bootstrap. something weird and underlying must be going on but i don't even know where to look. – m4rlo Oct 09 '13 at 19:09
  • bootstrap.js is definitely loaded – m4rlo Oct 09 '13 at 19:09
  • Okay no problem, you could share your html and or webpage if you think it would help. Good luck figuring out what is going on. – Trevor Oct 09 '13 at 19:18
  • sure, here is the dev site - it's not cleaned up so disregard a lot of it -- the only thing i care about is that the alert('hi') work when the modal is fired. i just inserted the example to test. – m4rlo Oct 09 '13 at 19:28
  • The requested URL /gunnar_bootstrap/didyouseethis/js/application.js was not found on this server. – Bass Jobsen Oct 09 '13 at 20:18
  • 1
    @BassJobsen He is referencing application.js twice in his html one of them is loading the correct file. The other it's not found.. Would that cause the issue? – Trevor Oct 09 '13 at 20:48
  • 2
    Thanks @Trevor. It worked for me too. I was including 2 jquery.js. :-p – Akshay Vishnoi Sep 03 '16 at 18:58
8

Add this:

$(document).ready(function(){
    $(document).on('shown.bs.modal','.modal', function () {
         // DO EVENTS
    });
});
waka
  • 3,362
  • 9
  • 35
  • 54
zaarour
  • 107
  • 1
  • 4
7

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);                        
})
itsazzad
  • 6,868
  • 7
  • 69
  • 89
  • 1
    This is what I have been searching for! Thanks for pointing out the transition duration of the bootstrap! Kudos :D Even 150 works too :) – ShellZero Sep 27 '16 at 17:58
5

In my case, I was missing the .modal-dialog div

Doesn't fire event: shown.bs.modal

<div id="loadingModal" class="modal fade">
  <p>Loading...</p>
</div>

Does fire event: shown.bs.modal

<div id="loadingModal" class="modal fade">
  <div class="modal-dialog">      
    <p>Loading...</p>
  </div>
</div>
aeroson
  • 1,069
  • 13
  • 16
4

I had the same issue with bootstrap4. The solution was to add it inside the jQuery document ready() function:

$(document).ready(function() {
    $('#myModal').on('show.bs.modal', function () {
       alert('hi')
    })
})
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
Yuri Natividade
  • 354
  • 2
  • 3
  • Thank you - being a JS noob, had to wade through a ton of related questions/answers to find that this solved my problem of the modal, for whatever reason, only firing hte event handler on the second load (see https://stackoverflow.com/questions/20339958/bootstrap-modal-dialogs-shown-bs-modal-event-doesnt-fire) – Adam Hughes Jan 22 '21 at 21:59
4

This happens when code might been executed before and it's not showing up so you can add timeout() for it tp fire.

$(document).on('shown.bs.modal', function (event) {
      setTimeout(function(){
        alert("Hi");
      },1000); 
    });
3

I had a similar but different problem and still unable to work when I use $('#myModal'). I was able to get it working when I use $(window).

My other problem is that I found that the show event would not fire if I stored my modal div html content in a javascript variable like.

var content="<div id='myModal' ...";
$(content).modal();
$(window).on('show.bs.modal', function (e) {
  alert('show test');
});

the event never fired because it didn't occur

my fix was to include the divs in the html body

<body>
    <div id='myModal'>
       ...
    </div>
    <script>
        $('#myModal).modal();
        $(window).on('show.bs.modal', function (e) {
            alert('show test');
        });
    </script>
</body>
wjfinder77
  • 143
  • 4
3

Remember to put the script after the call of "js/bootstrap", not before.

3

Had the same issue. For me it was that i loaded jquery twice in this order:

  1. Loaded jQuery
  2. Loaded Bootstrap
  3. Loaded jQuery again

When jQuery was loaded the second time it somehow broke the references to bootstrap and the modal opened but the on('shown.bs..') method never fired.

d00d
  • 688
  • 1
  • 8
  • 29
  • Thanks. I had jquery loaded on the _Layout.cshtml and on my view on ASP.NET. I took me hours till I flow by your comment. – Stephan Feb 22 '21 at 19:09
2

Ensure that you are loading jQuery before you use Bootstrap. Sounds basic, but I was having issues catching these modal events and turns out the error was not with my code but that I was loading Bootstrap before jQuery.

travelsize
  • 74
  • 1
  • 4
2

Sometimes this doesn't work if:

1) you have an error in the java script code before your line with $('#myModal').on('show.bs.modal'...). To troubleshoot put an alert message before the line to see if it comes up when you load the page. To resolve eliminate JSs above to see which one is the problem

2) Another problem is if you load up the JS in wrong order. For example you can have the $('#myModal').on('show.bs.modal'...) part before you actually load JQuery.js. In that case your call will be ignored, so first in the HTML (view page source to be sure) check if the script link to JQuery is above your modal onShow call, otherwise it will be ignored. To troubleshoot put an alert inside the on show an one before. If you see the one before and not the one inside the onShow function it is clear that the function cannot execute. If the spelling is right more than likely your call to JQuery.js is not made or it is made after the onShow part

Alex Riabov
  • 8,655
  • 5
  • 47
  • 48
Marius
  • 190
  • 1
  • 9
  • This helped me - `$('#myModal').on('show.bs.modal'...)` needs to be after JQuery is loaded. Thanks! – Ian Wold Sep 14 '18 at 14:00
1

Make sure that you really use the bootstrap jquery modal and not another jquery modal.

Wasted way too much time on this...

0

In my case the problem was how travelsize comment.. The order of imports between bootstrap.js and jquery. Because I'am using the template Metronic and doesn't check before

0

i used jQuery's event delegation /bubbling... that worked for me. See below:

$(document).on('click', '#btnSubmit', function () {
                alert('hi loo');
            })

very good info too: https://learn.jquery.com/events/event-delegation/

0

The popular solution to put a setTimeout could work in some case, but is a terrible solution. I was myself using it amongst wraping it in $(document).ready() off course (but it never helped), but I was never able to have a reliable solution. Some browser/system take more time than other, and sometime 1000ms was not enough. And I was tired searching why the $(document).ready() wasn't helping, so :

I took a different approach.

I make the subscription to modal events when I need to use the modal for the first time.

<a href="javascript:void(0)" onclick="ShowModal()">Open my modal</a>

and on the JS side :

function ShowModal() {
    InitModalEventsOnce();
    $('#MyModal').modal('show');
}

var InitModalEventsIsDone = false; // Flag to keep track of the subscribtion

function InitModalEventsOnce() {

    if (!InitModalEventsIsDone) {
        InitModalEventsIsDone = true;

        $('#MyModal').on('shown.bs.modal', function () {
            // something
        })

        $('#MyModal').on('hidden.bs.modal', function (e) {
            // something
        });
    }
}

And that's it! The only reliable solution I found.

Matthieu Charbonnier
  • 2,794
  • 25
  • 33
  • You can also do `$('#MyModal').off('shown.bs.modal').on('shown.bs.modal' function(){..});` This can be helpful if you need to change any behaviors based on the modal being shown as opposed to only defining the event handler one time. – Dutchie432 Aug 24 '22 at 12:17
0

Try like this.

let mymodal=$('#myModal');
mymodal.on('show.bs.modal', function () 
{
    alert('hi')
});
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
  • Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Jun 09 '22 at 16:05
0

Native JavaScript event listener work:

$('#myModal')[0].addEventListener('shown.bs.modal', () => { 
    alert('hi');
});

Or

document.getElementById('myModal').addEventListener('shown.bs.modal', () => {   
    alert('hi');
});
-1

Below are the granular details:

show.bs.modal works while model dialog loading shown.bs.modal worked to do any thing after loading. post rendering

Anand
  • 5
  • 3