Получить выбранный текст asp.net пользовательский серверный элемент управления
Мне нужно, чтобы получить последний набор текста в пользовательском элементе управления с помощью JavaScript. Когда я пытался получить выделенный текст из серверного элемента управления, он всегда возвращает текст по умолчанию, а не измененный текст. Как сохранить последнее значение, установленное JavaScript в servercontrol? Ниже приведен полный код для вашей справки.
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 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;
}
1 ответ
Сервер не получит изменения вашего клиента, если вы не отправите ему изменения. Ваши HtmlAnchors отображаются в HTML как <a>
элементы управления, и эти типы элементов управления ничего не будут размещать на сервере.
Тебе понадобится <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's.
Как только вы это сделаете this.Controls.Add(dummyControl)
, вы делаете DummyControl, чтобы стать частью страницы и ее dummyControl.ClientID
будет внезапно изменен, чтобы отразить иерархию страницы, к которой вы его прикрепляете.
Я изменил порядок, в котором ваши элементы управления присоединяются к коллекции элементов управления, чтобы мы могли получить их 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.
Когда вы получаете свойство, вам нужно проверить, является ли это постбэком, и если это так, то вы хотите проверить, есть ли среди всей информации, поступающей из браузера, ваш HiddenInputField. Вы можете получить всю информацию, поступающую от клиента, прямо в объекте Request, более конкретно, в Request.Form.
Все включенные элементы управления вводом на вашей странице будут частью коллекции Request.Form, и вы можете получить их значения, используя Request.Form[anyInputControl.UniqueID]
, Обратите внимание, что ключ, используемый для этого объекта - это UniqueID, а не ClientID.
Как только вы получите измененное клиентом значение из скрытого ввода, вы назначаете его значение selectedTextAnchor
иначе он вернется к исходному тексту "Выбрать...".
Когда вы устанавливаете свойство, вам просто нужно присвоить его 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-запроса, обращать внимание на сервер, но для этого потребуется совершенно новый код.
Удачи!