Discussion on Development in Several Different Flavours

ASP.Net DropDownList annoyance

October 19, 2007 | Tagged: ,

I recently ran into a problem with using the ASP.Net DropDownList for toggling the status of an element. The problem stems from how the ASP.Net page object works. In this article I present the problem and then show a solution that seems to work with some caveats.

My goal is to create a toggle for the status of a page. For example I have a report and it has the possible status of Open or Closed. The DropDownList contains only the opposite of the current status of the report so when the report is Open the DropDownList contains an empty item (no change) and Closed. Here is the code.

<script runat="server">
  Sub Page_Load()
    If Not Page.IsPostBack Then
      Session("bool") = "Open"
    End If

    ' Setup drop down
    ddlItems.Items.Clear()
    ddlItems.Items.Add("")
    If Not Session("bool") = "Open" Then ddlItems.Items.Add("Open")
    If Not Session("bool") = "Closed" Then ddlItems.Items.Add("Closed")
  End Sub

  Sub Click_Submit(ByVal s As Object, ByVal e As EventArgs)
    If ddlItems.SelectedValue = "Open" Then
      Session("bool") = "Closed"
    ElseIf ddlItems.SelectedValue = "Open" Then
      Session("bool") = "Closed"
    End If
  End Sub
</script>

<html>
<head>
  <title>Drop Down Annoyance</title>
</head>
<body>
  <form runat="server">
  <h1>Drop Down Annoyance</h1>
  <p>Current Status: <%= Session("bool") %></p>
  <p>Update to: <asp:DropDownList ID="ddlItems" runat="server" /></p>
  <asp:Button ID="btnSubmit" Text="Update" OnClick="Click_Submit" runat="server" />
  </form>
</body>
</html>

There are two problems at work here that cause a complete failure of the intended action. Firstly, during Page_Load the Click_Submit event has not yet fired so the Session variable still contains the old value of Open. The code then rebuilds the DropDownList based on the Session variable being unchanged. Secondly, doing the change of the DropDownList resets which option is selected loosing the users input.

We can fix both of these problems with one change to the code. Simply move the DropDownList change to the very last moment right before its declaration. Make sure to add all possible options to the declaration using ListItems, this is a must for it to work.

<%@ Page Language="VB" Debug="True" %>

<script runat="server">

  Sub Page_Load()
    If Not Page.IsPostBack Then
      Session("bool") = "Open"
    End If
  End Sub

  Sub Click_Submit(ByVal s As Object, ByVal e As EventArgs)
    If ddlItems.SelectedValue = "Open" Then
      Session("bool") = "Open"
    ElseIf ddlItems.SelectedValue = "Closed" Then
      Session("bool") = "Closed"
    End If
  End Sub

</script>

<html>
<head>
  <title>Drop Down Annoyance</title>
</head>
<body>
  <form runat="server">
  <h1>Drop Down Annoyance</h1>
  <p>Current Status: <%= Session("bool") %></p>
  <%
    ' Setup drop down
    ddlItems.Items.Clear()
    ddlItems.Items.Add("")
    If Not Session("bool") = "Open" Then ddlItems.Items.Add("Open")
    If Not Session("bool") = "Closed" Then ddlItems.Items.Add("Closed")
  %>
  <p>Update to: <asp:DropDownList ID="ddlItems" runat="server">
    <asp:ListItem Text="" Selected="True" />
    <asp:ListItem Text="Open" />
    <asp:ListItem Text="Closed" />
  </asp:DropDownList></p>
  <asp:Button ID="btnSubmit" Text="Update" OnClick="Click_Submit" runat="server" />
  </form>
</body>
</html>

What is going on here is that when ASP.Net creates the ddlItems object it loads it up with all the ListItems given in the declaration. These items are available throughout the code right up until the point where we Clear and then change the DropDownList. The Session variable has been changed by this time and so everything works out. One very important caveat of this method is that you must not use ddlItems.SelectedIndex since the number of options in the list changes, instead use ddlItems.SelectedValue.

Does anybody else have any novel solutions for working with DropDownList controls?

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment