WebSurfer's Home

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

window.opener を使って PostBack

by WebSurfer 2010年11月4日 21:47
window.opener を使って PostBack

JavaScript の window.opener を利用すると、例えばページ A から window.open でページ B を開いたとすると、ページ B からページ A にポストバックをかけることが可能です。

先の記事 ModalPopup で編集・更新操作 で書いた、「一覧画面にレコード一覧を表示してユーザーに選択させ、一覧画面は開いたまま別に編集画面を開いてそこでレコードを編集してもらい、編集画面の[更新]ボタンクリックで DB を更新すると共に編集画面は閉じて、更新結果を一覧画面に反映する」というシナリオに使えます。

それを知らなかったので、先の記事では「開いたままの一覧画面に、編集画面による更新結果を反映するのは難しいです(というよりほとんど無理と思います)。」と書きましたが、そんなことはなかったです。(汗)

以下に、備忘録として例を書いておきます。

検証用に、一覧表示のための GridView を持つ親ページ (RecordList.aspx) と、編集・更新のための DetailsView を持つ子ページ (EditAndUpdate.aspx) を用いてアプリを作ってみました。手順は以下のようになります。

  1. まず親ページを要求する。
  2. 親ページは、DB からデータを取得し、GirdView にレコード一覧を表示。
  3. GridView 上のレコードを選択すると、親ページは開いたまま別ウィンドウを開いて子ページを要求。
  4. 子ページは、選択されたレコードを DB から取得し DetailsView に Edit モードで表示。
  5. 子ページでレコードを編集し、ボタンクリックでポストバックして DB を更新。同時に、親ページにポストバックをかけるための JavaScript を追加する。
  6. 子ページが再描画された時、追加した JavaScript が働いて親ページにポストバックをかける。
  7. 親ページはサーバー側で更新後のレコードを取得し GridView に表示する。
  8. 子ページを自動的に閉じる。

コードは以下のとおりです。

RecordList.aspx(親ページ)

