Załaduj ponownie zawartość w trybie modalnym (bootstrap na Twitterze)

98

Używam wyskakującego okienka modalnego Twittera 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>

Mogę załadować zawartość za pomocą Ajax z tym elementem a:

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

Teraz muszę otworzyć ten sam modalny, ale używając innego adresu URL. Używam tego modalu do edycji encji z mojej bazy danych. Więc kiedy klikam edytuj na encji, muszę załadować modal z identyfikatorem.

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

Jeśli kliknę link numer 1, działa dobrze. Ale jeśli następnie kliknę link numer 2, zawartość modalna jest już załadowana i dlatego wyświetli zawartość z linku numer 1.

Jak mogę odświeżyć lub zresetować załadowaną zawartość Ajax w modalnym wyskakującym okienku bootstrap na Twitterze?

stian.net
źródło
Miałem ten sam problem i stosowałem to samo rozwiązanie. Uciekam się do funkcji .attr () z jquery z jakiegoś dziwnego powodu, funkcja .data () nie działała.
user1803784

Odpowiedzi:

98

Mam ten sam problem i myślę, że sposobem na zrobienie tego będzie usunięcie atrybutu przełączania danych i utworzenie niestandardowego modułu obsługi łączy.

Coś w rodzaju:

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

Spróbuję później i opublikuję komentarze.

markz
źródło
16
$ ('. modal'). on ('hidden', function () {$ (this) .removeData ();}) to moja modyfikacja poniższego rozwiązania ... czyściej, ponieważ nie musisz łapać kliknięcia i ładować zrób to sam, więc programowy pokaz modeli nadal działa
Carter Cole,
1
Używam Bootstrap 3, zawartość w oknie modalnym jest odświeżana za każdym razem, ale tworzy dwa okna modalne. Czy ktoś jeszcze to rozumie?
Pan B
1
Hej Sid, tworzysz 2 elementy div z klasą „modal-body”, właściwie już je tworzysz, a modal tworzy ponownie. Z tego kodu usuń „.modal-body” i powinno działać dobrze.
Palantir
1
Działa dla mnie z Bootstrap 3, bardzo frustrujące, że nie jest to domyślnie obsługiwane przez podstawową bibliotekę bootstrap.
Josh Diehl
@markz, używam też czegoś takiego i ev.preventDefault (); ale nadal po kliknięciu linku, kiedy pojawia się okno modalne, wszystkie menu mojej strony są resetowane. Każdy pomysł, jak temu zapobiec?
Jaikrat
73

Aby wyładować dane, gdy modal jest zamknięty, możesz użyć tego z Bootstrap 2.x:

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

Oraz w 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
źródło
idealny. działał bez problemu. w bootstrap 3. Użyłem $ ('. modal'). on ('hidden.bs.modal', function () {$ (this) .removeData ('bs.modal');});
Thupten
4
Brak ideału: na krótko pokazuje starą treść przed nową zawartością.
Laurent
3
@Laurent, możesz usunąć poprzednią zawartość, dodając .html („”). Tak więc dla 2.x: $ (this) .removeData ('modal'). Find ('. Modal-body'). Html (''). Dla 3: $ (this) .removeData ('bs.modal'). Html ('') 2.x ładuje zawartość do .modal-body, podczas gdy 3 ładuje zawartość bezpośrednio do .modal kontenera
nabrown
mała poprawka do ostatniego komentarza, w bootstrap v3 powinno być: $ (e.target) .removeData ('bs.modal'). html (''); Jak dotąd to najbardziej eleganckie rozwiązanie (choć trochę się opóźnia).
Cesc
Użyłem edycji / wersji, którą @Softlion zamieścił w tym proponowanym rozwiązaniu - zadziałało i nie miałem żadnych problemów z szybkością / opóźnieniem.
user1801810
21

Możesz zmusić Modal do odświeżenia wyskakującego okienka, dodając ten wiersz na końcu metody ukrywania wtyczki Modal (jeśli używasz bootstrap-transit.js v2.1.1, powinien znajdować się w linii 836)

this.$element.removeData()

Lub ze słuchaczem wydarzeń

$('#modal').on('hidden', function() {
    $(this).data('modal').$element.removeData();
})
Sergio
źródło
4
-1 Pomysł umieszczenia tego pierwszego fragmentu kodu bezpośrednio we wtyczce Modal to straszny pomysł. Jeśli masz zamiar włamać się do wtyczki (czego bym unikał), bardziej rozsądną rzeczą byłoby przeniesienie load()wywołania z konstruktora do show()lub dodanie metody do wtyczki, aby ręcznie uruchomić ponowne załadowanie remote. Jeśli chodzi o drugą sugestię, podałem ją tylko jako odpowiedź na pytanie, w którym wyraźnie prosiłem, aby nie robić tego w sposób sugerowany przez @markz .
merv
2
Podoba mi się podejście słuchacza. Myślę, że można to nawet ulepszyć za pomocą „.modal” zamiast „#modal”, aby uniknąć sztywnego kodowania identyfikatora. Moim zdaniem jest to czystsze podejście niż markza, ponieważ nadal używasz przełączania danych, tak jak w oryginalnym trybie bootstrap.
Toni Grimalt
Zastanawiam się, dlaczego ta odpowiedź nie ma zbyt wielu głosów pozytywnych. Ta odpowiedź wydaje się być pierwszą, która sugeruje słuchacz zdarzenia, który jest dość interesujący i szybki w implementacji.
Anupam
15

W Bootstrap 3 możesz użyć modułu obsługi zdarzeń `` hidden.bs.modal '', aby usunąć wszelkie dane związane z modalem, zmuszając wyskakujące okienko do ponownego załadowania następnym razem:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
Sztuka
źródło
1
Tak, ale nadal istnieje istotne opóźnienie w tym rozwiązaniu; nadal wyświetla stare treści na sekundę lub trzy przed nową.
święto doc
zamiast #modal try body
wobsoriano
8

Na podstawie innych odpowiedzi (dzięki wszystkim).

Musiałem dostosować kod do pracy, ponieważ zwykłe wywołanie .html wymazało całą zawartość, a modal nie ładował się żadną zawartością po tym, jak to zrobiłem. Więc po prostu szukałem obszaru zawartości modalu i zastosowałem tam resetowanie HTML.

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

Nadal może pójść z zaakceptowaną odpowiedzią, ponieważ dostaję brzydki skok tuż przed ładowaniem modalnym, ponieważ kontrola jest z Bootstrapem.

Modika
źródło
5

Nieco bardziej skompresowany niż powyższy akceptowany przykład. Przechwytuje cel z celu danych aktualnie klikniętego elementu z włączoną opcją data-toggle = modal. To sprawia, że ​​nie musisz wiedzieć, jaki jest identyfikator docelowego modalu, po prostu użyj tego samego! mniej kodu = wygrana! Możesz również zmodyfikować to, aby załadować tytuł, etykiety i przyciski dla swojego modalu, jeśli chcesz.

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

Przykładowe linki:

<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
źródło
3

Zrobiłem małą zmianę w odpowiedzi Softlion , więc wszystkie moje modały nie odświeżają się po ukryciu. Modały z atrybutem data-refresh = 'true' są tylko odświeżane, inne działają jak zwykle. Oto zmodyfikowana wersja.

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

Teraz użyj atrybutu, jak pokazano poniżej,

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

Zapewni to odświeżenie tylko modali z data-refresh = 'true'. Zresetowałem również modalny kod HTML, ponieważ stare wartości są wyświetlane, dopóki nie zostaną załadowane nowe, co powoduje, że pusty kod HTML rozwiązuje ten problem.

Shiva Avula
źródło
2

Oto wersja Coffeescript, która zadziałała dla mnie.

$(document).on 'hidden.bs.modal', (e) ->
  target = $(e.target)
  target.removeData('bs.modal').find(".modal-content").html('')
rgagnon
źródło
rozwiązano problem polegający na tym, że zawartość przeładowuje się, ale js wewnątrz modalu nie wykonuje się po raz drugi
Souhaieb
1

Będzie działać dla wszystkich wersji twitterbootstrap

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

linki do modalnych są

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

<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
źródło
1

Utknąłem też w tym problemie, a potem zobaczyłem, że identyfikatory modalu są takie same. Jeśli chcesz mieć wiele modali, potrzebujesz różnych identyfikatorów modali. Użyłem dynamicznego identyfikatora . Oto mój kod w haml:

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

możesz to zrobić

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

a twoje linki do modalu będą

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

Mam nadzieję, że to zadziała.

Asnad Atta
źródło
1

Możesz spróbować tego:

$('#modal').on('hidden.bs.modal', function() {
    $(this).removeData('bs.modal');
});
bharat
źródło
0

Chciałem, aby zawartość ładowana przez AJAX została usunięta po zamknięciu modalu, więc dostosowałem linię sugerowaną przez innych (składnia coffeescript):

$('#my-modal').on 'hidden.bs.modal', (event) ->
  $(this).removeData('bs.modal').children().remove()
puste ściany
źródło
0

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

Pracował dla mnie

Ashwin Golani
źródło
0

Krok 1: Utwórz opakowanie dla modalu o nazwie clone-modal-wrapper.

Krok 2: Utwórz pusty element div o nazwie modal-wrapper.

Krok 3: Skopiuj element modalny z clone-modal-wrapperdo modal-wrapper.

Krok 4: Przełącz tryb 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
źródło