1

Je dois obtenir le dernier jeu de texte dans le contrôle personnalisé par javascript. Lorsque j'ai essayé d'obtenir le texte sélectionné à partir du contrôle du serveur, il renvoie toujours le texte par défaut & pas le texte modifié. Comment conserver la dernière valeur définie par le javascript dans servercontrol? Ci-dessous le code complet pour votre référence ..Get Selected Text Commande de serveur personnalisé 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; 
} 

PageTest 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; 
} 

Répondre

2

Le serveur n'obtiendra pas les modifications de votre client à moins que vous POST les modifications à lui. Vos HtmlAnchors sont rendus en HTML en tant que contrôles <a>, et ces types de contrôles ne POSTENT rien au serveur.

Vous aurez besoin d'un contrôle <input> pour entrer les changements dans le serveur (c'est pourquoi ils sont appelés contrôles d'entrée après tout). Je suggère un <input type=hidden> pour maintenir la valeur du anchor.innerText et garde son état.

Votre fonction Javascript doit être modifiée pour mettre à jour le anchor.innerText ET met également à jour la valeur d'entrée masquée. De cette façon, lorsque la page est renvoyée au serveur, vous pouvez récupérer la valeur mise à jour et modifiée par le client dans le champ masqué.

D'abord, vous devez définir comme champs privés votre selectedTextAnchor et le hiddenField que vous allez insérer. C'est parce que vous devez y accéder dans votre méthode CreateChildControls ainsi que dans la propriété getter et setter de yout Text. Une grande partie de la manière dont les classes de concepteurs partielles définissent les contrôles que vous voulez avoir dans le code-behind.

ServerControl.cs

private HtmlAnchor selectedTextAnchor; 
private HtmlInputHidden hiddenField; 

Dans la méthode CreateChildControls vous devez insérer le champ caché.

Vous remarquerez que j'ai supprimé l'utilisation de ClientIDMode.Static. L'utilisation de ce mode rendrait vos contrôles clients ayant les mêmes identifiants fixes et Javascript pourrait être confus lorsque vous avez plusieurs copies de votre ServerControl dans une page, perdant ainsi le but réutilisable d'un contrôle personnalisé.

Au lieu de cela, vous devez fournir votre fonction JavaScript avec les ID client des contrôles qu'il doit modifier. La clé ici est que vous devez attacher vos contrôles à la hiérarchie du contrôle AVANT d'essayer d'obtenir leur ID client.

Dès que vous this.Controls.Add(dummyControl), vous faites dummyControl pour devenir une partie de la page et son dummyControl.ClientID sera soudainement changé pour refléter la hiérarchie de la page que vous attacher dans.

J'ai modifié l'ordre dans lequel vos contrôles sont attachés à la collection du contrôle afin que nous puissions récupérer leurs identifiants clients au moment où nous construisons l'attribut onclick et transmettons les paramètres afin que votre fonction Javascript sache quels anchor et hiddenField affecter.

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); 
} 

Notez l'utilisation du mot-clé this dans la fonction updateData, ça va nous aider à saisir l'objet qui déclenche l'action. Notez également que les deux Id sont passés en tant que chaînes (avec des guillemets simples)

La fonction Javascript devrait être modifiée afin de mettre à jour l'ancre et le champ d'entrée caché.

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; 
     } 

La dernière chose à faire est de changer la façon dont vous définissez et obtenir votre propriété Text.

Lorsque vous GET la propriété dont vous avez besoin de vérifier s'il s'agit d'un postback, et si elle est, alors vous voulez vérifier si parmi toutes les informations qui proviennent du navigateur, il est votre HiddenInputField. Vous pouvez récupérer toutes les informations provenant du client directement sur l'objet Request, plus précisément dans Request.Form.

Request.Form.AllKeys

Tous les contrôles d'entrée activés sur votre page feront partie de la collection Request.Form, et vous pouvez obtenir leurs valeurs à l'aide Request.Form[anyInputControl.UniqueID]. Notez que la clé utilisée pour cet objet est UniqueID, NOT ClientID. Une fois que vous obtenez votre valeur modifiée par le client à partir de l'entrée cachée, vous affectez sa valeur au selectedTextAnchor, sinon elle reviendra au texte original "Sélectionner ...".

Lorsque vous SET la propriété, il vous suffit de l'affecter à la selectedTextAnchor.

Dans les deux GET et SET vous devez appeler EnsureChildControls(), qui fait appel à votre CreateChildControls() pour vous assurer que vos selectedTextAnchor et hiddenField contrôles sont instanciés avant d'essayer d'obtenir certaines de leurs propriétés. Pratiquement de la même manière que cela est fait en 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; 
    } 
} 

De cette façon, vous pouvez avoir un contrôle qui reconnaît les modifications apportées au client. Rappelez-vous que le serveur ne connaîtra aucun changement de client à moins que vous ne le remarquiez.

Une autre approche consisterait à remarquer le serveur chaque fois que vous cliquez sur un lien via une requête ajax, mais cela nécessiterait un tout nouveau code différent.

Bonne chance!

Questions connexes