web-dev-qa-db-fra.com

Twitter bootstrap modal distant montre le même contenu à chaque fois

J'utilise Twitter bootstrap, j'ai spécifié un modal

<div class="modal hide" id="modal-item">

    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">x</button>
        <h3>Update Item</h3>
    </div>

    <form action="http://www.website.com/update" method="POST" class="form-horizontal">

    <div class="modal-body">
        Loading content...
    </div>

    <div class="modal-footer">
        <a href="#" class="btn" data-dismiss="modal">Close</a>
        <button class="btn btn-primary" type="submit">Update Item</button>
    </div>

    </form>

</div>

Et les liens

<a href="http://www.website.com/item/1" data-target="#modal-item" data-toggle="modal">Edit 1</a>
<a href="http://www.website.com/item/2" data-target="#modal-item" data-toggle="modal">Edit 2</a>
<a href="http://www.website.com/item/3" data-target="#modal-item" data-toggle="modal">Edit 2</a>

Lorsque je clique sur l'un de ces liens pour la première fois, je vois le contenu correct, mais lorsque je clique sur d'autres liens, il affiche le même contenu chargé pour la première fois, il ne met pas à jour le contenu.

Je veux qu'il soit mis à jour chaque fois que l'on clique dessus.

P.S: Je peux facilement le faire fonctionner avec la fonction jQuery personnalisée, mais je veux savoir s’il est possible avec la fonction native modale Bootstrap, car elle devrait être assez simple et je suppose que je ne fais que compliquer les choses.

261
Dhruv Kumar Jha

Le problème est double.

D'abord , une fois qu'un objet Modal est instancié, il est attaché de façon permanente à l'élément spécifié par data-target et aux appels suivants pour montrer que modal ne fera que Appelle toggle() dessus, mais ne mettra pas à jour les valeurs dans le options. Ainsi, même si les attributs href diffèrent sur vos différents liens, lorsque vous modifiez le modal, la valeur de remote n'est pas mise à jour. Pour la plupart des options, on peut contourner ce problème en modifiant directement l'objet. Par exemple:

$('#myModal').data('bs.modal').options.remote = "http://website.com/item/7";

Cependant, cela ne fonctionnera pas dans ce cas, parce que ...

Deuxièmement , le plug-in Modal est conçu pour charger la ressource distante dans le constructeur de l'objet Modal, ce qui signifie malheureusement que même si une modification est apportée au options.remote, , il ne sera jamais rechargé .

Un remède simple consiste à détruire l'objet Modal avant de basculer par la suite. Une option consiste à simplement le détruire après qu'il ait fini de se cacher:

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

Remarque: Ajustez les sélecteurs selon vos besoins. C'est le plus général.

Plunker

Vous pouvez également essayer de concevoir un schéma plus compliqué consistant à vérifier, par exemple, si le lien qui lance le modal est différent du précédent. Si c'est le cas, détruisez; sinon, pas besoin de recharger.

447
merv

Pour bootstrap 3, vous devez utiliser:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});
171
Camilo Nova

Pour Bootstrap 3.1, vous souhaiterez supprimer les données et vider le modal-content plutôt que toute la boîte de dialogue (3.0) afin d'éviter le scintillement lors de l'attente du chargement du contenu distant.

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

Si vous utilisez des modaux non distants, le code ci-dessus supprimera évidemment leur contenu une fois qu'ils sont fermés (mauvais). Vous devrez peut-être ajouter quelque chose à ces modaux (comme une classe .local-modal) pour qu'ils ne soient pas affectés. Puis modifiez le code ci-dessus pour:

$(document).on("hidden.bs.modal", ".modal:not(.local-modal)", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});
50
slopapa

Merci merv. J'ai commencé à bricoler bootstrap.js mais votre réponse est une solution de contournement rapide et propre. Voici ce que j'ai fini par utiliser dans mon code.

$('#modal-item').on('hidden', function() {
    $(this).removeData('modal');
});
30
Bienvenido David

La réponse acceptée ne fonctionnait pas pour moi, alors je suis allé avec JavaScript pour le faire.

<a href="/foo" class="modal-link">
<a href="/bar" class="modal-link">

<script>
$(function() {
    $(".modal-link").click(function(event) {
        event.preventDefault()
        $('#myModal').removeData("modal")
        $('#myModal').modal({remote: $(this).attr("href")})
    })
})
21
James Ward

Cela fonctionne avec Bootstrap 3 FYI

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

Mon projet est construit en Yii et utilise le plug-in Bootstrap-Yii. Cette réponse n'est donc pertinente que si vous utilisez Yii.

Le correctif ci-dessus a fonctionné, mais seulement après la première présentation du modal. La première fois, il est venu vide. Je pense que c'est parce qu'après mon initiation du code, Yii appelle la fonction de masquage du modal, effaçant ainsi mes variables d'initiation.

J'ai constaté que le fait de placer l'appel removeData immédiatement avant le code qui a lancé le modal a fonctionné. Donc, mon code est structuré comme ça ...

$ ("#myModal").removeData ('modal');
$ ('#myModal').modal ({remote : 'path_to_remote'});
7
Sean Toru

