WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

GridView 内の隠しボタンでポストバック

by WebSurfer 2014年3月26日 17:34

GridView の各データ行に隠し Button を配置し、クライアントスクリプトを使って行クリックで当該行の隠しボタンをクリックすることによりポストバックがかかり、サーバー側の Button.Click イベントでクリックされた行のレコードの ID を取得するサンプルの紹介です。

GirdView 内の隠しボタンでポストバック

先の記事 __doPostBack を使ってはいけません では、GridView の行クリックでポストバックをかけるために GetPostBackEventReference メソッド を使用しました。

この記事のサンプルでは、GetPostBackEventReference メソッドを使う代わりに、隠し Button をクリックすることによりポストバックをかけます。

隠し Button なのでユーザーは直接それをクリックすることはできません。なので、GridView から生成されるデータ行の tr 要素の click イベントに JavaScript のリスナーをアタッチし、そのリスナーによって隠し Button をクリックします。

リスナーの作成および click イベントへのアタッチは、以下のコードのように jQuery を使うと比較的簡単にできます。

気をつけなければならないことは DOM イベントには「バブリング」というものがあることです。(バブリングの詳細については、先の記事 キャプチャリングとバブリング を見てください)

つまり、(1) tr 要素をクリック ⇒ (2) リスナーがクリックイベントを捕捉 ⇒ (3) リスナー内のメソッドが当該 tr 要素内の Button をクリック ⇒ (4) Button の click イベント発生 ⇒ (5) バブリングで tr 要素にイベントが伝播 ⇒ (6) ステップ (2) に戻る・・・と言うように無限ループになってしまうと言うことです。

この記事の例では、無限ループにならないように event.stopPropagation メソッドによりバブリングを止めました。その部分を含めたページ全体のソースコードをこの記事の下の方に記載しています。

また、実際に動かして試すことができるよう 実験室 にアップしました。興味のある方は試してみてください。

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

  // データソース用の DataTable を作成
  protected DataTable CreateDataTable()
  {
    DataTable dt = new DataTable();

    dt.Columns.Add(new DataColumn("ID", typeof(Int32)));
    dt.Columns.Add(new DataColumn("Name", typeof(string)));
    dt.Columns.Add(new DataColumn("Price", typeof(Int32)));
    dt.Columns.Add(new DataColumn("Qty", typeof(Int32)));
    dt.Columns.Add(new DataColumn("Amount", typeof(Int32)));
    dt.Columns.Add(new DataColumn("Remarks", typeof(string)));

    for (int i = 1; i < 6; i++)
    {
      DataRow dr = dt.NewRow();
      dr["ID"] = i;
      dr["Name"] = "Item " + i.ToString();
      dr["Price"] = 123000 * i;
      dr["Qty"] = i;
      dr["Amount"] = 123000 * i * i;
      dr["Remarks"] = "Remarks " + i.ToString();
      dt.Rows.Add(dr);
    }
    return dt;
  }

  protected void Page_Load(object sender, EventArgs e)
  {
    if (!Page.IsPostBack)
    {
      GridView1.DataSource = CreateDataTable();
      GridView1.DataBind();
    }
  }

  protected void Button1_Click(object sender, EventArgs e)
  {
    Label2.Text = 
      "Selected ID: " + ((Button)sender).CommandArgument;
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>WebSurfer's Page - 実験室</title>
  <script src="/scripts/jquery.js" type="text/javascript">
  </script>
  <script type="text/javascript">
  //<![CDATA[
    $(document).ready(function () {
      $("#<%=GridView1.ClientID%> tr.dataRow")
        .click(function () {

        var hiddenbutton = $(this).find("input:submit");

        // バブリングを止めないと無限ループになる。
        hiddenbutton.click(function (event) {
          event.stopPropagation();
        });

        hiddenbutton.click();
      });

      // カーソルを指型にする。
      $("#<%=GridView1.ClientID%> tr.dataRow")
        .css('cursor', 'pointer');
    });
  //]]>
  </script>
  <style type="text/css">
    .style1
    {
      display: none;
    }
    .style2
    {
      cursor: pointer;
    }
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:GridView ID="GridView1" 
      runat="server" 
      AutoGenerateColumns="False" 
      RowStyle-CssClass="dataRow">
      <Columns>
        <asp:TemplateField HeaderText="ID">
          <ItemTemplate>
            <asp:Label ID="Label1" 
              runat="server" 
              Text='<%#Eval("ID")%>'>
            </asp:Label>
            <asp:Button ID="Button1" 
              runat="server" 
              Text="Button" 
              OnClick="Button1_Click" 
              CommandArgument='<%#Eval("ID")%>' 
              CssClass="style1" />
          </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Name" HeaderText="Name" />
        <asp:BoundField DataField="Price" HeaderText="Price" />
        <asp:BoundField DataField="Qty" HeaderText="Qty" />
        <asp:BoundField DataField="Amount" HeaderText="Amount" />
        <asp:BoundField DataField="Remarks" HeaderText="Remarks" />
      </Columns>
    </asp:GridView>
    <asp:Label ID="Label2" runat="server"></asp:Label>
  </div>
  </form>
</body>
</html>

Tags: ,

ASP.NET

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年3月  >>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar