WebSurfer's Home

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

IE8 と traget frame

by WebSurfer 2010年8月24日 22:42

IE7 では問題なかった異なるウィンドウの target frame への表示が、IE8 ではうまくいきません。<=(やり方の問題でした。下の方に書いた追記参照)

親ウィンドウの iframe に子ウィンドウの更新結果を表示

確証はありませんが、IE8 では異なるウィンドウはプロセスが異なることが原因のように思われます。

GridView と iframe をもつ親ページ (Parent.aspx)、DetailsView を持つ子ページ (Child.aspx) を例にとって、シナリオを説明します。

  1. 親ウィンドウを開き Parent.aspx を要求。
  2. Parent.aspx は、DB からデータを取得し、GirdView にレコード一覧を表示。
  3. GridView 上でレコードを選択すると、親ウィンドウは開いたまま、子ウィンドウを開いて Child.aspx を要求。
  4. Child.aspx は、選択されたレコードの詳細を DetailsView に Edit モードで表示。
  5. 子ウィンドウでレコードを編集し、ボタンクリックで Child.aspx にポストバックして DB を更新。
  6. Child.aspx は、ReadOnly モードの DetailsView の形で、更新後のレコードを応答。
  7. Child.aspx の応答を、開いたままの親ウィンドウの Parent.aspx の iframe に表示。
  8. 子ウィンドウを閉じる。

問題は、上記 7 の、親ウィンドウを開いたままにしておいて、その iframe に子ウィンドウで行った更新結果を表示するところです。

これは、Parent.aspx の iframe の name を、Child.aspx の form 要素の target に設定するということで可能なはずです。

しかしながら、IE8 では新たに別ウィンドウが開いてそれに Child.aspx が表示され、target としたはずの iframe には何も表示されません。

以前 IE7 で試した時はうまくいきました(今は環境がないので試せませんが、間違いないです)。Firefox 3.6.8, Opera 10.61(この時点での最新版)は、以前と同様、期待通りに動きます。

どうも IE8 では、親ウィンドウと子ウィンドウのプロセスが違うということが問題のようです。つまり、親ウィンドウの iframe の name を、子ウィンドウのプロセスが認識できず、そのような名前の iframe はないと判断されるので、新たに別ウィンドウを開いて Child.aspx を表示するのではないかと思います。

ただ、ググって見ても上記のような話は見当たらないので、ひょっとして何か思い違いをしている可能性はゼロではなさそうですけど。(汗)

検証に使ったサンプルも書いておきます。DB は Microsoft が提供しているサンプル、Northwind の Employee テーブルを使用しています。

Parent.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)
    {
      Button btn = (Button)e.Row.FindControl("Button1");
      int id = (int)((DataRowView)e.Row.DataItem)["EmployeeID"];
      btn.OnClientClick = 
        "javascript:window.open('042_Child.aspx?employeeid=" + 
        id.ToString() + "&mode=edit', null, " + 
        "'menubar=no, scrollbars=yes, status=no, width=500, height=600'); " + 
        "return false;";            
    }          
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:Northwind %>" 
        SelectCommand=
          "SELECT EmployeeID, LastName + ' ' + FirstName AS Name 
           FROM Employees">
      </asp:SqlDataSource>
      <asp:GridView ID="GridView1" 
        runat="server" 
        AutoGenerateColumns="False" 
        DataKeyNames="EmployeeID" 
        DataSourceID="SqlDataSource1" 
        EnableModelValidation="True" 
        OnRowDataBound="GridView1_RowDataBound">
        <Columns>
          <asp:BoundField DataField="EmployeeID" 
            HeaderText="ID" 
            InsertVisible="False" 
            ReadOnly="True" 
            SortExpression="EmployeeID" />
          <asp:BoundField DataField="Name" 
            HeaderText="名前" 
            ReadOnly="True" 
            SortExpression="Name" />
          <asp:TemplateField HeaderText="選択">
            <ItemTemplate>
              <asp:Button ID="Button1" 
                runat="server" 
                CommandName="Select" 
                Text="Select" />
            </ItemTemplate>
          </asp:TemplateField>
        </Columns>
      </asp:GridView>
    </div>
    <hr />
    <iframe name="DetailedList" height="450px" width="350px">
    </iframe>
  </form>
