none
ASP.NETでbootstrapのModalを使用する方法 RRS feed

  • 質問

  • Hoshinaです
    こんにちは

    ASP.NETでBootstrapのModalダイアログを使用したいのですが,うまくいきません。

    環境は以下の通りです
    ・Visual Studio 2010
    ・WEBサイト
    ・HTML5
    ・確認用のブラウザは,Chrome 35.0.1916.153m

    シナリオは以下の通りです
    ・画面に「削除」のボタンがあります
    ・そのボタンクリックで,Bootstrap の Modalダイアログを表示します
    ・ダイアログに存在する「OK」ボタンで,ポストバックを発生させたい

    現状は,上記シナリオの3番目で,ポストバックが発生してくれません。

    画面の「削除」ボタンのHTMLは以下の通りです。

    <asp:Button ID="DeleteButton" runat="server" CssClass="btn btn-primary" Text="削除"
                                UseSubmitBehavior="false" OnClientClick="return false"
                                data-toggle="modal" data-target="#myModal" />

    標準的な使い方から外れているのは,ボタンの有効/無効をプログラムで制御したいことと,ポストバックを発生させることなく,Modalダイアログを表示させたい点です。

    Modalダイアログと,ポストバックを発生させたいボタンのHTMLは以下の通りです。

            <div class="modal fade" id="myModal" tabindex="-1" role="dialog">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel">
                                削除確認</h4>
                        </div>
                        <div class="modal-body">
                            このデータを削除します。よろしいですか?
                        </div>
                        <div class="modal-footer">
                            <asp:Button ID="DeleteAction" runat="server" CssClass="btn btn-primary" Text="O K" data-dismiss="modal"  />
                            <button type="button" class="btn btn-primary" data-dismiss="modal">
                                Cancel</button>
                        </div>
                    </div>
                </div>
           </div>

    DeleteActionボタンに,data-dismissと付けているのは,こうしないとボタンクリックでダイアログが消えなかったためです。

    確認できていることは,次のことです。
    ・javaconsoleを使用して,function __doPostBack(eventTarget, eventArgument)の呼出しは確認できましたが,ポストバックがかかりません(デバッガでポストバック用メソッドに停止しません)
    System.Web.UI.ICallbackEventHandler を使用して,明示的にポストバックを発生させると,ポストバックはするのですが,それ以降に全く不可解な動作をします
    ・Bootstrap の Modal を使用せず,ブラウザの confirm() を使用すると,すべてうまくいきます

    今回の試みは,見た目をすべてBootstrapに合わせてカッコよくしたいというのがスタートでした。
    この件をあきらめてしまえば,動作的には問題がありませんが,できれば何とかしたいと思っています。

    何か誤りに気がつかれた方や,対応策をお持ちの方がありましたら,ご教授ください。
    昨日から色々のことをやっているため,もしかすると矛盾した内容があるかもしれません。その際は,ご指摘ください。

    それでは

    2014年7月11日 2:03

回答

  • Hoshinaです
    おそらく,解決できたと思います。

    正解と思われる,Modalと<asp:button>のHTMLを以下にのせます。

            <div class="modal fade" id="myModal" tabindex="-1" role="dialog">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel">
                                 削除確認</h4>
                        </div>
                        <div class="modal-body">
                            このデータを削除します。よろしいですか?
                        </div>
                        <div class="modal-footer">
                            <asp:Button ID="DeleteAction" runat="server" CssClass="btn btn-primary" Text="O K"
                                OnClick="DeleteAction_Click" UseSubmitBehavior="false" data-dismiss="modal" />
                            <button type="button" class="btn btn-primary" data-dismiss="modal">
                                Cancel</button>
                        </div>
                    </div>
                </div>
            </div>

    味噌は,OnClick属性とUseSubmitBehavior属性を両方指定することのようです。
    理屈からは,後者のみで十分と思いますので,両方付けたパターンはダメ元で試してみました。

    生成されたHTMLを比較すると,タグの部分は全く同一です。
    しかしながら,動作しない場合には「0x0d」(つまり,CRコード)が1バイト余分についていました。
    おそらくこれが原因と思います。

    それでは



    • 回答としてマーク Hoshina 2014年7月11日 7:06
    • 編集済み Hoshina 2014年7月11日 7:14 HTMLの文言を追加
    2014年7月11日 7:05
  • > 味噌は,OnClick属性とUseSubmitBehavior属性を両方指定することのようです。
    > 理屈からは,後者のみで十分と思いますので,両方付けたパターンはダメ元で試してみました。

    「理屈からは,後者のみで十分」というのは間違いだと思います。

    UseSubmitBehavior="false" によって Button に該当する html コードの input 要素の onclick 属性に JavaScript の __doPostBack 関数が追加された。

    それにより、Button クリックでポストバックされるようになったが、サーバー側のでのクリックイベントのハンドラが指定されてなかったので、そこに制御が飛ばなかった。結果、サーバー側での処置がされなかったのでダメだった。

    その後、質問者さんが忘れていたというサーバー側でのイベントハンドラの指定 OnClick="DeleteAction_Click" を追加した。それによりそのハンドラに制御が飛ぶようになり、サーバー側での処置がされるようになって解決したと言うことだと思います。

    いかがですか?

    • 回答としてマーク Hoshina 2014年7月11日 7:59
    2014年7月11日 7:31

すべての返信

  • Bootstrap はさわったこともない自分が、ググって得ただけの情報でレスするのもなんですが・・・

    以下のページと同じ問題ではないでしょうか?

    ASP.NET button inside bootstrap modal not triggering click event
    http://stackoverflow.com/questions/17380287/asp-net-button-inside-bootstrap-modal-not-triggering-click-event

    これによると、当該 Button コントロールの属性に UseSubmitBehavior="false" data-dismiss="modal" を追加して解決したようです。

    asp.net bootstrap modal postback をキーワードにググると、他にもいろいろ出てきますので調べてみてはいかがでしょう?


    • 編集済み SurferOnWww 2014年7月11日 3:09 タイポ訂正
    2014年7月11日 3:05
  • Hoshinaです

    投稿ありがとうございます。

    この元記事は知りませんでしたが,これは既にやってみていました。動作しません。

    UseSumnitBehavior="false"を付けると,OnClick属性に,__doPostBackの関数呼び出しがついたHTMLが生成されるようです。私もこれでいけるかと期待したのですが,ダメでした。

    また,data-dismissをむやみにつけるのはまづいかもと思い,$("#myModal").modal("hide")を呼び出して,自前で消してみましたが効果がありませんでした。

    おそらく,一段目のボタンは,<button><asp:button>で違いはないと思いますので,二段目のボタンを以下のどちらかにするしかないと試行錯誤しましたが,実現できていません。
    ・<button>で見た目を作り,System.Web.UI.ICallBackEventHandlerで独自の処理を組み込む
    ・<asb:button>でなんとかポストバックを発生する

    どちらの場合も,なぜダメなのか分からない動作をします。

    情報をお持ちの方の投稿をお待ちします。


    • 編集済み Hoshina 2014年7月11日 4:28 半角・全角混在の統一
    2014年7月11日 4:26
  • Hoshinaです

    最初の記事に関する訂正です。

    ModalダイアログとボタンのHTMLが間違っていました。

            <div class="modal fade" id="myModal" tabindex="-1" role="dialog">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel">
                                 削除確認</h4>
                        </div>
                        <div class="modal-body">
                            このデータを削除します。よろしいですか?
                        </div>
                        <div class="modal-footer">
                            <asp:Button ID="DeleteAction" runat="server" CssClass="btn btn-primary" Text="O K"
                                OnClick="DeleteAction_Click" data-dismiss="modal" />
                            <button type="button" class="btn btn-primary" data-dismiss="modal">
                                Cancel</button>
                        </div>
                    </div>
                </div>
            </div>

    <asp:Button>にOnClick属性を付けていませんでした。ソースを添付する際に編集作業で削除したためです。
    動作の検証結果には関与しません。


    • 編集済み Hoshina 2014年7月11日 5:18 投稿者の特有な文言を削除
    2014年7月11日 5:17
  • Hoshinaです
    おそらく,解決できたと思います。

    正解と思われる,Modalと<asp:button>のHTMLを以下にのせます。

            <div class="modal fade" id="myModal" tabindex="-1" role="dialog">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel">
                                 削除確認</h4>
                        </div>
                        <div class="modal-body">
                            このデータを削除します。よろしいですか?
                        </div>
                        <div class="modal-footer">
                            <asp:Button ID="DeleteAction" runat="server" CssClass="btn btn-primary" Text="O K"
                                OnClick="DeleteAction_Click" UseSubmitBehavior="false" data-dismiss="modal" />
                            <button type="button" class="btn btn-primary" data-dismiss="modal">
                                Cancel</button>
                        </div>
                    </div>
                </div>
            </div>

    味噌は,OnClick属性とUseSubmitBehavior属性を両方指定することのようです。
    理屈からは,後者のみで十分と思いますので,両方付けたパターンはダメ元で試してみました。

    生成されたHTMLを比較すると,タグの部分は全く同一です。
    しかしながら,動作しない場合には「0x0d」(つまり,CRコード)が1バイト余分についていました。
    おそらくこれが原因と思います。

    それでは



    • 回答としてマーク Hoshina 2014年7月11日 7:06
    • 編集済み Hoshina 2014年7月11日 7:14 HTMLの文言を追加
    2014年7月11日 7:05
  • > 味噌は,OnClick属性とUseSubmitBehavior属性を両方指定することのようです。
    > 理屈からは,後者のみで十分と思いますので,両方付けたパターンはダメ元で試してみました。

    「理屈からは,後者のみで十分」というのは間違いだと思います。

    UseSubmitBehavior="false" によって Button に該当する html コードの input 要素の onclick 属性に JavaScript の __doPostBack 関数が追加された。

    それにより、Button クリックでポストバックされるようになったが、サーバー側のでのクリックイベントのハンドラが指定されてなかったので、そこに制御が飛ばなかった。結果、サーバー側での処置がされなかったのでダメだった。

    その後、質問者さんが忘れていたというサーバー側でのイベントハンドラの指定 OnClick="DeleteAction_Click" を追加した。それによりそのハンドラに制御が飛ぶようになり、サーバー側での処置がされるようになって解決したと言うことだと思います。

    いかがですか?

    • 回答としてマーク Hoshina 2014年7月11日 7:59
    2014年7月11日 7:31
  • Hoshinaです

    動作するHTMLと動作しないHTMLを比較して,違っている点を発見したためこれが原因と即断してしまいました。

    良く考えると,SurferOnWwwさんの指摘が正解ですね。

    javascriptの__doPostBackが呼び出されているのに,該当するメソッドが呼び出されていないことが判明した時点で,このことに気がつけばよかったです。
    UseSubmitBehavior="false"の動作時に関して,思いこみがあったのもいけない点でした。

    再度の投稿,ありがとうございました。

    一つだけ補足します。

    OnClick="DeleteAction_Click"はずっと付けていました。
    但し,UseSubmitBehavior="false"を試す際に,ご丁寧にも削除して試していたのです。

    このことを,「UseSubmitBehavior="false"の動作時に関して,思いこみ」と書きました。
    良く考えないといけませんね。



    • 編集済み Hoshina 2014年7月11日 8:17 補足以降を追加
    2014年7月11日 7:58
  • 間違ったことを言っているといけないと思って、自分でも以下のサイトから Bootstrap をダウンロードして試してみました。

    Getting started
    http://getbootstrap.com/getting-started/

    上のページにあった Basic template と、以下のページにあった Modal のサンプルコードを組み合わせて検証用のASP.NET Web Forms アプリのページを作ってみました。

    JavaScript
    http://getbootstrap.com/javascript/

    サンプルコードからは、Modal の表示を jQuery で行うのと、[Save changes] ボタンを ASP.NET の Button コントロールに変更しています。

    Button コントロールに UseSubmitBehavior="false" を追加しなくてもポストバックされました。Button コントロールは html では input type="submit" になりますので、当然クリックでポストバックされるはずですね。質問者さんの場合、何故ダメだったかは不思議です。

    ポストバックされれば、ボタンには OnClick="Button2_Click" とイベントハンドラが設定されていますので、サーバー側でそのコードが動きます。自分が作った例では Label1 が書き換えられることで確認できます。

    さらにポストバックされてページが再描画されると、初期画面と同様に Modal は表示されませんので、data-dismiss="modal" も不要でした。

    何が違うのか分かりませんが、ご参考に検証に使ったコードをアップしておきますので、よろしければ確認してください。

    環境は、Vista SP2, IIS7, ASP.NET 4, Visual Studio 2010 Professional, Bootstrap 3.2.0, jQuery 1.11.1 です。ブラウザは IE9, Firefox 30.0, Chrome 35.0.1916.153 m, Safari 5.1.7, Opera 12.17 で確認しました。

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
        protected void Button2_Click(object sender, EventArgs e)
        {
            Label1.Text = "[Save changes] button clicked!";
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head id="Head1" runat="server">
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <title>Bootstrap Modal Demo</title>
    
        <!-- Bootstrap -->
        <link href="/bootstrap-3.2.0-dist/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->
    
        <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
        <script src="/Scripts/jquery-1.11.1.js" type="text/javascript"></script>
        <!-- Include all compiled plugins (below), or include individual files as needed -->
        <script src="/bootstrap-3.2.0-dist/js/bootstrap.js" type="text/javascript"></script>
    </head>
    <body>
        <form id="form1" runat="server">
        
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        <br />
    
        <input id="Button1" type="button" class="btn btn-primary btn-lg" 
            value="Launch demo modal" onclick="$('#myModal').modal('show');"/>
       
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" 
            aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal">
                            <span aria-hidden="true">&times;</span>
                            <span class="sr-only">Close</span>
                        </button>
                        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
                    </div>
                    <div class="modal-body">
                        Modal Body&hellip;
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>                    
                        <asp:Button ID="Button2" CssClass="btn btn-primary" 
                            runat="server" Text="Save changes" OnClick="Button2_Click" />
                    </div>
                </div>
            </div>
        </div>
        </form>
    </body>
    </html>


    • 編集済み SurferOnWww 2014年7月11日 9:43 Bootstrap, jQuery バージョン追記。
    2014年7月11日 9:28