1

javascriptでカスタムコントロールに設定された最新のテキストを取得する必要があります。サーバーコントロールから選択したテキストを取得しようとすると、変更されたテキストではなく常にデフォルトのテキスト&が返されます。どのようにservercontrolのjavascriptによって設定された最新の値を保持するには?以下はあなたの参照のための完全なコード..です選択されたテキストasp.netカスタムサーバーコントロール

ServerControl1.cs

[assembly: WebResource("ServerControl1.Scripts.JScript1.js", "text/javascript")] 
namespace ServerControl1 
{ 
[DefaultProperty("Text")] 
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")] 
public class ServerControl1 : WebControl 
{ 
    public List<string> ListItems 
    { 
     get 
     { 
      return ViewState["items"] as List<string>; 
     } 
     set 
     { 
      ViewState["items"] = value; 
     } 
    } 

    public string Text 
    { 
     get 
     { 
      return (FindControl("middleDiv").FindControl("anchorID") as HtmlAnchor).InnerText; 
     } 
     set 
     { 
      ((FindControl("middleDiv").FindControl("anchorID") as HtmlAnchor)).InnerText = value; 
     } 
    } 

    protected override void CreateChildControls() 
    { 
     base.CreateChildControls(); 

     HtmlGenericControl selectedTextContainer = new HtmlGenericControl("div"); 
     selectedTextContainer.ClientIDMode = System.Web.UI.ClientIDMode.Static; 
     selectedTextContainer.ID = "middleDiv"; 

     HtmlAnchor selectedTextAnchor = new HtmlAnchor(); 
     selectedTextAnchor.ClientIDMode = System.Web.UI.ClientIDMode.Static; 
     selectedTextAnchor.ID = "anchorID"; 
     selectedTextAnchor.HRef = ""; 
     selectedTextContainer.Controls.Add(selectedTextAnchor); 

     HtmlGenericControl unList = new HtmlGenericControl("ul"); 

     foreach (string item in ListItems) 
     { 
      HtmlGenericControl li = new HtmlGenericControl("li"); 
      HtmlAnchor anchor = new HtmlAnchor(); 
      anchor.HRef = ""; 
      anchor.Attributes.Add("onclick", "updateData()"); 
      anchor.InnerText = item; 
      li.Controls.Add(anchor); 
      unList.Controls.Add(li); 
     } 

     selectedTextContainer.Controls.Add(unList); 
     Controls.Add(selectedTextContainer); 

     ChildControlsCreated = true; 
    } 

    protected override void OnPreRender(EventArgs e) 
    { 
     base.OnPreRender(e); 
     string resourceName = "ServerControl1.Scripts.JScript1.js"; 

     ClientScriptManager cs = this.Page.ClientScript; 
     cs.RegisterClientScriptResource(typeof(ServerControl1), resourceName); 
    } 
} 
} 

JScript1.js

function updateData() { 
var evt = window.event || arguments.callee.caller.arguments[0]; 
var target = evt.target || evt.srcElement; 
var anchor = document.getElementById("anchorID"); 
anchor.innerText = target.innerText; 
return false; 
} 

TestPage分離コード

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
    List<string> items = GetDataSource(); 
    ServerControl1.ListItems = items; 
    ServerControl1.Text = "Select .."; 
    } 
} 
protected void ClientButton_Click(object sender, EventArgs e) 
{ 
    string selectedText = ServerControl1.Text; 
} 

答えて

2

変更をPOSTしない限り、サーバーはクライアントの変更を取得しません。あなたのHtmlAnchorsは<a>のコントロールとしてHTMLでレンダリングされており、これらのタイプのコントロールはサーバーに何もPOSTしません。

サーバーに変更を入力するには、<input>コントロールが必要です(そのため、入力コントロールと呼ばれています)。私はanchor.innerTextの値を保持するために<input type=hidden>を提案し、その状態を保持します。

JavaScriptの機能を変更してanchor.innerTextを更新し、非表示の入力値も更新するようにする必要があります。このようにして、ページがサーバーにポストバックされると、非表示フィールドから更新およびクライアント変更値を取得できます。

まず、プライベートフィールドとしてselectedTextAnchorhiddenFieldを挿入する必要があります。これは、CreateChildControlsメソッドとyout Textプロパティのgetterおよびsetterでアクセスする必要があるためです。部分的なデザイナクラスは、コードビハインドで利用可能にしたいコントロールを定義する方法の大部分を占めています。

ServerControl.cs CreateChildControlsの方法では

private HtmlAnchor selectedTextAnchor; 
private HtmlInputHidden hiddenField; 

あなたが隠しフィールドを挿入する必要があります。

ClientIDMode.Staticの使用を削除したことがわかります。このモードを使用すると、クライアントコントロールが同じ固定IDを持つようになり、ServerControlの複数のコピーがページにあるときにJavascriptが混乱し、カスタムコントロールの再利用可能な目的が失われる可能性があります。

代わりに、Javascript関数に変更する必要のあるコントロールのClientIDを指定する必要があります。 ここで重要な点は、ClientIDを取得する前にコントロールをコントロールの階層にアタッチする必要があることです。

とすぐにthis.Controls.Add(dummyControl)がそうであるように、あなたはdummyControlは、ページの一部となるように作っているとそのdummyControl.ClientIDが突然あなたにそれを装着しているページの階層を反映するように変更されます。

