2017-01-17 14 views
0

非同期ポストバック中にフォーカスされた要素を保存するための小さなスクリプトを作成しました。完全ポストバック内でコントロールをタブで移動すると、いくつかの不思議な理由のためにがトリガーされます。ここには、作業するための簡潔なサンプルがあります:ASP.NETウェブフォームポストバックの挙動を妨げる

<%@ Page Language="C#" EnableEventValidation="false" %> 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <title></title> 
    <script runat="server"> 
     public IEnumerable<int> Measurements_GetData() 
     { 
      return new[] { 123, 328, 1099 }; 
     } 
    </script> 
</head> 
<body> 
    <form method="post" runat="server"> 
     <asp:ScriptManager runat="server" /> 
     <asp:UpdatePanel runat="server"> 
      <ContentTemplate> 
       <h1>OK</h1> 
       <div> 
        <asp:TextBox ID="Measurement1" runat="server" Text="123" AutoPostBack="true" /> 
       </div> 

       <div> 
        <asp:TextBox ID="TextBox1" runat="server" Text="328" AutoPostBack="true" /> 
       </div> 

       <div> 
        <asp:TextBox ID="TextBox2" runat="server" Text="1099" AutoPostBack="true" /> 
       </div> 

       <h1>Not OK</h1> 
       <asp:Repeater ID="Measurements" runat="server" SelectMethod="Measurements_GetData" ItemType="System.Int32"> 
        <ItemTemplate> 
        <div> 
         <asp:TextBox ID="Measurement" runat="server" AutoPostBack="true" Text="<%# Item %>" /> 
        </div> 
        </ItemTemplate> 
       </asp:Repeater> 
      </ContentTemplate> 
     </asp:UpdatePanel> 
    </form> 
    <script type="text/javascript"> 
     (function() { 
      var focusedElementId = ""; 
      var prm = Sys.WebForms.PageRequestManager.getInstance(); 

      prm.add_pageLoaded(function (source, args) { 
       // re-focus element, if any selected prior to postback 
       if (focusedElementId !== "") { 
        document.getElementById(focusedElementId).focus(); 
        console.log("focus:" + focusedElementId); 
       } 
      }); 

      prm.add_pageLoading(function (source, args) { 
       var fe = document.activeElement; 
       focusedElementId = fe !== null ? fe.id : ""; 
      }); 
     })(); 
    </script> 
</body> 
</html> 

このサンプルは、動作中と動作していない両方の動作を示しています。最初のテキストボックスをクリックすると、値を変更し、次のタブに移動し、値を変更し、次のタブに移動します。最後の要素にフォーカスが維持され、JSコンソールで保存された要素の進行が確認できます。

あなたがJSコンソールを見て、リピータで生成されたマークアップ(Not OKセクション)の最初のテキスト入力をクリックして、タブを変更してから、タブをもう一度変更すると、最後のコントロールでフォーカスが失われていることがわかります。完全なポストバックがトリガーされます(JSコンソールはクリアされます)。

ここでは何が起こっていますか?これはWebフォームのバグでなければならないように見えますが、それ以外の場合はわかりません。バグの場合、回避策はありますか?

答えて

0

これは、ASP.NET Webフォームの既知の問題です。これは、ASP.NET 4.0のClientIDModeの変更によって発生します。 MS投稿some workarounds here

あなたがコントロールの生成されたIDを気にしない場合は、最も簡単な解決策はreverting to pre-ASP.NET 4.0 behaviour by settingように表示されます。

<pages ClientIDMode="AutoID"/

web.configファイルに。

0

これはバグのようには見えませんが、JavaScript機能は何となくPostBackの原因です。完全に削除すると、TextBoxは正常に動作します。おそらく、スクリプトによってバインドされたTextBoxes(ページが最初に読み込まれたときにのみ起動される)と、非同期ポストバック後にRepeater内で再生成されたものとの間に不一致があります。

非同期ポストバックのすべてのテキストボックスを登録すると、再び機能します。

protected void Page_Load(object sender, EventArgs e) 
{ 
    foreach (RepeaterItem item in Measurements.Items) 
    { 
     TextBox tb = item.FindControl("Measurement") as TextBox; 
     ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(tb); 
    } 
} 
+0

もちろん、スクリプトなしでも動作しますが、それはこの質問のポイントです。私はJSのテキストボックスをバインドしたり、何か特別なことはしません。 page_Loadingイベントは、非同期応答が受信されると起動し、現在フォーカスされている要素のidが保存されます。次に、page_Loadedイベントが発生します(要求された最初の読み込み時にのみ) idで呼び出してfocus()を呼び出します。私は何もキャッシュしない、私は常にidによってコントロールを調べる。ここには何も特別なことはありません。それは不合理な単純なスクリプトです。回避策をありがとうございますが、これはバグではありません。 – naasking

関連する問題