Dans Bootstrap 3.2.0, l'événement "on" doit figurer sur le document et vous devez vider le modal:

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

Dans Bootstrap 3.1.0, l'événement "on" peut figurer sur le corps:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});
5
Romain

Pourquoi ne pas le rendre plus général avec BS 3? Utilisez simplement "[quelque chose] modal" comme identifiant du DIV modal.

$("div[id$='modal']").on('hidden.bs.modal',
    function () {
        $(this).removeData('bs.modal');
    }
);
3
user2763645

La seule option qui fonctionne pour moi est:

$('body').on('hidden.bs.modal', '#modalBox', function () {
    $(this).remove();
});

J'utilise Bootstrap 3 et j'ai une fonction appelée popup('popup content') qui ajoute la boîte modale html.

2
Orkun Tuzel

Ajouter un $ (this) .html (''); pour effacer les données visibles aussi, et cela fonctionne très bien

1
webstr

J'ai ajouté quelque chose comme ceci, parce que l'ancien contenu est affiché jusqu'à ce que le nouveau apparaisse.

$('#myModal').on('hidden.bs.modal', function () {
   $('#myModal').removeData('bs.modal');
   $('#myModal').find('.modal-content').html('');
});
1
Mau GM

Si une URL distante est fournie, le contenu sera chargé une fois via la méthode load de jQuery et injecté dans la div .modal-content. Si vous utilisez data-api, vous pouvez également utiliser l'attribut href pour spécifier la source distante. Un exemple de ceci est montré ci-dessous

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});
1
Ciprian Mihalache
        $('#myModal').on('hidden.bs.modal', function () {
            $(this).removeData('modal');
        });

Celui-ci fonctionne pour moi.

0
Shawn Ang

Cette autre approche fonctionne bien pour moi:

$("#myModal").on("show.bs.modal", function(e) {
    var link = $(e.relatedTarget);
    $(this).find(".modal-body").load(link.attr("href"));
});
0
Rhys Stephens

Pour Bootstrap 3, dans modal.js j'ai changé:

$(document)
  .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
  .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open'); })

à

$(document)
  .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
  .on('hidden.bs.modal', '.modal', function () { 
    $(this).removeData('bs.modal').empty()
    $(document.body).removeClass('modal-open')
  })

(espacement supplémentaire ajouté pour plus de clarté)

Cela évite toute flambée indésirable d'ancien contenu modal en appelant empty () sur le conteneur modal et en supprimant les données.

0
Stanton

Version développée de la réponse acceptée par @merv. Il vérifie également si le contenu modal masqué est chargé depuis une source distante et efface l'ancien contenu pour l'empêcher de clignoter.

$(document).on('hidden.bs.modal', '.modal', function () {
  var modalData = $(this).data('bs.modal');

  // Destroy modal if has remote source – don't want to destroy modals with static content.
  if (modalData && modalData.options.remote) {
    // Destroy component. Next time new component is created and loads fresh content
    $(this).removeData('bs.modal');
    // Also clear loaded content, otherwise it would flash before new one is loaded.
    $(this).find(".modal-content").empty();
  }
});

https://Gist.github.com/WojtekKruszewski/ae86d7fb59879715ae1e6dd623f743c5

0
Wojtek Kruszewski

Celui-ci fonctionne pour moi:

modal

<div class="modal fade" id="searchKaryawan" tabindex="-1" role="dialog" aria-labelledby="SearchKaryawanLabel" aria-hidden="true"> <div class="modal-dialog">
<div class="modal-content">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <h4 class="modal-title" id="SearchKaryawanLabel">Cari Karyawan</h4>
  </div>
  <div class="modal-body">
    <input type="hidden" name="location">
    <input name="cariNama" type="text" class="form-control" onkeyup="if (this.value.length > 3) cariNikNama();" />
    <div class="links-area" id="links-area"></div>
  </div>
  <div class="modal-footer">
  </div>
</div> </div></div>

scénario

<script type="text/javascript">$('body').on('hidden.bs.modal', '.modal', function () {  $(".links-area").empty() }); </script>

zone de liens est la zone où je mets les données et doivent effacer

0
dewaz
$('body').on('hidden.bs.modal', '.modal', function () {
       $("#mention Id here what you showed inside modal body").empty()
});

Quel élément HTML vous souhaitez vider (div, span que ce soit).

0
Atul

J'ai écrit un simple extrait traitant de l'actualisation du modal. Fondamentalement, il stocke le lien cliqué dans les données du modal et vérifie si c'est le même lien sur lequel vous avez cliqué, en supprimant ou non les données modales.

var handleModal = function()
{
    $('.triggeringLink').click(function(event) {
        var $logsModal = $('#logsModal');
        var $triggeringLink = $logsModal.data('triggeringLink');

        event.preventDefault();

        if ($logsModal.data('modal') != undefined
            && $triggeringLink != undefined
            && !$triggeringLink.is($(this))
        ) {
            $logsModal.removeData('modal');
        }

        $logsModal.data('triggeringLink', $(this));

        $logsModal.modal({ remote: $(this).attr('href') });
        $logsModal.modal('show');
    });
};
0
DevAntoine