Spyros P.
Spyros P.

Reputation: 296

Dynamically adding listitems to a select tag in ASP.NET

I'm trying to do something I thought would be very simple - dynamically add some options in a select tag using ASP.NET.

I've written my code as:

<select id='cmbDuration'>
<%  Dim periods As Generic.List(Of Models.Duration) = DBSupport.getDurations
    For Each d As Models.Duration In periods
        Response.Write("<option value='" & d.id & "'>" & d.name & "</option>")        
    Next   
 %>
</select>

All is well and the data returned by my db layer appear in my select tag.

Later on, I remembered to add a runat = "Server" tag, to process my data in my code-behind post. But, after adding that, no options are displayed. Checking the resulting source code, I see no options added to it as well.

What is the problem here? Why no options are shown when runat = "Server" is added?

Upvotes: 1

Views: 3742

Answers (3)

Liam
Liam

Reputation: 29714

So, the way I understand this, is that adding the runat="Server" attribute will result in my control being available for subsequent process only in code-behind

No, adding runat="server" tells visual studio and the compiler that this control will be represented as a server control. It add's a server control into your .designer.cs file:

 /// <summary>
 /// Image3 control.
 /// </summary>
 /// <remarks>
 /// Auto-generated field.
 /// To modify move field declaration from designer file to code-behind file.
 /// </remarks>
 protected global::System.Web.UI.WebControls.Image Image3;

this process happens at design time.

Your code (everything inside the <%%>) happens at runtime. So your trying to build dynamic HTML using your code block. So the designer has no idea what your going to add, how many controls are your adding? How do I represent this? So it can't build the server side control code. So it doesn't. It also causes the runtime code to be unable to process the ViewState. Again it doesn't know what your controls are supposed to represent.

So you can't simply:

<select id='cmbDuration' runat='server'>
<%  Dim periods As Generic.List(Of Models.Duration) = DBSupport.getDurations
    For Each d As Models.Duration In periods
        Response.Write("<option value='" & d.id & "' runat='server'>" & d.name & "</option>")        
    Next   
 %>
</select>

This is simply invalid ASP.Net syntax. You can't write to the code behind at runtime in this manner. Before your for-loop is executed .Net has already built up what code behind blocks it needs, so you can't add to this.

I'm not going to repeat what @Scott has already answered but this is what you need to do.

Upvotes: 0

Scott
Scott

Reputation: 13931

Why are you talking about processing data in your code-behind post, but writing in-line code to generate list items? You should be binding your dropdown list in the code-behind:

ASP.NET

<asp:DropDown ID="cmbDuration" DataTextField="Name" DataValueField="ID" runat="server" />

CODE-BEHIND (in Page_Load)

If Not Page.IsPostBack Then
    Dim periods As Generic.List(Of Models.Duration) = DBSupport.getDurations
    cmbDuration.DataSource = periods
    cmbDuration.DataBind()
End If

Upvotes: 2

laylarenee
laylarenee

Reputation: 3284

The problem is you are writing to ASPNET's "Response Stream" by using the function Response.Write(), which will cause the output'd option tags to appear at the very very top of the page where the Response Stream is printed. This will appear even above the HTML declaration tag. (Examine your HTML source code to see) If you wish to write output directly to the ASPX page, try this:

<select id='cmbDuration'>
    <%For x As Integer = 0 To 5%>
        <option><%=x%></option>
    <%Next%>
</select>

If this helps, or not, please let me know!

Upvotes: 0

Related Questions