Ricarica il contenuto in modalità modale (bootstrap di twitter)


98

Sto usando il popup modale di bootstrap di Twitter.

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

Posso caricare contenuti usando ajax con questo elemento a:

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

Ora devo aprire la stessa modale ma utilizzando un URL diverso. Sto usando questo modale per modificare un'entità dal mio database. Quindi, quando faccio clic su Modifica su un'entità, devo caricare il modale con un ID.

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

Se clicco sul collegamento numero 1, funziona bene. Ma se poi clicco sul link numero 2 il contenuto modale è già caricato e quindi mostrerà il contenuto dal link numero 1.

Come posso aggiornare o ripristinare il contenuto caricato ajax in un popup modale bootstrap di Twitter?


2
possibile duplicato del modale remoto bootstrap
Marijn

Ha avuto lo stesso problema e utilizzato per la stessa soluzione. Ricorro alla funzione .attr () di jquery per qualche strana ragione. La funzione .data () non funzionava.
user1803784

Risposte:


98

Sto riscontrando lo stesso problema e immagino che il modo per farlo sarà rimuovere l'attributo data-toggle e avere un gestore personalizzato per i collegamenti.

Qualcosa nelle linee di:

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

Lo proverò più tardi e pubblicherò commenti.


16
$ ('. modal'). on ('hidden', function () {$ (this) .removeData ();}) questa è la mia modifica della soluzione sotto ... più pulita perché non devi catturare il clic e caricare il tuo modello di spettacolo programmatico funziona ancora
Carter Cole

1
Sto usando Bootstrap 3, il contenuto nel modale viene aggiornato ogni volta ma crea due finestre modali. Qualcun altro lo capisce?
Mr B

1
Ehi Sid, stai creando 2 div con la classe "modal-body", in realtà lo stai già creando, e il modal sta creando di nuovo. Da quel codice, rimuovi ".modal-body" e dovrebbe funzionare correttamente.
Palantir

1
Per me funziona con Bootstrap 3, molto frustrante che questo non sia supportato dalla libreria bootstrap principale per impostazione predefinita.
Josh Diehl

@markz, sto anche usando qualcosa di simile e ev.preventDefault (); allo stesso modo, ma sempre al clic del collegamento, quando ottengo la finestra modale, tutti i menu a discesa della mia pagina vengono ripristinati. Qualche idea su come evitarlo?
Jaikrat

73

Per scaricare i dati quando il modale è chiuso puoi usarlo con Bootstrap 2.x:

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

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

Perfetto. ha funzionato senza alcun problema. in bootstrap 3. Ho usato $ ('. modal'). on ('hidden.bs.modal', function () {$ (this) .removeData ('bs.modal');});
Thupten

4
Non perfetto: mostra brevemente il vecchio contenuto prima del nuovo contenuto.
Laurent

3
@Laurent, puoi cancellare i contenuti precedenti aggiungendo .html (''). Quindi, per 2.x: $ (this) .removeData ('modal'). Find ('. Modal-body'). Html (''). Per 3: $ (this) .removeData ('bs.modal'). Html ('') 2.x carica il contenuto nel .modal-body, mentre 3 carica il contenuto direttamente nel contenitore
.modal

piccola correzione sull'ultimo commento, in bootstrap v3 dovrebbe essere: $ (e.target) .removeData ('bs.modal'). html (''); Questa è la soluzione più elegante finora (ma ritarda un po ').
Cesc

Ho usato la modifica / versione che @Softlion ha pubblicato in questa soluzione proposta: ha funzionato e non ho riscontrato problemi di velocità / ritardo.
user1801810

21

Puoi forzare Modal ad aggiornare il popup aggiungendo questa riga alla fine del metodo hide del plug-in Modal (se stai usando bootstrap-transizione.js v2.1.1, dovrebbe essere alla riga 836)

this.$element.removeData()

O con un ascoltatore di eventi

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

4
-1 L'idea di inserire quel primo frammento direttamente nel plugin Modal è un'idea terribile. Se avessi intenzione di hackerare il plug-in (cosa che eviterei), la cosa più ragionevole da fare sarebbe spostare la load()chiamata fuori dal costruttore e nel show(), o aggiungere un metodo al plug-in per attivare manualmente un ricaricamento di remote. Sul secondo suggerimento, l'ho fornito solo come risposta a una domanda che chiedeva esplicitamente di non farlo nel modo suggerito da @markz .
merv

2
Mi piace l'approccio dell'ascoltatore. Penso che possa anche essere migliorato usando ".modal" invece di "#modal" per evitare l'hardcoding dell'ID. A mio parere è un approccio più pulito di quello di markz, perché continui a utilizzare il data-toggle come nel modal bootstrap originale.
Toni Grimalt

Mi chiedo perché questa risposta non abbia ricevuto molti voti positivi. Questa risposta sembra essere la prima a suggerire un ascoltatore di eventi abbastanza interessante e veloce da implementare.
Anupam

15

Con Bootstrap 3 puoi utilizzare il gestore di eventi 'hidden.bs.modal' per eliminare qualsiasi dato relativo alla modalità modale, costringendo il popup a ricaricarsi la volta successiva:

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

1
Sì, ma c'è ancora un ritardo cruciale in questa soluzione; mostra ancora il vecchio contenuto per un secondo o tre prima del nuovo.
doc vacanza

invece di #modal prova il corpo
wobsoriano

8

Basato su altre risposte (grazie a tutti).

Avevo bisogno di adattare il codice affinché funzionasse, poiché la semplice chiamata .html cancellava l'intero contenuto e il modale non si caricava con alcun contenuto dopo averlo fatto. Quindi ho semplicemente cercato l'area del contenuto del modale e lì ho applicato il ripristino dell'HTML.

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

Può ancora andare con la risposta accettata poiché sto facendo un brutto salto appena prima dei carichi modali poiché il controllo è con Bootstrap.


5

Un po 'più compresso rispetto all'esempio sopra accettato. Afferra il target dal data-target del corrente cliccato su qualsiasi cosa con data-toggle = modal on. In questo modo non devi sapere qual è l'id del modale di destinazione, basta riutilizzare lo stesso! meno codice = vinci! Puoi anche modificarlo per caricare titolo, etichette e pulsanti per il tuo modale se lo desideri.

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

Link di esempio:

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

3

Ho apportato una piccola modifica alla risposta di Softlion , quindi tutte le mie modali non si aggiorneranno su hide. Le modalità con l'attributo data-refresh = 'true' vengono solo aggiornate, altre funzionano come al solito. Ecco la versione modificata.

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

Ora usa l'attributo come mostrato di seguito,

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

Questo assicurerà che solo i modali con data-refresh = 'true' vengano aggiornati. E sto anche resettando l'html modale perché i vecchi valori vengono mostrati fino a quando non vengono caricati nuovi, rendendo html vuoto che risolve quello.


2

Ecco una versione coffeescript che ha funzionato per me.

$(document).on 'hidden.bs.modal', (e) ->
  target = $(e.target)
  target.removeData('bs.modal').find(".modal-content").html('')

ha risolto un problema in cui il contenuto si ricarica ma js all'interno di modal non viene eseguito una seconda volta
Souhaieb

1

Funzionerà con tutte le versioni di twitterbootstrap

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

i collegamenti a modal sono

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

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


1

Anche io ero bloccato su questo problema poi ho visto che gli id del modale sono gli stessi. Hai bisogno di ID diversi di modali se vuoi più modali. Ho usato l' ID dinamico . Ecco il mio codice in haml:

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

Puoi farlo

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

e i tuoi collegamenti a modal saranno

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

Spero che questo funzioni per te.


1

Puoi provare questo:

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

0

Volevo che il contenuto caricato AJAX fosse rimosso quando il modale si chiudeva, quindi ho regolato la linea suggerita da altri (sintassi coffeescript):

$('#my-modal').on 'hidden.bs.modal', (event) ->
  $(this).removeData('bs.modal').children().remove()

0

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

Ha funzionato per me


0

passaggio 1: creare un wrapper per il modale chiamato clone-modal-wrapper.

passaggio 2: crea un div vuoto chiamato modal-wrapper.

Passaggio 3: copia l'elemento modale da clone-modal-wrappera modal-wrapper.

passaggio 4: attiva / disattiva il modale di 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');
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.