Recharger le contenu en modal (bootstrap Twitter)

98

J'utilise le popup modal de Twitter Bootstrap.

<div id="myModal" class="modal hide fade in">
    <div class="modal-header">
        <a class="close" data-dismiss="modal">×</a>
        <h3>Header</h3>
    </div>
    <div class="modal-body"></div>
    <div class="modal-footer">
        <input type="submit" class="btn btn-success" value="Save"/>
    </div>
</div>

Je peux charger du contenu en utilisant ajax avec cet élément a:

<a data-toggle="modal" data-target="#myModal" href="edit.aspx">Open modal</a>

Maintenant, je dois ouvrir le même modal mais en utilisant une URL différente. J'utilise ce modal pour modifier une entité de ma base de données. Ainsi, lorsque je clique sur modifier sur une entité, je dois charger le modal avec un identifiant.

<a data-toggle="modal" data-target="#myModal" href="edit.aspx?id=1">Open modal</a>
<a data-toggle="modal" data-target="#myModal" href="edit.aspx?id=2">Open modal</a>
<a data-toggle="modal" data-target="#myModal" href="edit.aspx?id=3">Open modal</a>

Si je clique sur le lien numéro 1, cela fonctionne bien. Mais si je clique ensuite sur le lien numéro 2, le contenu modal est déjà chargé et il affichera donc le contenu du lien numéro 1.

Comment puis-je actualiser ou réinitialiser le contenu chargé ajax dans une fenêtre contextuelle modale d'amorçage Twitter?

stian.net
la source
2
duplication possible du modal distant de bootstrap
Marijn
Eu le même problème et habitué à la même solution. J'ai recours à la fonction .attr () de jquery pour une raison étrange. La fonction .data () ne fonctionnait pas.
user1803784

Réponses:

98

J'ai le même problème, et je suppose que la façon de le faire sera de supprimer l'attribut data-toggle et d'avoir un gestionnaire personnalisé pour les liens.

Quelque chose dans les lignes de:

$("a[data-target=#myModal]").click(function(ev) {
    ev.preventDefault();
    var target = $(this).attr("href");

    // load the url and show modal on success
    $("#myModal .modal-body").load(target, function() { 
         $("#myModal").modal("show"); 
    });
});

Je vais l'essayer plus tard et publier des commentaires.

Markz
la source
16
$ ('. modal'). on ('hidden', function () {$ (this) .removeData ();}) c'est ma modification de la solution ci-dessous ... nettoyeur parce que vous n'avez pas à attraper le clic et à charger it your self so programmatic model show works still
Carter Cole
1
J'utilise Bootstrap 3, le contenu du modal est actualisé à chaque fois, mais il crée deux fenêtres modales. Est-ce que quelqu'un d'autre comprend cela?
Mr B
1
Hey Sid, vous créez 2 divs avec la classe "modal-body", en fait vous le créez déjà, et le modal est en train de créer à nouveau. À partir de ce code, supprimez le '.modal-body' et devrait fonctionner correctement.
Palantir
1
Fonctionne pour moi avec Bootstrap 3, très frustrant que cela ne soit pas pris en charge par la bibliothèque d'amorçage principale par défaut.
Josh Diehl
@markz, j'utilise également quelque chose comme ça et ev.preventDefault (); aussi mais toujours sur clic de lien, quand j'obtiens la fenêtre modale, toutes les listes déroulantes de ma page sont réinitialisées. Une idée, comment éviter cela?
Jaikrat
73

Pour décharger les données lorsque le modal est fermé, vous pouvez l'utiliser avec Bootstrap 2.x:

$('#myModal').on('hidden', function() {
    $(this).removeData('modal');
});

