Bootstrap modal 'loaded' event on remote fragment
D

5

21

I'm currently using Twitter Bootstrap modal component and i have an issue where I use jquery validation plugin on input fields in the content I load remotely using the data-remote attribute.

Because the content is loaded after jquery validation has run across the dom, validation doesn't occur for the newly loaded elements.

I have a solution where I modify bootstrap.js (the modal class), see below.

  var Modal = function (element, options) {
    this.options = options
    this.$element = $(element)
      .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
    //this.options.remote && this.$element.find('.modal-body').load(this.options.remote)

    this.options.remote && this.$element.find('.modal-body').load(this.options.remote, $.proxy(function () {
        this.$element.trigger('loaded')
    }, this)) //my additions
  }

I trigger a 'loaded' event to the call that loads the external html fragment.

I already have this event wired up and i call the validation on the newly loaded elements.

$('#myModal').on('loaded', function () {
                $.validator.unobtrusive.parse($(this));
            });

My issue is that I had to modify bootstrap.js to achieve this, is there a way I can have this working externally without modifying bootstrap.js? Is there a way to access the modal object on a page and attach the 'loaded' event to it? i'd like to do this in an external script or within a page so i don't need to worry about bootstrap versions.

Devote answered 23/9, 2013 at 12:29 Comment(2)
Is there an issue with doing the validation in the shown event of the modal?Romaic
@Romaic For remote content, the shown triggers before the new elements are loaded.Devote
R
18

According to both these issues:

https://github.com/twbs/bootstrap/issues/5169

https://github.com/twbs/bootstrap/pull/6846

..as of now the Bootstrap developers are digging their heels in and refusing to add a loaded event into Bootstrap.

So instead they recommend you avoid using the data-remote markup and load the data yourself into the modal:

$('#myModal').modal(your_options).find('.modal-body').load('request_url', function () {
  // do cool stuff here all day… no need to change bootstrap
}')
Romaic answered 23/9, 2013 at 14:7 Comment(2)
You are great! Thank for this solution! This helped me with this problem: #20340458Malanie
Just a quick note so people don't just go with the accepted answer without checking. Bootstrap has had a 'loaded.bs.modal' event for a while now - getbootstrap.com/javascript/#modals.Leopold
C
36

Just an update here:

Bootstrap has added a loaded event.

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

capture the 'loaded.bs.modal' event on the modal

$('#myModal').on('loaded.bs.modal', function (e) {
  // do cool stuff here all day… no need to change bootstrap
})
Crystallize answered 7/4, 2014 at 21:0 Comment(5)
Thanks you prevented me from having no more hair on my head!Affix
Please remove the ' from the last line. It should be }) not }')Castalia
This event work only when content of the modal is loaded with remote option, if the content is embeded in the html modal not workAnergy
Any idea when this was added? It's not working for meJovia
This work when we need to call a function after loading script in bootstrap remote modal . Thank you.Jubbulpore
S
19

The 'loaded.bs.modal' event doesn't work for me, so I have tried the 'shown.bs.modal' event and it's works fine :

$('#myModal').on('shown.bs.modal', function () {
   // do cool stuff here...
});

This event is captured after the modal is shown.

I hope this will help someone :)

Spang answered 24/2, 2015 at 11:23 Comment(3)
the modals first shows, then loads the remote content, so it doesn't workStevenstevena
This isn't relevant to the question. The question involves ajax loaded content and 'shown' is never triggered as a product of an ajax response.Choreography
Worked for me too. My modal-body is loaded with ajax, then shown. Maybe not relevant to the question, but helpful for some of us :-)Eno
R
18

According to both these issues:

https://github.com/twbs/bootstrap/issues/5169

https://github.com/twbs/bootstrap/pull/6846

..as of now the Bootstrap developers are digging their heels in and refusing to add a loaded event into Bootstrap.

So instead they recommend you avoid using the data-remote markup and load the data yourself into the modal:

$('#myModal').modal(your_options).find('.modal-body').load('request_url', function () {
  // do cool stuff here all day… no need to change bootstrap
}')
Romaic answered 23/9, 2013 at 14:7 Comment(2)
You are great! Thank for this solution! This helped me with this problem: #20340458Malanie
Just a quick note so people don't just go with the accepted answer without checking. Bootstrap has had a 'loaded.bs.modal' event for a while now - getbootstrap.com/javascript/#modals.Leopold
J
0

I had a rather interesting catch, In my case, on localhost, the event loaded.bs.modal was firing before the event shown.bs.modal since on local host the act of fetching the data from the "remote" url(which was local btw), was happening instanteneously even before the bootstrap could finish its transition and trigger the shown.bs.modal event.

But on a webserver the events were firing in the perceived order.

First the shown.bs.modal was being triggered and then owing to the pragmatic latency of the remote url, the event loaded.bs.modal was being triggered.

What I wanted is to grab an event whichever happened the last.

So to solve it I came up with my own implementation as below. YMMV, Now there are a lot of assumptions here, so take the below code as just a POC and with a grain of salt rather than a full fledged code.

jQuery('#myModal').on('shown.bs.modal', function () {
    if (jQuery(this).find('.resetFlag').length) {
        // Do something ONLY IF "loaded.bs.modal" hasn't yet been triggered
    }
});
jQuery('#myModal').on('loaded.bs.modal', function (e) {

    if (jQuery(this).find('.resetFlag').length) {
        // Do something ONLY IF "shown.bs.modal" hasn't yet been triggered
        } else  {
        // Do something ONLY IF "shown.bs.modal" hasn already been triggered
        }
});
jQuery('#myModal').on('hidden.bs.modal', function () {
    jQuery('#myModal .modal-content').html('<div class="resetFlag" style="display:none;"></div>');
    showModalLoader();
});
Jedthus answered 16/11, 2018 at 12:14 Comment(0)
C
0

Boostrap 3.3's modal events has the loaded.bs.modal event.

however in Bootstrap 4's modal events dose not have this event. I would recommend using the shown.bs.modal event as it fires after the CSS has been rendered

Chlordane answered 16/12, 2020 at 5:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.