モーダルでコンテンツをリロード(twitterブートストラップ)


98

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>

このa要素でajaxを使用してコンテンツをロードできます。

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

同じモーダルを開く必要がありますが、別のURLを使用しています。このモーダルを使用して、データベースのエンティティを編集しています。エンティティの編集をクリックすると、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>

リンク番号1をクリックすると、正常に動作します。しかし、リンク番号2をクリックすると、モーダルコンテンツが既に読み込まれているため、リンク番号1のコンテンツが表示されます。

TwitterブートストラップモーダルポップアップでAjaxで読み込まれたコンテンツを更新またはリセットするにはどうすればよいですか?



同じ問題があり、同じソリューションに慣れていました。なんらかの理由で.data()関数が機能しなかったため、jqueryの.attr()関数を使用しています。
user1803784 2016

回答:


98

私は同じ問題を抱えており、これを行う方法はdata-toggle属性を削除してリンクのカスタムハンドラーを作成することだと思います。

以下の行の何か:

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

後で試してコメントを投稿します。


16
$( '。modal')。on( 'hidden'、function(){$(this).removeData();})これは以下のソリューションの私の変更です...クリックをキャッチしてロードする必要がないため、よりクリーンですそれはあなた自身のプログラマティックモデルショーがまだ機能している
カーターコール

1
私はBootstrap 3を使用していますが、モーダルのコンテンツは毎回更新されますが、2つのモーダルウィンドウが作成されます。他の誰かがこれを受け取りますか?
B氏

1
Hey Sid、 "modal-body"クラスで2つのdivを作成しています。実際にはすでに作成していて、モーダルは再び作成しています。そのコードから、「。modal-body」を削除すると正常に動作するはずです。
Palantir 2013年

1
Bootstrap 3で動作します。デフォルトでコアブートストラップライブラリでサポートされていないことに非常に苛立ちます。
Josh Diehl 2013年

@markz、私もこのようなものを使用しており、ev.preventDefault(); 同様に、リンクをクリックしても、モーダルウィンドウが表示されると、ページのすべてのドロップダウンがリセットされます。それを防ぐ方法はありますか?
Jaikrat 2014年

72

モーダルが閉じているときにデータをアンロードするには、これをBootstrap 2.xで使用できます。

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

そして、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');
});

完璧。問題なく動作しました。ブートストラップ3で。私は$( '。modal')。on( 'hidden.bs.modal'、function(){$(this).removeData( 'bs.modal');});を使用しました。
2013

4
完璧ではありません:新しいコンテンツの前に古いコンテンツが簡単に表示されます。
ローラン

3
@ Laurent、.html( '')を追加することで以前のコンテンツをクリアできます。したがって、2.xの場合:$(this).removeData( 'modal')。find( '。modal-body')。html( '')。3の場合:$(this).removeData( 'bs.modal')。html( '')2.xはコンテンツを.modal-bodyにロードしますが、3はコンテンツを.modalコンテナーに直接ロードします
nabrown

ブートストラップv3では、最後のコメントの小さな修正は次のようになります:$(e.target).removeData( 'bs.modal')。html( ''); これは、これまでで最もエレガントなソリューションです(ただし、少し遅れます)。
Cesc 2013年

私は@Softlionがこの提案されたソリューションに投稿した編集/バージョンを使用しました-機能し、速度/遅延の問題は発生しませんでした。
user1801810

21

Modalプラグインのhideメソッドの最後にこの行を追加することで、Modalに強制的にポップアップを更新させることができます(bootstrap-transition.js v2.1.1を使用している場合は、836行目にあるはずです)。

this.$element.removeData()

またはイベントリスナーを使って

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

4
-1その最初のスニペットを直接Modalプラグインに入れるという考えは、ひどい考えです。プラグインをハックする場合(私は避けます)、より合理的な方法は、load()呼び出しをコンストラクターからに移動するかshow()、プラグインにメソッドを追加して手動でリロードをトリガーすることです。remote。2番目の提案では、@ markzが提案た方法で実行しないことを明示的に要求した質問に対する回答としてのみ提供しまし
merv

2
私はリスナーのアプローチが好きです。IDのハードコーディングを回避するために、「#modal」の代わりに「.modal」を使用して改善することもできると思います。私の意見では、これはmarkzよりもクリーンなアプローチです。なぜなら、元のブートストラップモーダルと同じようにデータトグルを使い続けるからです。
Toni Grimalt 2013

なぜこの回答はあまり賛成票を持っていないのでしょうか。この回答は、非常に興味深い実装が迅速なイベントリスナーを提案する最初の回答のようです。
アヌパム2018

15

Bootstrap 3では、「hidden.bs.modal」イベントハンドラーを使用してモーダル関連データを削除し、次にポップアップを強制的にリロードすることができます。

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

1
はい。ただし、このソリューションにはまだ重大な遅れがあります。それでも、新しいコンテンツの前に1〜3秒間古いコンテンツが表示されます。
ドキュメントの休日

#modal try bodyの代わりに
wobsoriano 2016年

8

他の回答に基づいています(みんなに感謝します)。

.htmlを呼び出すだけでコンテンツ全体がワイプされ、モーダルが実行した後にコンテンツが読み込まれないため、コードを調整して動作させる必要がありました。だから私は単にモーダルのコンテンツ領域を探し、そこにHTMLのリセットを適用しました。

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

コントロールがブートストラップを使用しているため、モーダルがロードされる直前にいくつかの醜いジャンプを取得しているため、まだ受け入れられている回答でうまくいく場合があります。


5

上記の受け入れられた例よりも少し圧縮されています。data-toggle = modalをオンにして、現在クリックされているもののデータターゲットからターゲットを取得します。これにより、ターゲットモーダルのIDが何であるかを知る必要がなくなり、同じものを再利用するだけです!少ないコード=勝つ!これを変更して、必要に応じてモーダルのタイトル、ラベル、ボタンをロードすることもできます。

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

リンクの例:

<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

Softlionの回答に小さな変更を加えたので、すべてのモーダルが非表示で更新されません。data-refresh = 'true'属性を持つモーダルは更新されるだけで、その他は通常どおり機能します。こちらが修正版です。

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

次のように属性を使用します。

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

これにより、data-refresh = 'true'のモーダルのみが確実に更新されます。また、新しい値が読み込まれるまで古い値が表示されるため、モーダルhtmlをリセットしています。これにより、htmlの空の値が修正されます。


2

これは私のために働いたコーヒースクリプトバージョンです。

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

コンテンツは再読み込みされますが、モーダル内のjsが2回実行されないという問題が解決されました
Souhaieb

1

すべてのバージョンのtwitterbootstrapで動作します

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>

モーダルへのリンクは

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

モーダルをポップアップ

<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

私もこの問題に行き詰まり、モーダルのIDが同じであることがわかりました。複数のモーダルが必要な場合は、モーダルの異なるIDが必要です。動的IDを使用しました。これが私のコードですhaml

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

あなたはこれを行うことができます

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

これがうまくいくことを願っています。


1

あなたはこれを試すことができます:

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

0

モーダルが閉じたときにAJAXロードされたコンテンツを削除したかったので、他の人が提案した行を調整しました(coffeescript構文):

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


0

ステップ1:と呼ばれるモーダルのラッパーを作成しますclone-modal-wrapper

ステップ2:という空のdivを作成しますmodal-wrapper

ステップ3:モーダル要素をからclone-modal-wrapperにコピーし modal-wrapperます。

ステップ4:のモーダルを切り替え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');
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.