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?



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.


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

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

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

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.


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>

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.


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

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>


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.


1

Możesz spróbować tego:

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

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


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');
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.