コントロールがコントロールのコレクションにアタッチされる順番を変更して、onclick属性を作成してパラメータを渡すときにClientIDを取得できるようにし、Javascript関数が影響を受けるアンカーとhiddenFieldを知るようにしました。

ServerControl.cs

protected override void CreateChildControls() 
{ 
    base.CreateChildControls(); 

    // Instantiate the hidden input field to include 
    hiddenField = new HtmlInputHidden(); 
    hiddenField.ID = "ANCHORSTATE"; 

    // Insert the hiddenfield into the Control's Collection hierarchy 
    // to ensure that hiddenField.ClientID contains all parent's NamingContainers 
    Controls.Add(hiddenField); 

    HtmlGenericControl selectedTextContainer = new HtmlGenericControl("div"); 
    // REMOVED: selectedTextContainer.ClientIDMode = System.Web.UI.ClientIDMode.Static; 
    selectedTextContainer.ID = "middleDiv"; 

    selectedTextAnchor = new HtmlAnchor(); 
    // REMOVED: selectedTextAnchor.ClientIDMode = System.Web.UI.ClientIDMode.Static; 
    selectedTextAnchor.ID = "anchorID"; 
    selectedTextAnchor.HRef = ""; 
    selectedTextContainer.Controls.Add(selectedTextAnchor); 

    // Insert the selectedTextContainer (and its already attached selectedTextAnchor child) 
    // into the Control's Collection hierarchy 
    // to ensure that selectedTextAnchor.ClientID contains all parent's NamingContainers 
    Controls.Add(selectedTextContainer); 

    HtmlGenericControl unList = new HtmlGenericControl("ul"); 

    foreach (string item in ListItems) 
    { 
     HtmlGenericControl li = new HtmlGenericControl("li"); 
     HtmlAnchor anchor = new HtmlAnchor(); 
     anchor.HRef = ""; 

     // The updateData function is provided with parameters that will help 
     // to know who's triggering and to find the anchor and the hidden field. 
     // ClientID's are now all set and resolved at this point. 
     anchor.Attributes.Add("onclick", "updateData(this, '" + selectedTextAnchor.ClientID + "', '" + hiddenField.ClientID + "')"); 
     anchor.InnerText = item; 
     li.Controls.Add(anchor); 
     unList.Controls.Add(li); 
    } 

    selectedTextContainer.Controls.Add(unList); 
} 

にupdateData機能のキーワードthisの使用に注意してください、それがアクションをトリガーされたオブジェクトをつかむために私たちをお手伝いします。また、両方のIDが文字列(一重引用符)として渡されることにも注意してください。

Javascript関数を修正して、アンカーフィールドと非表示の入力フィールドを更新する必要があります。

JScript1.js

function updateData(sender, anchorId, hidFieldId) { 
      // Update the anchor 
      var anchor = document.getElementById(anchorId); 
      anchor.innerText = sender.innerText; 
      // Update the hidden Input Field 
      var hidField = document.getElementById(hidFieldId); 
      hidField.value = sender.innerText; 
      return false; 
     } 

行うには最後のものは、あなたが設定して、Textプロパティを取得している方法を変更します。

GETあなたがそれがポストバックかどうかをチェックする必要があるプロパティで、そうであれば、ブラウザからのすべての情報の中にあなたのHiddenInputFieldがあるかどうかをチェックする必要があります。あなたは、Requestオブジェクトで、より具体的にはRequest.Formで、クライアントから来るすべての情報を取得することができます。

Request.Form.AllKeys

あなたのページのすべての有効な入力コントロールは、Request.Formコレクションの一部となり、あなたはRequest.Form[anyInputControl.UniqueID]を使用してそれらの値を取得することができます。このオブジェクトに使用されるキーはUniqueIDであり、ClientIDではないことに注意してください。

隠し入力からクライアント変更値を取得したら、その値をselectedTextAnchorに割り当てます。それ以外の場合は元の「選択...」テキストに戻ります。

SETプロパティの場合は、selectedTextAnchorに割り当てる必要があります。

取得および設定あなたはEnsureChildControls()を呼び出す必要があり、実際には、そのプロパティの一部を取得しようとする前に、あなたのselectedTextAnchorhiddenFieldコントロールがインスタンス化されていることを確認するためにあなたのCreateChildControls()を呼ぶであろう両方。それはComposite Controlsで行われたのとほぼ同じです。

ServerControl.cs

public string Text 
{ 
    get 
    { 
     EnsureChildControls(); 
     if (this.Page.IsPostBack) 
     { 
      string HiddenFieldPostedValue = Context.Request.Form[hiddenField.UniqueID]; 
      // Assign the value recovered from hidden field to the Anchor 
      selectedTextAnchor.InnerText = HiddenFieldPostedValue; 
      return HiddenFieldPostedValue; 
     } 
     else 
     { 
      return selectedTextAnchor.InnerText; 
     } 
    } 
    set 
    { 
     EnsureChildControls(); 
     selectedTextAnchor.InnerText = value; 
    } 
} 

あなたがクライアントで行われた変更を認識して制御することができますこの方法です。あなたが彼に気付かない限り、サーバはクライアントの変更を知らないことに注意してください。

もう1つのアプローチは、ajaxリクエストでリンクをクリックするたびにサーバーに気付くことですが、これはまったく新しいコードを必要とします。

幸運を祈る!

関連する問題