Converting ASP.NET control check box list into drop-down check box list.
Introduction
When a developer wants to display a list of items with the ability to select some of them, there are not many options available, actually it comes to only two:
- List box
- Check box list
Both have some disadvantages.
The list box control selection is just highlighting of a row, which is visually weak type of selection, multiple selection is not intuitive and is not convenient for the end user.
Check box list has a strong visual selection type but takes a lot of space if the list is long enough.
It would be nice to use something like a drop-down list, but unfortunately the drop-down list control does not support multiple-item selection.
The combination of the drop-down list and check box list would be ideal for this purpose.
So when the time had come and the web portal that I developed required to have such selection list, I started to do my home work and look for a suitable solution on the Internet.
I found a few, but was not satisfied with the complexity and overall amount of code to implement them.
I also found a nice JQuery extension, but it was pure client side solution and I had something else in mind.
I decided to develop my own server side control.
I realized that it would be JavaScript driven, because I want to implement the client side click event to open and close the drop-down list.
My JavaScript of choice would be JQuery, which is very popular nowadays.
I also realized that CSS will be involved to style this control the way I wanted.
So the entire solution will be:
- server side control
- reference to JQuery library
- CSS(either a file of just a style tag)
- One image(an arrow down)
Server side control
Obviously this control will inherit from CheckBoxList control.
I added three public properties (Title, ImageURL, and OpenOnStart) and overrode the Render procedure.
For my convenience when rendering the control, I added the reference to JQuery library inside the Render procedure, but you can do it differently.
So this is the source:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CodeProjectWeb
{
public class CheckBoxListDropDown : CheckBoxList
{
//First row
public string Title { get; set; }
public string ImageURL { get; set; }
//Expand or hide on start
public bool OpenOnStart { get; set; }
/// Display as a dropdown list
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//default css class
if (string.IsNullOrEmpty(this.CssClass))
this.CssClass = "ddlchklst";
//first row division:
string divFirstRow = @"
<div>
{0} <img id=""{1}"" style=""float: right;"" src=""{2}"" />
</div>";
//unorder list:
string ulTag = "<ul style=\"display:{1}\" id=\"{0}\" >";
//check box:
string chkbox = "<input id=\"{0}\" name=\"{1}\" type=\"checkbox\" value=\"{2}\"{3} />";
//title for check box:
string label = "<label for=\"{0}\">{1}</label>";
string jqueryToggleFunction = @"
<script type=""text/javascript"">
$(document).ready(function () {{
$(""#{0}"").click(function () {{
$(""#{1}"").toggle(""fast"");
}});
$("".{2} li:even"").css(""background-color"", ""#efefef"")
}});
</script>";
//rendering the control:
// optionally you can place reference to jquery library here:
writer.WriteLine("<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'></script>");
writer.WriteLine(string.Format("<div class=\"{0}\">", this.CssClass));
writer.Write(string.Format(divFirstRow, this.Title + " ", base.ClientID + "_arrowDown", ImageURL));
writer.WriteLine();
writer.Indent++;
writer.WriteLine(string.Format(ulTag, base.ClientID + "_ul", OpenOnStart ? "block" : "none"));
for (int index = 0; index < Items.Count; index++)
{
writer.Indent++;
writer.WriteLine("<li>");
writer.Indent++;
writer.WriteLine(string.Format(chkbox,
base.ClientID + "_" + index.ToString(),
base.ClientID + "$" + index.ToString(),
Items[index].Value,
(Items[index].Selected ? " checked" : " ")));
writer.WriteLine(string.Format(label, base.ClientID + "_" + index.ToString(), Items[index].Text + " "));
writer.Indent--;
writer.WriteLine("</li>");
writer.WriteLine();
writer.Indent--;
}
writer.WriteLine("</ul>");
writer.WriteLine("</div>");
writer.Write(string.Format(jqueryToggleFunction, base.ClientID + "_arrowDown", base.ClientID + "_ul", this.CssClass));
}
}
}
Testing the control
ASPX page:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DropdownCheckcs.aspx.cs"
Inherits="CodeProjectWeb.DropdownCheckcs" %>
<%@ Register Assembly="CodeProjectWeb" Namespace="CodeProjectWeb" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style type="text/css">
.ddlchklst
{
width: 170px;
border:solid 1px silver;
}
.ddlchklst ul
{
margin:0;
padding:0;
border-top:solid 1px silver;
}
.ddlchklst li
{
list-style: none;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<cc1:CheckBoxListDropDown ID="ddlchklst" runat="server" Title="Select what you need" OpenOnStart="true" ImageURL="/images/DropDown.PNG">
</cc1:CheckBoxListDropDown>
</div>
<div>
<asp:Button ID="btn" runat="server" Text="Save" OnClick="btn_Click" />
</div>
</form>
</body>
</html>
Please not that you have to register the control:
<%@ Register Assembly="CodeProjectWeb" Namespace="CodeProjectWeb" TagPrefix="cc1" %>
User your own Assembly and Namespace to register.
Use the following image to display the down arrow:
Place this image into convenient location and set the ImageURL property correctly.
Also this is our CSS:
<style type="text/css">
.ddlchklst
{
width: 170px;
border:solid 1px silver;
}
.ddlchklst ul
{
margin:0;
padding:0;
border-top:solid 1px silver;
}
.ddlchklst li
{
list-style: none;
}
</style>
ASPX.cs
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CodeProjectWeb
{
public partial class DropdownCheckcs : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string[] ds = new string[] { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
this.ddlchklst.DataSource = ds;
this.ddlchklst.DataBind();
}
}
protected void btn_Click(object sender, EventArgs e)
{
foreach (ListItem li in this.ddlchklst.Items)
{
Response.Write( li.Value +": " +li.Selected.ToString() + "
");
}
}
}
}
Result
This is the result you will see when you expand the list:
Conclusion
As you can see, this control is easy to implement and you can change the way it looks by changing the Render procedure and/or CSS class.
If you like this article, please, vote for it. It is important, because it allows more programmers to utilize this code.