<%@ 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">
  protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
  {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
      LinkButton lb = (LinkButton)e.Row.FindControl("LinkButton1");
      DataRowView rowView = (DataRowView)e.Row.DataItem;
      string script = String.Format(
        "javascript:window.open('EditAndUpdate.aspx?customerId={0}', " +
        "null, 'width=400, height=300'); return false;", 
        rowView["CustomerID"]);
      lb.OnClientClick = script;
    }
  }

  protected void Page_Load(object sender, EventArgs e)
  {
      if (Page.IsPostBack)
      {
          GridView1.DataBind();
      }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
  <title>一覧画面</title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <h1>一覧画面</h1>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
      ConnectionString="<%$ ConnectionStrings:Northwind %>" 
      SelectCommand=
        "SELECT [CustomerID], [CompanyName], [ContactName], 
          [ContactTitle], [Phone] 
        FROM [Customers]">
    </asp:SqlDataSource>
    <asp:GridView ID="GridView1" 
      runat="server" 
      AutoGenerateColumns="False" 
      DataKeyNames="CustomerID" 
      DataSourceID="SqlDataSource1" 
      EnableModelValidation="True" 
      OnRowDataBound="GridView1_RowDataBound"
      AllowPaging="True">
      <Columns>
        <asp:BoundField DataField="CustomerID" 
          HeaderText="CustomerID" 
          ReadOnly="True" 
          SortExpression="CustomerID" />
        <asp:BoundField DataField="CompanyName" 
          HeaderText="CompanyName" 
          SortExpression="CompanyName" />
        <asp:BoundField DataField="ContactName" 
          HeaderText="ContactName" 
          SortExpression="ContactName" />
        <asp:BoundField DataField="ContactTitle" 
          HeaderText="ContactTitle" 
          SortExpression="ContactTitle" />
        <asp:BoundField DataField="Phone" 
          HeaderText="Phone" 
          SortExpression="Phone" />
        <asp:TemplateField ShowHeader="False">
          <ItemTemplate>
            <asp:LinkButton ID="LinkButton1" 
              runat="server" 
              CausesValidation="False" 
              CommandName="Select" 
              Text="編集">
            </asp:LinkButton>
          </ItemTemplate>
        </asp:TemplateField>
      </Columns>
    </asp:GridView>
  </div>
  </form>
</body>
</html>

EditAndUpdate.aspx(子ページ)

<%@ 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 Page_Load(object sender, EventArgs e)
  {
    string customerid = Request.QueryString["customerId"];
    if (!String.IsNullOrEmpty(customerid))
    {
      DetailsView1.DefaultMode = DetailsViewMode.Edit;
      Panel1.Visible = true;
      Panel2.Visible = false;
      Label1.Text = customerid;
    }
    else
    {
      Panel1.Visible = false;
      Panel2.Visible = true;
    }
  }

  protected void  LinkButton1_Click(object sender, EventArgs e)
  {
    DetailsView1.UpdateItem(false);
    string csname = "PostBackSourceWindowScript";
    Type cstype = this.GetType();
    ClientScriptManager cs = Page.ClientScript;
    if (!cs.IsStartupScriptRegistered(cstype, csname))
    {
      String cstext =
      @"window.onload = function() {
        if (!window.opener || window.opener.closed) {
          self.close();
        }
        else {
          window.opener.document.getElementById('form1').submit();
          self.close();
        }
      };";
      cs.RegisterStartupScript(cstype, csname, cstext, true);
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
  <title>編集画面</title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:Panel ID="Panel1" runat="server">
      <h1>編集画面</h1>
      <span>
        選択された Customer ID: <asp:Label ID="Label1" runat="server" />
      </span>

      <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
        ConnectionString="<%$ ConnectionStrings:Northwind %>" 
        SelectCommand=
          "SELECT [CustomerID], [CompanyName], [ContactName], 
             [ContactTitle], [Phone] 
          FROM [Customers] 
          WHERE ([CustomerID] = @CustomerID)" 
        UpdateCommand=
          "UPDATE [Customers] 
          SET [CompanyName]=@CompanyName, [ContactName]=@ContactName, 
            [ContactTitle]=@ContactTitle, [Phone]=@Phone 
          WHERE [CustomerID] = @CustomerID">
        <SelectParameters>
          <asp:ControlParameter ControlID="Label1" 
            Name="CustomerID" 
            PropertyName="Text" 
            Type="String" />
        </SelectParameters>
        <UpdateParameters>
          <asp:Parameter Name="CompanyName" Type="String" />
          <asp:Parameter Name="ContactName" Type="String" />
          <asp:Parameter Name="ContactTitle" Type="String" />
          <asp:Parameter Name="Phone" Type="String" />
          <asp:Parameter Name="CustomerID" Type="String" />
        </UpdateParameters>
      </asp:SqlDataSource>

      <asp:DetailsView ID="DetailsView1" 
        runat="server" 
        AutoGenerateRows="False" 
        DataKeyNames="CustomerID" 
        DataSourceID="SqlDataSource2" 
        EnableModelValidation="True">
        <Fields>
          <asp:BoundField DataField="CustomerID" 
            HeaderText="CustomerID" 
            ReadOnly="True" 
            SortExpression="CustomerID" />
          <asp:BoundField DataField="CompanyName" 
            HeaderText="CompanyName" 
            SortExpression="CompanyName" />
          <asp:BoundField DataField="ContactName" 
            HeaderText="ContactName" 
            SortExpression="ContactName" />
          <asp:BoundField DataField="ContactTitle" 
            HeaderText="ContactTitle" 
            SortExpression="ContactTitle" />
          <asp:BoundField DataField="Phone" 
            HeaderText="Phone" 
            SortExpression="Phone" />
        </Fields>
      </asp:DetailsView>
      <div>
        <asp:LinkButton ID="LinkButton1" 
          runat="server" 
          onclick="LinkButton1_Click" 
          Text="Save" />
        <asp:LinkButton ID="LinkButton2" 
          runat="server"
          CausesValidation="False" 
          Text="Cancel"
          OnClientClick="self.close(); return false;" />
      </div>
    </asp:Panel>
    <asp:Panel ID="Panel2" runat="server">
      <p>クエリ文字列 customerId が指定されていません。</p>
    </asp:Panel>
  </div>
  </form>
</body>
</html>

先の記事 ModalPopup で編集・更新操作 で紹介したアプリと比べると、一覧画面の[編集]ボタンの二度押し防止と、更新された行を GirdView 上でハイライトする操作が実装できていません。解決策がないか考えてみましたが、思いつきません。というわけで、先の記事の例の方がよさそうです。

Tags: ,

ASP.NET

About this blog

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

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar