[2.0 + Ajax] Ajouter dynamiquement des TextBox à un PlaceHolder qui en contient déjà
Bonjour,
Je vous explique le topo : j'ai un TreeView. Lorsque l'on clique sur un de ses noms, un certain nombre d'informations le concernant sont récupérées dans le fichier XML source pour être affichées, notamment ses noeuds enfants. Ceux-ci peuvent être d'un nombre "très" variable, donc je dois les ajouter dans un PlaceHolder dynamiquement.
Par la suite je souhaite que l'utilisateur puisse cliquer sur un bouton "PLUS" afin de faire apparaitre autant de TextBox supplémentaires qu'il le souhaite, afin d'y saisir des informations et finalement les enregistrer dans le fichier XML source.
Je ne vous cache pas que tous ces besoins créent un beau pataquès dès qu'il s'agit de créer la logique de PostBack.
J'ai trouvé cette vidéo de Joe Stagner, qui m'a vaguement aidé, mais évidemment mes besoins sont légèrement différents de ce qu'il y explique.
Voilà où j'en suis niveau code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <asp:XmlDataSource ID="XmlDataSourceGeo" runat="server" DataFile="~/App_Data/thesaurus-Geographique-Sample.xml"
XPath="/thesaurus/*" CacheExpirationPolicy="Sliding" CacheDuration="60" />
<asp:TreeView ID="TreeViewGeo" runat="server" DataSourceID="XmlDataSourceGeo" ExpandDepth="0" ShowLines="true" SkipLinkText="" OnSelectedNodeChanged="TreeViewGeo_SelectedNodeChanged"
OnTreeNodeDataBound="TreeViewGeo_DataBound">
<DataBindings>
<asp:TreeNodeBinding DataMember="retenu" ValueField="id" TextField="terme" />
<asp:TreeNodeBinding DataMember="EP" TextField="terme" FormatString="Employé pour : {0}" SelectAction="None" />
</DataBindings>
</asp:TreeView>
<table><tr><td>
<asp:UpdatePanel ID="UpdatePanelEP" runat="server">
<ContentTemplate>
<asp:PlaceHolder ID="PlaceHolderEP" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="BoutonPlusEP" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</td>
<td>
<asp:ImageButton ID="BoutonPlusEP" runat="server" ImageUrl="~/images/plus.gif" OnClick="BoutonPlusEP_Click" />
</td></tr></table> |
Et surtout côté code behind :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| using System;
using System.Data;
using System.Xml;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
public partial class _Default : System.Web.UI.Page
{
static XmlDocument xmlDoc = new XmlDocument();
static int nbTextBoxEP = 0;
private TextBox[] textBoxEP;
protected void Page_PreInit(object sender, EventArgs e)
{
Control monControl = GetPostBackControl(this.Page);
if ((monControl != null))
{
if ((monControl.ClientID.ToString() == "BoutonPlusEP"))
{
nbTextBoxEP++;
}
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
textBoxEP = new TextBox[nbTextBoxEP];
for (int i = 0; i < nbTextBoxEP; i++)
{
TextBox textBox = new TextBox();
textBox.ID = "TextBoxEP" + i;
textBox.CssClass = "TextBoxEP";
PlaceHolderEP.Controls.Add(textBox);
textBoxEP[i] = textBox;
}
}
protected void Page_Load(object sender, EventArgs e)
{
xmlDoc.Load(Server.MapPath("~/App_Data/thesaurus-Geographique-Sample.xml"));
//TreeViewGeo.Nodes.Clear();
//foreach (XmlNode noeudRetenu in xmlDoc.DocumentElement.SelectNodes("retenu"))
//{
// AddNode(noeudRetenu, TreeViewGeo.Nodes);
//}
//TreeViewGeo.CollapseAll();
}
//protected void AddNode(XmlNode noeud, TreeNodeCollection collecNoeuds)
//{
// collecNoeuds.Add(new TreeNode(noeud.Attributes["terme"].Value, noeud.Attributes["id"].Value));
// TreeNode newNoeud = collecNoeuds[collecNoeuds.Count - 1];
// if (noeud.HasChildNodes)
// {
// foreach (XmlNode noeudEnfant in noeud.SelectNodes("retenu"))
// AddNode(noeudEnfant, newNoeud.ChildNodes);
// }
//}
public static Control GetPostBackControl(Page maPage)
{
Control monControl = null;
string nomControl = maPage.Request.Params.Get("__EVENTTARGET");
if (((nomControl != null) && (nomControl != string.Empty)))
{
monControl = maPage.FindControl(nomControl);
}
else
{
foreach (string control in maPage.Request.Form)
{
Control testControl = maPage.FindControl(control);
if (testControl is Button)
{
monControl = testControl;
}
}
}
return monControl;
}
protected void TreeViewGeo_DataBound(object sender, TreeNodeEventArgs e)
{
if (e.Node.Text.StartsWith("Employé pour : "))
e.Node.Text = "<span style=\"color: #CF4DCF\">" + e.Node.Text + "</span>";
}
protected void TreeViewGeo_SelectedNodeChanged(object sender, EventArgs e)
{
TableInfos.Style.Add("display", "");
if (TreeViewGeo.SelectedNode.Parent != null)
LabelParent.Text = TreeViewGeo.SelectedNode.Parent.Text;
TextBoxRetenu.Text = TreeViewGeo.SelectedNode.Text;
XmlNodeList noeudsEP = xmlDoc.SelectSingleNode(TreeViewGeo.SelectedNode.DataPath).SelectNodes("EP");
nbTextBoxEP = noeudsEP.Count;
for (int i = 0; i < noeudsEP.Count; i++)
{
TextBox TextBoxEP = new TextBox();
TextBoxEP.ID = "TextBoxEP" + i;
TextBoxEP.CssClass = "TextBoxEP";
TextBoxEP.Text = noeudsEP[i].Attributes["terme"].Value;
PlaceHolderEP.Controls.Add(TextBoxEP);
}
}
protected void BoutonPlusEP_Click(object sender, EventArgs e)
{
//TextBox TextBoxEP = new TextBox();
//TextBoxEP.ID = "TextBoxEP" + PlaceHolderEP.Controls.Count;
//TextBoxEP.CssClass = "TextBoxEP";
//PlaceHolderEP.Controls.Add(TextBoxEP);
//TextBoxEP.Focus();
}
protected void BoutonSauv_Click(object sender, EventArgs e)
{
foreach (TextBox textBox in textBoxEP)
{
Response.Write(textBox.Text);
}
}
} |
Un problème qui se pose est que Joe Stagner montre comment ajouter les TextBox au moment de l'évènement OnInit de la page, mais il semble aussi qu'à ce moment là je ne peux pas déterminer quel est le nœud sélectionné dans le TreeView, et donc récupérer les infos dans le fichier XML (notamment le nombre de nœuds enfants).
De plus, lorsque l'on clique sur le bouton "PLUS", pour l'instant cela n'ajoute dans le meilleur des cas qu'une seule TextBox, pas plus...
Je suis désolé je me rends compte que mon code n'est sans doute pas très facile à lire et mon cas assez complexe à résoudre, mais je ne vois pas trop comment faire mieux. Peut-être en vous envoyant le code source s'il y a des volontaires.;)
Merci d'avance pour vos suggestions.