読者です 読者をやめる 読者になる 読者になる

1.21 jigowatts

Great Scott!

jQueryとASP.NETのボタンの挙動について

ASP.NET

現在開発中のWebアプリにてマスターページのformのonsubmit属性に"return false;"が設定されており(Ajax利用のため?)、サーバにフォームを送信したい場合にどうすればいいかを調べてみました。

Button Webサーバーコントロール

Button Webサーバーコントロールはinputタグのtype="submit"に自動で書き換えられてしまうようです。

Index.aspx

<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />


ページのソース

<input type="submit" name="Button1" value="Button" id="Button1" />

Button WebサーバーコントロールのClickイベントをjQueryで書いた場合、サーバにフォームが送信されて画面がリロードされてしまいます。

画面のリロードをさせたくない場合は、Clickイベントでfalseをreturnすることで対応できます。

$('#Button1').click(function () {
    console.log('#Button1');
    return false;
});

Input(Button)タグ

Input(Button)タグを使うことでサーバにフォームを送信せずにクライアントサイドで処理を行うこともできます。

<input id="Button2" type="button" value="Button" />

汎用ボタンなのでsubmitせずにクライアントサイドの処理が可能

$('#Button2').click(function () {
    console.log('#Button2');
});


今回のケースはformのonsubmit属性にretrun false;が設定されていました。form単位での制御により不意なサーバへのフォーム送信を防ぐことができるためでしょうか。

<form id="form1" runat="server" onsubmit="return false;">

ただし、この方法の場合サーバにフォームを送信したい場合まで出来なくなってしまう弊害があります。(マスターページのformのため配下の全ページに影響する)


対処法としてjQueryで一時的にformのonsubmit属性を書き換えてみました。

protected void Button1_Click(object sender, EventArgs e)
{
    //サーバ側の処理
    System.Diagnostics.Debug.WriteLine("Button1");
}

一時的にサーバにフォーム送信

$('#Button1').click(function () {
    console.log('#Button1');
    $('#form1').attr({ onsubmit: "" });
});

もう少しいい方法があるかもしれませんし、そもそもformのonsubmit属性でreturn falseをしない方がいいのかはもう少し調べる必要がありますね。

f:id:sh_yoshida:20130917012636p:plain

ソース

Index.aspx

<%@ Page Language="C#" AutoEventWireup="true" 
CodeBehind="Index.aspx.cs" Inherits="WebApp.Index" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Ajax Test</title>
    <script src="/Scripts/jquery-1.9.0.min.js" type="text/javascript"></script>

</head>
<body>
    <form id="form1" runat="server" onsubmit="return false;">
    <div>
        <label id="now"></label><br/>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="Button1" onclick="Button1_Click" />
        <input id="Button2" type="button" value="Button2" />
        <asp:Button ID="Button3" runat="server" Text="Button3" />
    </div>
    </form>

    <script type="text/javascript">

        $(function () {

            $('#now').text(new Date);

            $('#Button1').click(function () {
                console.log('#Button1');
                $('#form1').attr({ onsubmit: "" });
            });
            $('#Button2').click(function () {
                console.log('#Button2');
            });
            $('#Button3').click(function () {
                console.log('#Button3');
            });
        });
    </script>
</body>
</html>

Index.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApp
{
    public partial class Index : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Button1");
        }
    }
}

#後日追記
formのonsubmit属性に"return false;"を設定したのはやはり、Ajax利用サイトのためでした。
今回は無理やりformの属性を変更してみましたが、これは誤った解決法でありジェネリックハンドラで処理をするべきということがわかりました。
ジェネリックハンドラの処理については別の記事で書いてみます。