web-dev-qa-db-fra.com

Bootstrap modal 'chargé' sur un fragment distant

J'utilise actuellement le composant modal Twitter Bootstrap et j'ai un problème où j'utilise le plug-in de validation jquery sur les champs d'entrée du contenu que je charge à distance à l'aide de l'attribut data-remote.

Comme le contenu est chargé après la validation de jQuery sur le dom, la validation n'a pas lieu pour les éléments récemment chargés.

J'ai une solution où je modifie bootstrap.js (la classe modale), voir ci-dessous.

  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
  }

Je déclenche un événement "chargé" à l'appel qui charge le fragment HTML externe.

J'ai déjà cet événement câblé et j'appelle la validation sur les éléments nouvellement chargés.

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

Mon problème est que j'ai dû modifier bootstrap.js pour y parvenir. Y a-t-il un moyen de faire fonctionner cela en externe sans modifier bootstrap.js? Existe-t-il un moyen d'accéder à l'objet modal sur une page et de lui associer l'événement 'chargé'? Je voudrais le faire dans un script externe ou dans une page afin que je n'ai pas à m'inquiéter des versions de bootstrap.

16
scartag

Selon ces deux questions:

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

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

..as les développeurs Bootstrap se creusent la tête et refusent d’ajouter un événement loaded à Bootstrap.

Au lieu de cela, ils vous recommandent d'éviter d'utiliser le balisage data-remote et de charger les données vous-même dans le modal:

$('#myModal').modal(your_options).find('.modal-body').load('request_url', function () {
  // do cool stuff here all day… no need to change bootstrap
}')
17
mccannf

Juste une mise à jour ici:

Bootstrap a ajouté un événement chargé.

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

capturer l'événement 'Load.bs.modal' sur le modal

$('#myModal').on('loaded.bs.modal', function (e) {
  // do cool stuff here all day… no need to change bootstrap
})
33
George

L'événement "Loaded.bs.modal" ne fonctionne pas pour moi, j'ai donc essayé l'événement "shown.bs.modal" et ça fonctionne bien: 

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

Cet événement est capturé après l'affichage du modal.

J'espère que cela aidera quelqu'un :)

13

J'ai eu un piège assez intéressant, dans mon cas, sur localhost, l'événement loaded.bs.modal était déclenché avant l'événement shown.bs.modal puisque sur hôte local l'acte consistant à récupérer les données à partir de l'URL "remote" (qui était local), se passait instantanément avant même que le bootstrap puisse achever sa transition et déclencher l'événement shown.bs.modal.

Mais sur un serveur Web, les événements se sont déroulés dans le ordre perçu .

Tout d'abord, le shown.bs.modal était déclenché, puis en raison de la latence pragmatique de l'URL distante, l'événement loaded.bs.modal était en cours de déclenchement.

Ce que je voulais, c'est saisir un événement peu importe ce qui s'est passé le dernier.

Donc, pour résoudre ce problème, j’ai imaginé ma propre implémentation comme indiqué ci-dessous. YMMV, Maintenant, il y a beaucoup d'hypothèses ici, prenez donc le code ci-dessous comme un simple POC et avec un grain de sel plutôt qu'un code à part entière.

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();
});
0
Mohd Abdul Mujib