WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

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

by WebSurfer 26. March 2014 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月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  January 2021  >>
MoTuWeThFrSaSu
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

View posts in large calendar