Laden Sie Inhalte in Modal neu (Twitter Bootstrap)

98

Ich verwende das modale Popup von 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>

Ich kann Inhalte mit Ajax mit diesem a-Element laden:

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

Jetzt muss ich das gleiche Modal öffnen, aber eine andere URL verwenden. Ich verwende dieses Modal, um eine Entität aus meiner Datenbank zu bearbeiten. Wenn ich also auf eine Entität auf Bearbeiten klicke, muss ich das Modal mit einer ID laden.

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

Wenn ich auf Link Nummer 1 klicke, funktioniert es gut. Wenn ich dann aber auf Link Nummer 2 klicke, ist der modale Inhalt bereits geladen und zeigt daher den Inhalt von Link Nummer 1 an.

Wie kann ich den mit Ajax geladenen Inhalt in einem modalen Twitter-Bootstrap-Popup aktualisieren oder zurücksetzen?

stian.net
quelle
Hatte das gleiche Problem und war an die gleiche Lösung gewöhnt. Ich greife aus irgendeinem seltsamen Grund von jquery auf die Funktion .attr () zurück. Die Funktion .data () funktionierte nicht.
user1803784

Antworten:

98

Ich habe das gleiche Problem, und ich denke, der Weg, dies zu tun, besteht darin, das Datenumschaltattribut zu entfernen und einen benutzerdefinierten Handler für die Links zu haben.

Etwas in den Zeilen von:

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

Werde es später versuchen und Kommentare posten.

markz
quelle
16
$ ('. modal'). on ('hidden', function () {$ (this) .removeData ();}) Dies ist meine Modifikation der folgenden Lösung ... sauberer, da Sie den Klick und das Laden nicht abfangen müssen es selbst funktioniert so programmatische Modellshow noch
Carter Cole
1
Ich verwende Bootstrap 3, der Inhalt im Modal wird jedes Mal aktualisiert, aber es werden zwei modale Fenster erstellt. Bekommt das noch jemand?
Herr B
1
Hey Sid, du erstellst 2 Divs mit der Klasse "Modal-Body", eigentlich erstellst du es bereits und das Modal erstellt wieder. Entfernen Sie aus diesem Code den '.modal-body' und er sollte einwandfrei funktionieren.
Palantir
1
Funktioniert für mich mit Bootstrap 3, sehr frustrierend, dass dies von der Bootstrap-Kernbibliothek standardmäßig nicht unterstützt wird.
Josh Diehl
@markz, ich benutze auch so etwas und ev.preventDefault (); Wenn ich ein modales Fenster erhalte, werden alle Dropdown-Listen meiner Seite zurückgesetzt. Irgendeine Idee, wie man das verhindert?
Jaikrat
72

Um die Daten zu entladen, wenn das Modal geschlossen ist, können Sie dies mit Bootstrap 2.x verwenden:

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

Und in 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
quelle
perfekt. funktionierte ohne probleme. in Bootstrap 3. Ich habe $ ('. modal'). on ('hidden.bs.modal', function () {$ (this) .removeData ('bs.modal');}) verwendet;
Thupten
4
Nein perfekt: Es zeigt kurz den alten Inhalt vor dem neuen Inhalt.
Laurent
3
@Laurent, Sie können den vorherigen Inhalt löschen, indem Sie .html ('') hinzufügen. Also, für 2.x: $ (this) .removeData ('modal'). Find ('. Modal-body'). Html (''). Für 3: $ (this) .removeData ('bs.modal'). Html ('') 2.x lädt Inhalte in den .modal-Body, während 3 Inhalte direkt in den .modal-Container
lädt
kleine Korrektur am letzten Kommentar in Bootstrap v3 sollte sein: $ (e.target) .removeData ('bs.modal'). html (''); Dies ist die bisher eleganteste Lösung (sie verzögert sich jedoch ein wenig).
Cesc
Ich habe die Bearbeitung / Version verwendet, die @Softlion in dieser vorgeschlagenen Lösung veröffentlicht hat - sie hat funktioniert und es sind keine Geschwindigkeits- / Verzögerungsprobleme aufgetreten.
user1801810
21

Sie können Modal zwingen, das Popup zu aktualisieren, indem Sie diese Zeile am Ende der Hide-Methode des Modal-Plugins hinzufügen (Wenn Sie bootstrap-Transition.js v2.1.1 verwenden, sollte es sich in Zeile 836 befinden).

this.$element.removeData()

Oder mit einem Event-Listener

$('#modal').on('hidden', function() {
    $(this).data('modal').$element.removeData();
})
Sergio
quelle
4
-1 Die Idee, dieses erste Snippet direkt in das Modal-Plugin zu integrieren, ist eine schreckliche Idee. Wenn Sie das Plugin hacken würden (was ich vermeiden würde), wäre es vernünftiger, entweder den load()Aufruf aus dem Konstruktor in das zu verschieben show()oder dem Plugin eine Methode hinzuzufügen, um ein erneutes Laden von manuell auszulösen remote. Beim zweiten Vorschlag habe ich dies nur als Antwort auf eine Frage angegeben, bei der ausdrücklich darum gebeten wurde, dies nicht so zu tun, wie es @markz vorgeschlagen hat .
Merv
2
Ich mag den Hörer-Ansatz. Ich denke, es kann sogar mit '.modal' anstelle von '#modal' verbessert werden, um ein Hardcodieren der ID zu vermeiden. Meiner Meinung nach ist es ein sauberer Ansatz als der von Markz, da Sie den Datenumschalter weiterhin wie im ursprünglichen Bootstrap-Modal verwenden.
Toni Grimalt
Ich frage mich, warum diese Antwort nicht viele positive Stimmen hat. Diese Antwort scheint die erste zu sein, die einen Ereignis-Listener vorschlägt, der sehr interessant und schnell zu implementieren ist.
Anupam
15

Mit Bootstrap 3 können Sie den Ereignishandler 'hidden.bs.modal' verwenden, um alle modalbezogenen Daten zu löschen und das Popup beim nächsten Mal neu zu laden:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
Kunst
quelle
1
Ja, aber diese Lösung weist immer noch eine entscheidende Verzögerung auf. Es zeigt noch alte Inhalte für eine oder drei Sekunden vor dem neuen.
Doc Urlaub
statt #modal versuchen Körper
Wobsoriano
8

Basierend auf anderen Antworten (danke an alle).

Ich musste den Code anpassen, um zu funktionieren, da durch einfaches Aufrufen von .html der gesamte Inhalt gelöscht wurde und das Modal nach dem Ausführen mit keinem Inhalt geladen wurde. Also habe ich einfach nach dem Inhaltsbereich des Modals gesucht und dort das Zurücksetzen des HTML angewendet.

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

Kann immer noch mit der akzeptierten Antwort gehen, da ich kurz vor dem Laden des Modals einen hässlichen Sprung bekomme, da die Steuerung mit Bootstrap erfolgt.

Modika
quelle
5

Etwas komprimierter als das oben akzeptierte Beispiel. Greift das Ziel vom Datenziel des aktuell angeklickten Objekts mit Datenumschaltung = modal an. Dadurch müssen Sie nicht wissen, wie die ID des Zielmodals lautet. Verwenden Sie einfach dieselbe ID! weniger Code = gewinnen! Sie können dies auch ändern, um Titel, Beschriftungen und Schaltflächen für Ihr Modal zu laden, falls Sie möchten.

 $("[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"); 
    });
});

Beispiel-Links:

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

Ich habe eine kleine Änderung an der Softlion- Antwort vorgenommen, damit alle meine Modalitäten beim Verstecken nicht aktualisiert werden. Die Modalitäten mit dem Attribut data-refresh = 'true' werden nur aktualisiert, andere funktionieren wie gewohnt. Hier ist die modifizierte Version.

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

Verwenden Sie nun das unten gezeigte Attribut.

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

Dadurch wird sichergestellt, dass nur die Modalitäten mit data-refresh = 'true' aktualisiert werden. Und ich setze auch das modale HTML zurück, weil die alten Werte angezeigt werden, bis neue geladen werden, wodurch HTML leer wird und dieses Problem behoben wird.

Shiva Avula
quelle
2

Hier ist eine Coffeescript-Version, die für mich funktioniert hat.

$(document).on 'hidden.bs.modal', (e) ->
  target = $(e.target)
  target.removeData('bs.modal').find(".modal-content").html('')
rgagnon
quelle
Es wurde ein Problem behoben, bei dem der Inhalt neu geladen wurde, js inside modal jedoch kein zweites Mal ausgeführt wurde
Souhaieb,
1

Es funktioniert für alle Versionen von Twitterbootstrap

Javascript-Code:

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

Links zu Modal sind

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

Popup 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
quelle
1

Ich war auch bei diesem Problem festgefahren, als ich sah, dass die IDs des Modals gleich sind. Sie benötigen unterschiedliche Modal- IDs, wenn Sie mehrere Modalitäten möchten. Ich habe eine dynamische ID verwendet . Hier ist mein Code in haml:

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

du kannst das

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

und deine Links zu Modal werden sein

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

Ich hoffe das wird für dich funktionieren.

Asnad Atta
quelle
1

Sie können dies versuchen:

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

Ich wollte, dass der von AJAX geladene Inhalt entfernt wird, wenn das Modal geschlossen wird, also habe ich die von anderen vorgeschlagene Zeile angepasst (Coffeescript-Syntax):

$('#my-modal').on 'hidden.bs.modal', (event) ->
  $(this).removeData('bs.modal').children().remove()
leere Wände
quelle
0

var $ table = $ ('# myTable2');
$ table.bootstrapTable ('destroy');

Hat für mich gearbeitet

Ashwin Golani
quelle
0

Schritt 1: Erstellen Sie einen Wrapper für das aufgerufene Modal clone-modal-wrapper .

Schritt 2: Erstellen Sie ein leeres Div mit dem Namen modal-wrapper .

Schritt 3: Kopieren Sie das modale Element von clone-modal-wrappernach modal-wrapper .

Schritt 4: Schalten Sie das Modal von um 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
quelle