none
GridViewのクリックイベントについて RRS feed

  • 質問

  • VB.Netを用いてWebページの開発をしています。(VB.Net2013、IE11.0、.NetFramework4.5.2、IIS7.5)

    画面右上の×ボタンを閉じるときに、ブラウザ上で確認メッセージを表示させるため、jqueryを使用し、

    以下のようなスクリプトをjsファイルに設定しています。

    var execBeforeUnload = true;
    $(window).bind('beforeunload', function(e) {
    if (execBeforeUnload) {
    return '終了します';
    }
    });

    aタグのような他の画面に遷移するような動きをするものについては、

    下記を追加して終了メッセージは表示しないよう回避しようとしているのですが、

    GridViewの一覧に配置したボタンクリックのときに、

    何をやっても、下記に記載のイベントではなく、

    終了しますというメッセージが表示されてしまい、

    回避することができません。

    このような経験があり、回避策をお持ちの方いらっしゃいましたら、

    ご教示ください。

    $(document).ready(function() {
    $('a').click(function(e) {
    if (e.target.href && e.target.href.indexOf("javascript") === 0) {
    execBeforeUnload = false;
    setTimeout(function() {
    execBeforeUnload = true;
    }, 0);}
    });
    });

    ※GridView

     <asp:GridView runat="server" CssClass="form" ID="TestGrid" AutoGenerateColumns="False" ShowHeader="False" BorderStyle="None" >
         <Columns>
              <asp:CommandField ButtonType="Button" ShowSelectButton="True" headertext="選択">
                    <ItemStyle Width="68px" CssClass="form" />
               </asp:CommandField>
               <asp:BoundField DataField="XXXXX">
                    <ItemStyle Width="353px" CssClass="form" />
               </asp:BoundField>
                                       
          </Columns>
    </asp:GridView>


    • 編集済み takusan 2015年9月3日 11:55
    2015年9月3日 11:55

回答

  • 当方でもコードを書いて検証してみました。

    > 通常のボタンであれば、下記のコードを入れることによって回避ができるのですが、
    > なぜかGridviewの中のボタンをクリックした時は、$(document).ready~より先に、
    > BeforeUnloadのイベントが走るようです。

    うまく行かない理由は、「$(document).ready~より先に、BeforeUnloadのイベントが走る」ということではないです。

    <asp:CommandField ButtonType="Button" ... は html ソースでは以下のようになって、ASP.NET が onclick に設定したスクリプト __doPostBack の方が先に動いて execBeforeUnload が false に設定される前にポストバックされる(form が submit される)からです。

    <input type="button" 
        value="選択" 
        onclick="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Select$0&#39;)" />
    


    対処法方は以下のようにするのがよいと思います。

    デザイン画面で CommandField を TemplateField に変換します。以下のようになるはずです(上が元の CommandField で、その下が自動変換された TemplateField)。

    <asp:CommandField ShowSelectButton="True" ButtonType="Button" />                
    
    <asp:TemplateField ShowHeader="False">
        <ItemTemplate>
            <asp:Button ID="Button1" runat="server" CausesValidation="False" 
                CommandName="Select" Text="選択" />
        </ItemTemplate>
    </asp:TemplateField>
    

    execBeforeUnload を false に設定するスクリプトは以下のようにします。(:button ではなく :submit)

    $(':submit').click(function (e) {
        execBeforeUnload = false;
    });

    上記でダメならその旨連絡してください。
    • 回答としてマーク takusan 2015年9月4日 4:44
    2015年9月4日 3:26

すべての返信

  • > aタグのような他の画面に遷移するような動きをするものについては、
    > 下記を追加して終了メッセージは表示しないよう回避しようとしているのですが、

    それは以下のコードで実現しているのですよね?

    > $(document).ready(function() {
    > $('a').click(function(e) {
    > ・・・後略・・・

    で、もし上記以外には回避するためのコードはないのなら、

    > GridViewの一覧に配置したボタンクリックのときに、
    > 何をやっても、下記に記載のイベントではなく、
    > 終了しますというメッセージが表示されてしまい、
    > 回避することができません。

    というのは、上の回避するためのコードが $('a') 即ち a 要素のみに設定されていて、<asp:CommandField ButtonType="Button" ... には設定されてないので当然そうなると思いますけど。
     
    <asp:CommandField ButtonType="Button" ... が html ソースではどうなるかを見て、それの click イベントにも回避するためのコードを設定すればうまく行くのでは?(未検証です。ご自分で試してみてうまく行かなかったらその旨連絡ください)

    2015年9月3日 13:32
  • ご回答ありがとうございます。

    通常のボタンであれば、下記のコードを入れることによって回避ができるのですが、

    なぜかGridviewの中のボタンをクリックした時は、$(document).ready~より先に、

    BeforeUnloadのイベントが走るようです。

    この回避の方法がわからず思案しています。

    何か良いアドバイスありませんでしようか。

    var execBeforeUnload = true;
    $(function () {

        // フォームの入力欄が更新されたかどうかを表すフラグです。
        var isChanged = true;

        $(window).bind("beforeunload", function(evtn) {
            if (execBeforeUnload) {

                   var msg = "終了します"

                   return msg;
            }
        });
    });
    //
    $(document).ready(function () {
        $('a').click(function (e) {
                cancelBeforeUnload();
        });
        $(':button').click(function (e) {
                cancelBeforeUnload();
        });
    });

    2015年9月4日 1:57
  • 当方でもコードを書いて検証してみました。

    > 通常のボタンであれば、下記のコードを入れることによって回避ができるのですが、
    > なぜかGridviewの中のボタンをクリックした時は、$(document).ready~より先に、
    > BeforeUnloadのイベントが走るようです。

    うまく行かない理由は、「$(document).ready~より先に、BeforeUnloadのイベントが走る」ということではないです。

    <asp:CommandField ButtonType="Button" ... は html ソースでは以下のようになって、ASP.NET が onclick に設定したスクリプト __doPostBack の方が先に動いて execBeforeUnload が false に設定される前にポストバックされる(form が submit される)からです。

    <input type="button" 
        value="選択" 
        onclick="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Select$0&#39;)" />
    


    対処法方は以下のようにするのがよいと思います。

    デザイン画面で CommandField を TemplateField に変換します。以下のようになるはずです(上が元の CommandField で、その下が自動変換された TemplateField)。

    <asp:CommandField ShowSelectButton="True" ButtonType="Button" />                
    
    <asp:TemplateField ShowHeader="False">
        <ItemTemplate>
            <asp:Button ID="Button1" runat="server" CausesValidation="False" 
                CommandName="Select" Text="選択" />
        </ItemTemplate>
    </asp:TemplateField>
    

    execBeforeUnload を false に設定するスクリプトは以下のようにします。(:button ではなく :submit)

    $(':submit').click(function (e) {
        execBeforeUnload = false;
    });

    上記でダメならその旨連絡してください。
    • 回答としてマーク takusan 2015年9月4日 4:44
    2015年9月4日 3:26
  • お世話になります。

    うまく行けました!

    アドバイスいただきました、下記内容でテストしましたところ、

            <asp:Button ID="Button1" runat="server" CausesValidation="False"
               
    CommandName="Select" Text="選択"  />

    GridViewで選択した行(選択行の内容)の番号が以前取れてたものが

    取れなくなってしまったので、

    CommandArgument="<%# CType(Container, GridViewRow).RowIndex%>

    を追加して取得するようにしたところ、うまく行くようになりました。

    大変参考になりました!

    ありがとうございました。

    2015年9月4日 4:43