I am developping an asp.net webforms application. My page is composed of 2 dropdown list.
At each selection on ddl1, I want to add dynamically via javascript the selected element of ddl1 to ddl2. By default when first loading the page, ddl1 is composed of 3 elements (a,b,c) and ddl2 is only composed of one element (a).
<script>
function ddl1_handler()
{
var ddl2 = document.getElementById("ddl2");
var newOption = document.createElement("option");
newOption.text = document.getElementById("ddl1").value;
newOption.value = document.getElementById("ddl1").value;
ddl2.add(option);
}
</script>
<asp:DropDownList ID="ddl1" runat="server" ClientIDMode="Static" onChange="ddl1_handler()">
</asp:DropDownList>
<asp:DropDownList ID="ddl2" runat="server" ClientIDMode="Static">
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click"/>
This is my code_behind code :
private List<string> choices = new List<string>() { "a", "b", "c"};
protected override void Render(HtmlTextWriter writer)
{
foreach (var choice in choices)
{
Page.ClientScript.RegisterForEventValidation(ddl2.UniqueID, choice);
}
base.Render(writer);
}
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.ddl1.Items.Clear();
foreach (var choice in choices)
{
this.ddl1.Items.Add(new ListItem(){ Text = choice, Value = choice});
}
this.ddl2.Items.Clear();
this.ddl2.Items.Add(new ListItem(){ Text = choices.First(), Value = choices.First()});
}
}
protected void Button1_Click(object sender, EventArgs e)
{
var selectedValue = this.ddl2.selectedValue;
}
With the following code, when I first load my page, my ddl1 is composed of a,b,c and my ddl2 is composed of a. I then select b on my ddl1, this element is added to my ddl2. I select this element on my ddl2 and then click on my button. But when I arrive on my button1_click handler, my selected value is still a, i don't understand.
The items inserted in client-side code are not persisted in code-behind. You could set up a mechanism involving hidden fields to get the value back but I think the easiest solution is to add the item in code-behind and use an UpdatePanel to avoid refreshing the whole page.
Here is how it could be used, showing how the update can be triggered by a control inside or outside of the panel:
Since the property
ChildrenAsTriggers
of the UpdatePanel is true by default, a selection inddl1
will update the panel. On the other hand,ddl3
will have a similar effect because it is registerd as a trigger of the UpdatePanel.The following event handler could be used by both
ddl1
andddl3
:Please note that
ClientIDMode="Static"
has been removed since it does not mix well with UpdatePanels.I included the ScriptManager declaration in the markup as a reminder, since it is required when using UpdatePanels.