</body>
</html>
Child.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 employeeid = Request.QueryString["employeeid"];
    string mode = Request.QueryString["mode"];
        
    if (Page.IsPostBack)
    {
      mode = "readonly";
    }

    if (!String.IsNullOrEmpty(employeeid) && 
      !String.IsNullOrEmpty(mode))
    {
      Panel1.Visible = true;
      Panel2.Visible = false;
      Label1.Text = employeeid;
            
      if (mode == "edit")
      {                
        DetailsView1.DefaultMode = DetailsViewMode.Edit;
        ((Button)DetailsView1.FindControl("Button1")).OnClientClick =
          "javascript:setTimeout('self.close()', 100);";
        ((Button)DetailsView1.FindControl("Button2")).OnClientClick =
          "self.close(); return false;";
      }
      else
      {
        DetailsView1.DefaultMode = DetailsViewMode.ReadOnly;
      }
    }
    else
    {
      Panel1.Visible = false;
      Panel2.Visible = true;
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" target="DetailedList" runat="server">
    <asp:Panel ID="Panel1" runat="server">
      <h1>詳細表示</h1>
      <span>
        選択された Employee ID: <asp:Label ID="Label1" runat="server" />
      </span>
      <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:Northwind %>" 
        SelectCommand=
         "SELECT [EmployeeID], [LastName], [FirstName], [Title], 
            [TitleOfCourtesy], [Address], [City], [Region], 
            [PostalCode], [Country], [HomePhone] 
          FROM [Employees] 
          WHERE ([EmployeeID] = @EmployeeID)" 
        UpdateCommand=
         "UPDATE [Employees] 
          SET [LastName] = @LastName, [FirstName] = @FirstName, 
            [Title] = @Title, [TitleOfCourtesy] = @TitleOfCourtesy, 
            [Address] = @Address, [City] = @City, [Region] = @Region, 
            [PostalCode] = @PostalCode, [Country] = @Country, 
            [HomePhone] = @HomePhone 
          WHERE [EmployeeID] = @EmployeeID" >
        <SelectParameters>
          <asp:ControlParameter ControlID="Label1" 
            Name="EmployeeID" 
            PropertyName="Text" 
            Type="Int32" />
        </SelectParameters>
        <UpdateParameters>
          <asp:Parameter Name="LastName" Type="String" />
          <asp:Parameter Name="FirstName" Type="String" />
          <asp:Parameter Name="Title" Type="String" />
          <asp:Parameter Name="TitleOfCourtesy" Type="String" />
          <asp:Parameter Name="Address" Type="String" />
          <asp:Parameter Name="City" Type="String" />
          <asp:Parameter Name="Region" Type="String" />
          <asp:Parameter Name="PostalCode" Type="String" />
          <asp:Parameter Name="Country" Type="String" />
          <asp:Parameter Name="HomePhone" Type="String" />
          <asp:Parameter Name="EmployeeID" Type="Int32" />
        </UpdateParameters>
      </asp:SqlDataSource>
      <asp:DetailsView ID="DetailsView1" 
        runat="server" 
        AutoGenerateRows="False" 
        DataKeyNames="EmployeeID" 
        DataSourceID="SqlDataSource1" 
        EnableModelValidation="True">
        <Fields>
          <asp:BoundField DataField="EmployeeID" 
            HeaderText="EmployeeID" 
            InsertVisible="False" 
            ReadOnly="True" 
            SortExpression="EmployeeID" />
          <asp:BoundField DataField="LastName" 
            HeaderText="LastName" 
            SortExpression="LastName" />
          <asp:BoundField DataField="FirstName" 
            HeaderText="FirstName" 
            SortExpression="FirstName" />
          <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
          <asp:BoundField DataField="TitleOfCourtesy" 
            HeaderText="TitleOfCourtesy" 
            SortExpression="TitleOfCourtesy" />
          <asp:BoundField DataField="Address" 
            HeaderText="Address" 
            SortExpression="Address" />
          <asp:BoundField DataField="City" 
            HeaderText="City" 
            SortExpression="City" />
          <asp:BoundField DataField="Region" 
            HeaderText="Region" 
            SortExpression="Region" />
          <asp:BoundField DataField="PostalCode" 
            HeaderText="PostalCode" 
            SortExpression="PostalCode" />
          <asp:BoundField DataField="Country" 
            HeaderText="Country" 
            SortExpression="Country" />
          <asp:BoundField DataField="HomePhone" 
            HeaderText="HomePhone" 
            SortExpression="HomePhone" />          
          <asp:TemplateField ShowHeader="False">
            <EditItemTemplate>
              <asp:Button ID="Button1" 
                runat="server" 
                CausesValidation="True" 
                CommandName="Update" 
                Text="更新">
              </asp:Button>
               
              <asp:Button ID="Button2" 
                runat="server" 
                CausesValidation="False" 
                CommandName="Cancel" 
                Text="キャンセル">
              </asp:Button>
            </EditItemTemplate>
          </asp:TemplateField>          
        </Fields>
      </asp:DetailsView>
    </asp:Panel>
    <asp:Panel ID="Panel2" runat="server">
      <p>クエリ文字列 employeeid または mode が指定されていません。</p>
    </asp:Panel>
  </form>
</body>
</html>

---------- 2010/8/29 追記 ----------

思い違いというか、やり方の問題でした。

Visual Studio で、[デバッグ] → [デバッグ開始] または [デバッグなしで開始] で IE8 を起動して試していたのでダメでした。

普通に IE8 を起動して、アドレスバーに url を直打ちして試したら、期待通り子ウィンドウのポストバック結果が親ウィンドウの iframe に表示されました。

お騒がせしましたが、違うことが認識できて、一つ利口(?)になったということで・・・(苦笑)

でも、何で違うんでしょう???

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