Multiple Selections with Check Boxes and List Boxes
Often, we'll want to display a list of choices from which our
Displaying Multiple Selection Controls
To start the process, you must create the asp:
control within a form in the body of the HTML block. It's important that both the form and the
control must have the
<form id="MyForm" runat="server"> <asp:CheckBoxList id="chklstMyCheckList" runat="server" /> </form>
<form id="MyForm" runat="server"> <asp:ListBox id="lbxMyListBox" runat="server" SelectionMode="Multiple" /> </form>
Once the controls are on the page, populating them with data
Using Data from Multiple Selections
multiple selections, however, requires more code and planning than the data-aware controls we've worked with so far. If you don't handle multiple selections properly, your code will tend to
The correct technique is the same for CheckBoxList, ListBox, and DropDownList controls, and consists of two steps:
To assist in this task, ADO.NET allows enumeration over its list objects, which means that we can use a ForEach...In loop to test every item in the list. The syntax for the "Is this item selected?" loop could therefore be the following:
Dim strSelectionResult As String Dim liThisOne As ListItem For Each liThisOne In ckbEmployees.Items If liThisOne.Selected Then strSelectionResult &= liThisOne.Value End If
In the above code, we create a string
to hold the output of our loop - the values of the selected items,
For Each liThisOne In ckbEmployees.Items If liThisOne.Selected Then strSelectionResult &= " MyLeadingCharacters" strSelectionResult &= liThisOne.Value StrSelectionResult &= " MyFollowingCharacters" End If Next strSelectionResult = "WHERE " & strSelectionResult
Once we've looped through the choices, we must check whether any of the items were selected. This is easy to do, since the presence of a selection will result in the length of our string immediately after the loop being greater than zero. The following sample assumes that you have a DataGrid object named dgMyDataGrid, and that you only want the grid to appear if a selection has been made.
If strSelectionResult.Length > 0 Then dgMyDataGrid.Visible = True ' Work with the strSelectionResult, perhaps ' in an SQL statement to fill another grid Else dgMyDataGrid.Visible = False End If
Try It Out - Multiple Selections
We're going to create a page that lists all the Northwind
How It Works
In order of execution, what happens first is that in the
handler, a set of check boxes is
Starting with the HTML, and ignoring any formatting detail, the first thing to note is that setting the AutoPostBack attribute makes a 'submit' button unnecessary - whenever a box is checked or unchecked, the DataGrid will be repopulated. Also note that we've wired up a method called subListChange() to run whenever there is a change in the selection.
<html> ... <form runat="server"> <asp:CheckBoxList id="ckbEmployees" runat="server" ... OnSelectedIndexChanged="subListChange" AutoPostBack="True" /> <br/><br/> <asp:DataGrid id="dgEmployee" runat="server" /> </form> </body> </html>
The code that places the check boxes contains nothing new - as usual, it's wrapped in the "If Not IsPostBack" syntax to make sure that the check box list isn't repopulated after every selection. When the user clicks on a check box, the list object will trigger the SelectedIndexChanged event, which calls the subListChange() method below. In it, we build up a string of values from the selected items that will form a SQL WHERE clause for the DataGrid .
Sub subListChange(S As Object, E As EventArgs) ' Remove next line prior to deployment Response.Write("subListChange triggered<hr/>") Dim strWhereClause As String = "" Dim liThisOne As ListItem For Each liThisOne in ckbEmployees.Items If liThisOne.Selected Then strWhereClause &= "EmployeeID=" & liThisOne.Value & " OR " End If Next
Clearly, it's possible that there will be no selection at all, if the user's action was to uncheck the only checked box. To deal with this, we take a look at the length of the string holding the WHERE clause. If selections were made, then we execute all of the connection, command and binding code for the DataGrid object.
' Remove next line prior to deployment Response.Write("strWhereClause = <br/>" & strWhereClause & "<hr/>") If strWhereClause.Length > 0 Then dgEmployee.Visible = True ' This line removes the final ' OR ' from the WHERE clause strWhereClause = Left(strWhereClause, strWhereClause.Length - 4) strWhereClause = "WHERE " & strWhereClause Dim strConnection As String = ConfigurationSettings.AppSettings("NWind") Dim strSQLforGrid As String = "SELECT TitleOfCourtesy, FirstName, " & _ "LastName, Country, Region, City, Notes " & _ "FROM Employees " & strWhereClause Dim objConnection As New SqlConnection(strConnection) Dim objCommand As New SqlCommand(strSQLforGrid, objConnection) ' Remove next line prior to deployment Response.Write("strSQLforGrid = <br/>" & strSQLforGrid & "<hr/>") objConnection.Open() dgEmployee.DataSource = objCommand.ExecuteReader() dgEmployee.DataBind() objConnection.Close()
If the check box list contained no selections, then we can just hide the DataGrid, keeping the page neat and tidy.
Else dgEmployee.Visible = False End If
This works quite