Twitter Bootstrap Remote Modal zeigt jedes Mal den gleichen Inhalt

263

Ich benutze Twitter Bootstrap, ich habe ein Modal angegeben

<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>

Und die Links

<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>

Wenn ich zum ersten Mal auf einen dieser Links klicke, wird der richtige Inhalt angezeigt. Wenn ich jedoch auf andere Links klicke, wird derselbe Inhalt angezeigt, der zum ersten Mal geladen wurde. Der Inhalt wird nicht aktualisiert.

Ich möchte, dass es jedes Mal aktualisiert wird, wenn es angeklickt wird.

PS: Ich kann es einfach über die benutzerdefinierte jQuery-Funktion zum Laufen bringen, aber ich möchte wissen, ob es mit der nativen modalen Bootstrap-Remote-Funktion möglich ist, da es einfach genug sein sollte und ich denke, ich mache die Dinge nur komplizierter.

Dhruv Kumar Jha
quelle
Gleiches Update, jedoch geändert für Bootstrap 3. Bootstrap 3 führt Namespaces ein. plnkr.co/edit/HWSgSw?p=preview
Jeff H
5
Beachten Sie, dass remoteModals ab Bootstrap v3.2.1 veraltet sind und in v4 nicht mehr verfügbar sind .
Cvrebert

Antworten:

447

Das Problem ist zweifach.

Zuerst einmal ein Modal Objekt instanziiert wird, wird es dauerhaft an das Element angebracht , indem angegeben data-targetund nachfolgende Anrufe zu zeigen , dass modale nur nennen toggle()drauf, aber nicht die Werte in der Aktualisierung options. Obwohl die hrefAttribute in Ihren verschiedenen Links unterschiedlich sind, wird der Wert für beim Umschalten des Modals remotenicht aktualisiert. Bei den meisten Optionen kann dies umgangen werden, indem das Objekt direkt bearbeitet wird. Zum Beispiel:

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

In diesem Fall funktioniert das jedoch nicht, weil ...

Zweite ist das Modal-Plugin so konzipiert, dass die Remote-Ressource in den Konstruktor des Modal-Objekts geladen wird . Dies bedeutet leider, dass selbst wenn eine Änderung am vorgenommen wird options.remote, diese niemals neu geladen wird .

Eine einfache Abhilfe besteht darin, das Modal-Objekt vor dem anschließenden Umschalten zu zerstören. Eine Möglichkeit besteht darin, es einfach zu zerstören, nachdem es sich versteckt hat:

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

Hinweis: Passen Sie die Auswahl nach Bedarf an. Dies ist die allgemeinste.

Plunker

Oder Sie könnten versuchen, ein komplizierteres Schema zu entwickeln, um beispielsweise zu überprüfen, ob sich der Link, der das Modal startet, von dem vorherigen unterscheidet. Wenn ja, zerstöre; Wenn dies nicht der Fall ist, muss es nicht neu geladen werden.

merv
quelle
1
@VladimirStarkov Entschuldigung - anscheinend habe ich die hideKlasse auf dem Modal vergessen. Wenn Ihr Fenster also zu klein war, hat das Modal möglicherweise Mausereignisse auf den Schaltflächen blockiert. Aus irgendeinem Grund ist JSFiddle.net heute Morgen wirklich schlecht (ein 504 hat versucht zu aktualisieren), deshalb habe ich das Beispiel auf plnkr.co überarbeitet, was für AJAX sowieso besser ist.
Merv
3
Es gibt noch ein weiteres Problem: Der .modal-body enthält weiterhin den Text, daher habe ich hinzugefügt: <CODE> $ ('# myModal .modal-body'). text ("Loading ...") </ CODE> im versteckten Ereignis Listener
rbp
5
bs.modalin $(this).removeData('bs.modal')arbeitete für mich mit Bootstrap 3
jvannistelrooy
2
Vollständiger Arbeitscode für Boostrap 3 ist$('body').on('hidden.bs.modal', '.modal', function () { $(this).removeData('bs.modal'); });
Christophe Fondacci
1
Ich würde auch prüfen, ob das versteckte Modal von der Remote-Quelle geladen wird, um Modalitäten mit statischem Inhalt nicht zu beschädigen:var modalData = $(this).data('bs.modal'); if (modalData && modalData.options.remote)...
Wojtek Kruszewski
171

Für Bootstrap 3 sollten Sie Folgendes verwenden:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});
Camilo Nova
quelle
17
Mein Held. Lieben Sie diese undokumentierten Änderungen.
Jorin
2
Das hat sehr geholfen. Bootstrap 3 ist nicht abwärtskompatibel und der größte Teil des Inhalts in SO (oder anderen Foren) handelt von BS <3. Das Ausprobieren dieser Lösungen verschwendet in der Tat viel Zeit.
Swapnil
7
Nein perfekt: Es zeigt kurz den alten Inhalt vor dem neuen Inhalt.
Laurent
3
Wenn Sie das Modal anhand des obigen Beispiels leeren möchten, sollten Sie vor oder nach der remoteDataZeile Folgendes hinzufügen können :$(this).empty()
jgillman
11
Sie sollten nicht verwenden $(this).empty(). Die remoteOption lädt die entfernten Daten in das verschachtelte <div class="modal-content">Element. Verwenden Sie $('.modal-content', this).empty();stattdessen.
Gavin
50

Für Bootstrap 3.1 möchten Sie Daten entfernen und modal-contentnicht den gesamten Dialog (3.0) leeren , um das Flackern zu vermeiden, während Sie auf das Laden von Remote-Inhalten warten.

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

Wenn Sie nicht entfernte Modalitäten verwenden, entfernt der obige Code natürlich deren Inhalt, sobald er geschlossen ist (fehlerhaft). Möglicherweise müssen Sie diesen Modalen (wie einer .local-modalKlasse) etwas hinzufügen, damit sie nicht betroffen sind. Ändern Sie dann den obigen Code in:

$(document).on("hidden.bs.modal", ".modal:not(.local-modal)", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});
Slopapa
quelle
Stellen Sie auf den Remote-Seiten sicher, dass Sie keine Bootstrap- oder JQuery-Bibliotheken laden. Es wird jede Referenz töten und Sie mit einem leeren Modal leer lassen.
Bankzilla
Das hat bei mir nicht funktioniert. Hier ist mein Code, der funktioniert: $ (document) .on ("hidden.bs.modal", ".modal", Funktion (e) {if (! $ (E.target) .is (". Local-modal") ")) {$ (e.target) .removeData (" bs.modal "). find (". modal-content "). empty ();}});
Kevin
Wenn ich es benutze, ist $(e.target).removeData("bs.modal").find(".modal-content").empty();es so, als würde mein Modal irgendwie ausgeblendet und nur das graue Overlay erscheint.
Axel
30

Danke merv. Ich habe angefangen, an boostrap.js herumzubasteln, aber Ihre Antwort ist eine schnelle und saubere Problemumgehung. Folgendes habe ich letztendlich in meinem Code verwendet.

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

Die akzeptierte Antwort hat bei mir nicht funktioniert, deshalb habe ich mich für JavaScript entschieden.

<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")})
    })
})
James Ward
quelle
14

Dies funktioniert mit Bootstrap 3 FYI

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

Mein Projekt ist in Yii erstellt und verwendet das Bootstrap-Yii-Plugin. Diese Antwort ist daher nur relevant, wenn Sie Yii verwenden.

Das obige Update hat funktioniert, aber erst nach dem ersten Mal wurde das Modal angezeigt. Das erste Mal war es leer. Ich denke, das liegt daran, dass Yii nach der Initiierung des Codes die Hide-Funktion des Modals aufruft und dadurch meine Initiierungsvariablen löscht.

Ich fand, dass das Setzen des removeData-Aufrufs unmittelbar vor dem Code, der das Modal startete, den Trick machte. Mein Code ist also so aufgebaut ...

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

In Bootstrap 3.2.0 muss sich das Ereignis "Ein" im Dokument befinden und Sie müssen das Modal leeren:

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

In Bootstrap 3.1.0 kann sich das Ereignis "on" auf dem Body befinden:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});
Romain
quelle
Die 3.2-Lösung war das einzige, was in Bootstrap 3.1 für mich richtig funktioniert hat - unter Verwendung des Body-Ansatzes wurden einige meiner Ereignisse auf Modal ausgehängt.
StuartQ
3

