1

Мне нужно получить последний текст, заданный в пользовательском элементе управления, с помощью javascript. Когда я пытался получить выделенный текст с сервера, он всегда возвращает текст по умолчанию &, а не измененный текст. Как сохранить последнее значение, установленное javascript в servercontrol? Ниже приведен полный код для справки ..Получить выбранный текстовый пользовательский контроль 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; 
} 

Codebehind тестовую страницу

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

Сервер не получит изменения вашего клиента, если вы не внесете в него изменения. Ваши HtmlAnchors отображаются в HTML как элементы управления <a>, и эти типы элементов управления не будут отправлять POST на сервер.

Вам понадобится элемент управления <input> для внесения изменений на сервер (поэтому все они называются элементами управления вводом). Я предлагаю <input type=hidden> для хранения значения anchor.innerText и сохраняет его состояние.

Ваша функция Javascript должна быть изменена, чтобы она обновляла anchor.innerText И обновляла также скрытое входное значение. Таким образом, когда страница будет отправлена ​​обратно на сервер, вы можете получить обновленное и измененное клиентом значение из скрытого поля.

Сначала вы должны определить как частные поля свои selectedTextAnchor и hiddenField, которые вы собираетесь вставить. Это связано с тем, что вам необходимо получить к ним доступ в вашем методе CreateChildControls, а также в getter и setter свойства yout Text. Многое в том, как частичные классы дизайнеров определяют элементы управления, которые вы хотите иметь в коде.

ServerControl.cs

private HtmlAnchor selectedTextAnchor; 
private HtmlInputHidden hiddenField; 

В методе CreateChildControls вам нужно вставить скрытое поле.

Вы заметите, что я удалил использование ClientIDMode.Static. Использование этого режима заставит ваши клиентские элементы управления иметь одинаковые фиксированные идентификаторы, а Javascript может запутаться, когда у вас будет несколько копий вашего ServerControl на странице и, таким образом, потеряете многоразовую цель настраиваемого элемента управления.

Вместо этого вам необходимо предоставить функцию Javascript с идентификаторами ClientID элементов управления, которые необходимо изменить. Ключ здесь в том, что вам нужно прикрепить свои элементы управления к иерархии элемента управления, прежде чем пытаться получить их идентификаторы ClientID.

Как только вы this.Controls.Add(dummyControl), вы делаете dummyControl стать частью страницы и его dummyControl.ClientID будет внезапно изменен, чтобы отразить иерархию страницы вы прикрепляя его в.

Я изменил порядок, в котором элементы управления прикреплены к коллекции Control, чтобы мы могли захватить их ClientID в момент создания атрибута onclick и передать параметры, чтобы ваша функция 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); 
} 

Обратите внимание на использование ключевого слова this в функции UpdateData, это поможет нам захватить объект, инициирующее действие. Также обратите внимание, что оба идентификатора передаются как строки (с одинарными кавычками)

Функция 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.

Когда вы ПОЛУЧИТЬ недвижимость, которую нужно проверить, если это Postback, и если это так, то вы хотите, чтобы проверить, если среди всю информацию, которая приходит из браузера есть ваш HiddenInputField. Вы можете получить всю информацию, поступающую от клиента прямо на объекте Request, а точнее в Request.Form.

Request.Form.AllKeys

Все включенные входные элементы управления на странице будет частью коллекции Request.Form, и вы можете получить их значения с помощью Request.Form[anyInputControl.UniqueID]. Обратите внимание, что ключ, используемый для этого объекта, - UniqueID, NOT ClientID.

После того, как вы получите измененное клиентом значение со скрытого ввода, вы назначаете его значение selectedTextAnchor, в противном случае оно вернется к исходному тексту «Выбрать ...».

Если у вас SET недвижимости, вам просто нужно назначить ее selectedTextAnchor.

В как GET и SET вам нужно вызвать EnsureChildControls(), который будет на самом деле назвать ваш CreateChildControls(), чтобы убедиться, что ваши selectedTextAnchor и hiddenField управления инстанцируются, прежде чем попытаться получить некоторые их свойства. Совсем так же, как это делается в 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; 
    } 
} 

Таким образом, вы можете иметь контроль, который распознает изменения, внесенные в клиенте. Помните, что сервер не будет знать никаких изменений в клиенте, если вы его не заметите.

Другой подход - заметить сервер при каждом нажатии ссылки через запрос ajax, но для этого потребуется совершенно новый код.

Удачи вам!

Смежные вопросы