Et dans Bootstrap 3 ( https://github.com/twbs/bootstrap/pull/7935#issuecomment-18513516 ):

$(document.body).on('hidden.bs.modal', function () {
    $('#myModal').removeData('bs.modal')
});

//Edit SL: more universal
$(document).on('hidden.bs.modal', function (e) {
    $(e.target).removeData('bs.modal');
});
Steffen Wenzel
la source
parfait. travaillé sans aucun problème. dans bootstrap 3. J'ai utilisé $ ('. modal'). on ('hidden.bs.modal', function () {$ (this) .removeData ('bs.modal');});
Jeudi
4
Pas parfait: il montre brièvement l'ancien contenu avant le nouveau contenu.
Laurent
3
@Laurent, vous pouvez effacer le contenu précédent en ajoutant .html (''). Donc, pour 2.x: $ (this) .removeData ('modal'). Find ('. Modal-body'). Html (''). Pour 3: $ (this) .removeData ('bs.modal'). Html ('') 2.x charge le contenu dans le .modal-body, tandis que 3 charge le contenu directement dans le conteneur
.modal
petite correction sur le dernier commentaire, dans bootstrap v3 devrait être: $ (e.target) .removeData ('bs.modal'). html (''); C'est la solution la plus élégante à ce jour (mais elle retarde un peu).
Cesc
J'ai utilisé l'édition / la version publiée par @Softlion dans cette solution proposée - cela a fonctionné et je n'ai rencontré aucun problème de vitesse / retard.
user1801810
21

Vous pouvez forcer Modal à actualiser la popup en ajoutant cette ligne à la fin de la méthode hide du plugin Modal (si vous utilisez bootstrap-transition.js v2.1.1, cela devrait être à la ligne 836)

this.$element.removeData()

Ou avec un auditeur d'événement

$('#modal').on('hidden', function() {
    $(this).data('modal').$element.removeData();
})
Sergio
la source
4
-1 L'idée de mettre ce premier extrait de code directement dans le plugin Modal est une idée terrible. Si vous deviez pirater le plugin (ce que j'éviterais), la chose la plus raisonnable à faire serait soit de déplacer l' load()appel hors du constructeur et dans le show(), soit d'ajouter une méthode au plugin pour déclencher manuellement un rechargement de remote. Sur la deuxième suggestion, je n'ai fourni cela que comme réponse à une question qui demandait explicitement de ne pas le faire de la manière suggérée par @markz .
merv
2
J'aime l'approche de l'auditeur. Je pense qu'il peut même être amélioré en utilisant «.modal» au lieu de «#modal» afin d'éviter de coder en dur l'identifiant. À mon avis, c'est une approche plus propre que celle de markz, car vous continuez à utiliser le basculement de données comme dans le modal bootstrap d'origine.
Toni Grimalt
Je me demande pourquoi cette réponse n'a pas reçu beaucoup de votes positifs. Cette réponse semble être la première à suggérer un écouteur d'événements assez intéressant et rapide à mettre en œuvre.
Anupam
15

Avec Bootstrap 3, vous pouvez utiliser le gestionnaire d'événements 'hidden.bs.modal' pour supprimer toutes les données liées au modal, forçant la fenêtre contextuelle à se recharger la prochaine fois:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
Art
la source
1
Oui, mais il y a encore un décalage crucial dans cette solution; il affiche toujours l'ancien contenu pendant une ou trois secondes avant le nouveau.
vacances doc
au lieu de #modal try body
wobsoriano
8

Basé sur d'autres réponses (merci à tous).

J'avais besoin d'ajuster le code pour qu'il fonctionne, car le simple fait d'appeler .html effaçait tout le contenu et le modal ne se chargerait d'aucun contenu après l'avoir fait. J'ai donc simplement cherché la zone de contenu du modal et y ai appliqué la réinitialisation du HTML.

    $(document).on('hidden.bs.modal', function (e) {
        var target = $(e.target);
        target.removeData('bs.modal')
              .find(".modal-content").html('');
    });

Peut-être encore aller avec la réponse acceptée car je reçois un saut laid juste avant les charges modales car le contrôle est avec Bootstrap.

Modika
la source
5

Un peu plus compressé que l'exemple accepté ci-dessus. Attrape la cible de la cible de données de l'actuel cliqué sur n'importe quoi avec data-toggle = modal activé. Ainsi, vous n'avez pas besoin de savoir quel est l'identifiant du modal cible, réutilisez simplement le même! moins de code = gagner! Vous pouvez également le modifier pour charger le titre, les étiquettes et les boutons de votre modal si vous le souhaitez.

 $("[data-toggle=modal]").click(function(ev) {
    ev.preventDefault();
    // load the url and show modal on success
    $( $(this).attr('data-target') + " .modal-body").load($(this).attr("href"), function() { 
         $($(this).attr('data-target')).modal("show"); 
    });
});

Exemples de liens:

<a data-toggle="modal" href="/page/api?package=herp" data-target="#modal">click me</a>
<a data-toggle="modal" href="/page/api?package=derp" data-target="#modal">click me2</a>
<a data-toggle="modal" href="/page/api?package=merp" data-target="#modal">click me3</a>
Geilt
la source
3

J'ai apporté une petite modification à la réponse Softlion , donc tous mes modaux ne s'actualiseront pas. Les modaux avec l'attribut data-refresh = 'true' sont uniquement actualisés, les autres fonctionnent comme d'habitude. Voici la version modifiée.

$(document).on('hidden.bs.modal', function (e) {
    if ($(e.target).attr('data-refresh') == 'true') {
        // Remove modal data
        $(e.target).removeData('bs.modal');
        // Empty the HTML of modal
        $(e.target).html('');
    }
});

Maintenant, utilisez l'attribut comme indiqué ci-dessous,

<div class="modal fade" data-refresh="true" id="#modal" tabindex="-1" role="dialog" aria-labelledby="#modal-label" aria-hidden="true"></div>

Cela garantira que seuls les modaux avec data-refresh = 'true' sont actualisés. Et je réinitialise également le html modal parce que les anciennes valeurs sont affichées jusqu'à ce que de nouvelles soient chargées, ce qui rend le html vide corrige celui-là.

Shiva Avula
la source
2

Voici une version coffeescript qui a fonctionné pour moi.

$(document).on 'hidden.bs.modal', (e) ->
  target = $(e.target)
  target.removeData('bs.modal').find(".modal-content").html('')
rgagnon
la source
il a résolu un problème où le contenu se recharge mais js à l'intérieur du modal ne s'exécute pas une deuxième fois
Souhaieb
1

Cela fonctionnera pour toutes les versions de twitterbootstrap

Code Javascript:

<script type="text/javascript">
/* <![CDATA[ */
(function(){
   var bsModal = null;
   $("[data-toggle=modal]").click(function(e) {
      e.preventDefault();
      var trgId = $(this).attr('data-target'); 
      if ( bsModal == null ) 
       bsModal = $(trgId).modal;
      $.fn.bsModal = bsModal;
      $(trgId + " .modal-body").load($(this).attr("href"));
      $(trgId).bsModal('show');
    });
 })();
/* <![CDATA[ */
</script>

les liens vers modal sont

<a data-toggle="modal" data-target="#myModal" href="edit1.aspx">Open modal 1</a>
<a data-toggle="modal" data-target="#myModal" href="edit2.aspx">Open modal 2</a>
<a data-toggle="modal" data-target="#myModal" href="edit3.aspx">Open modal 3</a>

pop up modal

<div id="myModal" class="modal hide fade in">
<div class="modal-header">
    <a class="close" data-dismiss="modal">×</a>
    <h3>Header</h3>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
    <input type="submit" class="btn btn-success" value="Save"/>
</div>

Bijaya Kumar
la source
1

J'étais aussi coincé sur ce problème puis j'ai vu que les identifiants du modal sont les mêmes. Vous avez besoin de différents identifiants de modaux si vous voulez plusieurs modaux. J'ai utilisé un identifiant dynamique . Voici mon code en haml:

.modal.hide.fade{"id"=> discount.id,"aria-hidden" => "true", "aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1"}

tu peux le faire

<div id="<%= some.id %>" class="modal hide fade in">
  <div class="modal-header">
    <a class="close" data-dismiss="modal">×</a>
    <h3>Header</h3>
  </div>
  <div class="modal-body"></div>
  <div class="modal-footer">
    <input type="submit" class="btn btn-success" value="Save" />
  </div>
</div>

et vos liens vers modal seront

<a data-toggle="modal" data-target="#" href='"#"+<%= some.id %>' >Open modal</a>
<a data-toggle="modal" data-target="#myModal" href='"#"+<%= some.id %>' >Open modal</a>
<a data-toggle="modal" data-target="#myModal" href='"#"+<%= some.id %>' >Open modal</a>

J'espère que cela fonctionnera pour vous.

Asnad Atta
la source
1

Vous pouvez essayer ceci:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
bharat
la source
0

Je voulais que le contenu chargé AJAX soit supprimé lors de la fermeture du modal, j'ai donc ajusté la ligne suggérée par d'autres (syntaxe coffeescript):

$('#my-modal').on 'hidden.bs.modal', (event) ->
  $(this).removeData('bs.modal').children().remove()
murs vides
la source
0

var $ table = $ ('# maTable2');
$ table.bootstrapTable ('détruire');

A travaillé pour moi

Ashwin Golani
la source
0

étape 1: créer un wrapper pour le modal appelé clone-modal-wrapper .

étape 2: Créez un div vide appelé modal-wrapper.

Étape 3: Copiez l'élément modal de clone-modal-wrappervers modal-wrapper.

Étape 4: Basculez le modal de modal-wrapper.

<a data-toggle="modal" class='my-modal'>Open modal</a>

<div class="clone-modal-wrapper">
   <div class='my-modal' class="modal fade">
      <div class="modal-dialog">
         <div class="modal-content">
            <div class="modal-header">
               <a class="close" data-dismiss="modal">×</a>
               <h3>Header</h3>
            </div>
            <div class="modal-body"></div>
            <div class="modal-footer">
               <input type="submit" class="btn btn-success" value="Save"/>
            </div>
         </div>
      </div>
   </div>
</div>

<div class="modal-wrapper"></div>


$("a[data-target=#myModal]").click(function (e) {
    e.preventDefault();
    $(".modal-wrapper").html($(".clone-modal-wrapper").html());
    $('.modal-wrapper').find('.my-modal').modal('toggle');
});
Soubhagya Kumar Barik
la source