Warum nicht mit BS 3 allgemeiner machen? Verwenden Sie einfach "[etwas] Modal" als ID des modalen DIV.

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

Die einzige Arbeitsoption für mich ist:

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

Ich benutze Bootstrap 3 und habe eine Funktion namens, popup('popup content') die die modale Box HTML anhängt.

Orkun Tuzel
quelle
2
Dies ist das einzige, was bei mir mit BS 3.3.6 funktioniert hat. auch mit Lenker Vorlage. Ich schlage jedoch vor, ein Dokument anstelle eines Körpers zu verwenden.
Dbinott
1

Hinzufügen eines $ (this) .html (''); um auch sichtbare Daten zu löschen, und es funktioniert ziemlich gut

webstr
quelle
1

Wenn eine Remote-URL angegeben wird, wird der Inhalt einmalig über die Lademethode von jQuery geladen und in die .modal-content div eingefügt. Wenn Sie die Daten-API verwenden, können Sie alternativ das href-Attribut verwenden, um die Remote-Quelle anzugeben. Ein Beispiel hierfür ist unten dargestellt

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});
Ciprian Mihalache
quelle
1

Ich habe so etwas hinzugefügt, weil der ältere Inhalt angezeigt wird, bis der neue angezeigt wird. Mit .html ('') im .modal-Inhalt wird der HTML-Code gelöscht. Ich hoffe, es hilft

$('#myModal').on('hidden.bs.modal', function () {
   $('#myModal').removeData('bs.modal');
   $('#myModal').find('.modal-content').html('');
});
Mau GM
quelle
Dies ist bei weitem die einfachste funktionierende Antwort, die ich gefunden habe. Nichts kompliziertes an der Antwort, wenige Codezeilen und einfach zu interpretieren. Hat beim ersten Mal perfekt funktioniert.
Tarquin
0

Ich habe ein einfaches Snippet geschrieben, das die Aktualisierung des Modals behandelt. Grundsätzlich speichert es den angeklickten Link in den Daten des Modals und prüft, ob es sich um denselben Link handelt, auf den geklickt wurde, wobei die Modaldaten entfernt werden oder nicht.

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');
    });
};
DevAntoine
quelle
0

Für Bootstrap 3 habe ich in modal.js Folgendes geändert:

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

zu

$(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')
  })

(zusätzlicher Abstand zur Klarheit hinzugefügt)

Dies verhindert ein unerwünschtes Flashen alter modaler Inhalte, indem leer () für den modalen Container aufgerufen und die Daten entfernt werden.

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

Dieser arbeitet für mich.

Shawn Ang
quelle
0

Dieser andere Ansatz funktioniert gut für mich:

$("#myModal").on("show.bs.modal", function(e) {
    var link = $(e.relatedTarget);
    $(this).find(".modal-body").load(link.attr("href"));
});
Rhys Stephens
quelle
0
$('body').on('hidden.bs.modal', '.modal', function () {
       $("#mention Id here what you showed inside modal body").empty()
});

Welches HTML-Element möchten Sie wie leeren (div, span was auch immer).

Atul
quelle
0

Dieser funktioniert für mich:

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>

Skript

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

Links-Bereich ist Bereich, in dem ich die Daten platziere und löschen muss

Dewaz
quelle
0

Erweiterte Version der akzeptierten Antwort von @merv. Außerdem wird überprüft, ob ausgeblendete Modaldaten von einer Remote-Quelle geladen wurden, und alte Inhalte werden gelöscht, um ein Flashen zu verhindern.

$(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

Wojtek Kruszewski
quelle
-1

Getestet auf Bootstrap Version 3.3.2

  $('#myModal').on('hide.bs.modal', function() {
    $(this).removeData();
  });
Abudayah
quelle
1
Dies ist eine schreckliche Lösung. Der Aufruf .removeData()ohne Parameter wird zeigen , jquery , um alle Daten zu entfernen , um dieses Element befestigt ist . Was das Problem des OP betrifft, .removeData('bs.modal')oder .removeData('modal')würde ausreichen und ist sehr sicher.
Julian Paolo Dayag
-4

Viel Glück mit diesem:

$('#myModal').on('hidden.bs.modal', function () {
    location.reload();
});
Mappy
quelle
2
das ist nutzlos. Das Neuladen der Seite ist nicht die Lösung.
Dbinott