So I am having an ASP.NET page for material ordering, where the users can order components for the production of a given product. The way it is structured:
- First DropDownList lists all active production lines, using SqlDataSource
- User selects production line
- Second DropDownList lists all products being made on that production line, using SqlDataSource with a ControlParameter that is set to use the production line from the first DropDownList
- User selects product
- Third DropDownList lists all components required for that product, using SqlDataSource with a ControlParameter that is set to use the product from the second DropDownList
Below you can see how it looks:
<div class="input-group mb-3">
<asp:DropDownList ID="ProductionLine" runat="server" CssClass="form-control" AutoPostBack="true" OnSelectedIndexChanged="ProductionLine_SelectedIndexChanged">
<asp:ListItem Text="Choose a production line..." Value="" Hidden="true" />
<asp:ListItem Text="Band 45" Value="Band 45" />
<asp:ListItem Text="Band 46" Value="Band 46" />
<asp:ListItem Text="Band 47" Value="Band 47" />
<asp:ListItem Text="Band 48" Value="Band 48" />
</asp:DropDownList>
<asp:DropDownList ID="Product" runat="server" CssClass="form-control" Enabled="false" AutoPostBack="true" OnSelectedIndexChanged="Product_SelectedIndexChanged" DataSourceID="Products" DataTextField="Material" DataValueField="Material" AppendDataBoundItems="true">
<asp:ListItem Text="Choose a product..." Value="" Hidden="true" />
</asp:DropDownList>
<asp:DropDownList ID="Component" runat="server" CssClass="form-control" Enabled="false" AutoPostBack="true" OnSelectedIndexChanged="Component_SelectedIndexChanged" DataSourceID="Components" DataTextField="Component" DataValueField="Component" AppendDataBoundItems="true">
<asp:ListItem Text="Choose a component..." Value="" Hidden="true" />
</asp:DropDownList>
</div>
<asp:SqlDataSource ID="Products" runat="server" ConnectionString='<%$ ConnectionStrings:conn %>' SelectCommand="SELECT DISTINCT SUBSTRING([Material],1, 4) + '.' + SUBSTRING([Material], 5, 3) + '.' + SUBSTRING([Material], 8, 3) AS 'Material' FROM [RBBE_sl_scan_log] WHERE [ProdLine] = @ProdLine">
<SelectParameters>
<asp:ControlParameter Name="ProdLine" ControlID="ProductionLine" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="Components" runat="server" ConnectionString='<%$ ConnectionStrings:conn %>' SelectCommand="SELECT DISTINCT [Component] FROM [RBBE_sl_BOM] WHERE [Material] = @Material">
<SelectParameters>
<asp:ControlParameter Name="Material" ControlID="Product" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
This is all good so far, but I wanted to add a blank row at the start of each DropDownList in the form of "Select a production line...", "Select a product..." and "Select a component...". As you can see, I have those blank values added manually, then used AppendDataBoundItems="true" on the DropDownLists so this blank row is not removed once they get filled by the SqlDataSource.
The issue is, this way the rows from the SqlDataSource will get appended again every time the selected index of a DropDownList is changed, meaning the DropDownLists will end up with more and more options, instead of old options disappearing and new options appearing. Of course the solution to this would be to remove the AppendDataBoundItems="true" setting from the DropDownLists, but then the manually added blank row also gets removed.
In this case, what would be the best/cleanest method to keep the first blank row, while also making the DropDownLists properly rebind with new values? I know I could just add the the blank row from the code behind after databinding, but I was hoping for a more clean solution. Adding the blank row using UNION in the SQL query is also not an option, as I would like to localize the page with different languages.