Click here to Skip to main content
Click here to Skip to main content

MultiDropDown v2: A Multiple Selection Dropdown Control for ASP.NET

, 8 Aug 2011
Rate this:
Please Sign up or sign in to vote.
The MultiDropdown control allows selection of multiple items from a checkable list of dropdown items. The latest version allow searching items.

Introduction

The stock DropDown control that comes with ASP.NET allows us to select only one item. To overcome this limitation, I wrote the MultiDropDown ASP.NET Server Control that allows selection of multiple items from a checkable list of items. This control supports multiple instances in the same web page. The best part about this control is you do not have to add any other external files (like images, style sheets or JavaScript files) to your project, the control does everything automatically behind the scenes.

Features

  1. Supports multiple instances on the same page.
  2. Appearance of textbox, button, dropdown and tooltip can be customized.
  3. No external files like JavaScript or style sheets required. The control take care of everything.
  4. ASP.NET AJAX compliant. Works with UpdatePanel.
  5. Uses plain JavaScript. No JavaScript framework (like jQuery, mootools, etc.) required.
  6. Works with Internet Explorer, Firefox, Chrome, Opera and Safari. (Safari and Chrome do not seem to honor the dropdown's min-width property though).
  7. Just drag-n-drop to your page and start using the control.
  8. Allows searching items.

Background

I had been looking for a control that allows me to select multiple items from a drop down, after searching the Internet in vain to find one, I decided to write my own ASP.NET server control that allows selection of multiple items. The result? The MultiDropDown control.

Using the MultiDropdown Control

The control consists of a textbox, an image button and a dropdown. The default appearance of the control is:

multidropdowncontrol/mddv2-1.png

Clicking on the textbox or on the image button brings up the dropdown area.

multidropdowncontrol/mddv2-2.png

When items are selected, the textbox is automatically updated to show the comma separated list of the selected items. The selected rows are also highlighted. You can select items by clicking anywhere on the item and not just the checkbox. You can also click the 'All' item to select/unselect all items in the dropdown. The control also has a built-in tooltip that automatically shows the selected items.

As you start typing in the Search box, the list is filtered to match all the items that start with the characters you type. Clicking on the Clear Search button clears the filter and display all items.

multidropdowncontrol/mddv2-3.png

To use this control, add the MultiDropdown.dll to your Visual Studio toolbox and drag-n-drop the MultiDropdown control. You can also add a reference to the assembly and create the control directive yourself. The control directive looks like this:

<%@ Register Assembly="MultiDropDown" Namespace="MultiDropDownLib" 
	TagPrefix="MultiDropDownLib" %>

And the control instance looks like this:

<MultiDrodownLib:MultiDrodown ID="MultiDropdown1" runat="server"/> 

To add items to the control's dropdown, set its DataSource, DataTextField and DataValueField properties.

DataTable dt1 = new DataTable();
dt1.Columns.Add(new DataColumn("Name", typeof(System.String)));
dt1.Columns.Add(new DataColumn("ID", typeof(System.String)));

dt1.Rows.Add(new string[] { "Apple"     ,"1"  });
dt1.Rows.Add(new string[] { "Orange"    ,"2"  });
dt1.Rows.Add(new string[] { "Pear"      ,"3"  });
dt1.Rows.Add(new string[] { "Banana"    ,"4"  });
dt1.Rows.Add(new string[] { "Grapes"    ,"5"  });
dt1.Rows.Add(new string[] { "Strawberry","6"  });

MultiDropDown1.DataSource = dt1;
MultiDropdown1.DataTextField = "Name";
MultiDropdown1.DataValueField = "ID";

To get the list of selected items and selected values, use the SelectedItems, SelectedValues properties. The SelectedItems property is comma separated and the SelectedValues property is pipe separated.

string selectedItems = MultiDropdown1.SelectedItems;
string selectedValues = MultiDropdown1.SelectedValues;

Customizing the MultiDropDown Control

Almost every aspect of the control can be customized. Here's an instance of a customized control.

<MultiDropDownLib:MultiDropDown 
    ID="MultiDropDown2" 
    runat="server" 
    DropdownOnMouseOver="true"
    DropdownOnFocus="true"
    TextBoxClass="textbox1"
    ImageButtonClass="imagebutton1"
    TooltipClass="tooltip1" 
    DropdownClass="dropdown1"
    />

To show the dropdown just by hovering the mouse over the textbox, set the DropdownOnMouseOver property to true. This is turned off by default to avoid unnecessary intrusion of the dropdown on the page. The DropDownOnFocus property determines if the dropdown is shown when the textbox receives focus. This property is true by default.

The textbox can be customized by setting the TextBoxClass property to a custom CSS class.

.textbox1 
{ 
	border: 1px solid maroon;
	background-color:#FFC2D0;
	color:maroon;
	font-weight:bold;
}

The button can be customized by setting the ImageButtonClass property to a custom CSS class in your web project. The image is rendered as a div element to enable images to be set with a CSS class. (The image element does not allow images to be set with a CSS class.) To change the image to a custom image, set the background-image property in your CSS class to the path of the desired image file path. Be sure to set the height and width properties also.

.imagebutton1 
{
	display:block;
	background-image:url(../images/multidropdown.png);
	background-position:bottom;
	background-repeat:no-repeat;
	height:18px; 
	width:21px;
}

The dropdown can be customized by setting the DropdownClass property to a custom CSS class. However, when declaring a CSS class for the dropdown you have to declare separate classes for the td as well, like this:

.dropdown1 
{
	border: 2px solid maroon;
	min-width:150px;
}

.dropdown1 td
{
	border: 1px dotted maroon;
	background-color:#FFC2D0;
}

The tooltip's appearance can be customized by setting the TooltipClass property to a custom CSS class.

.tooltip1 {
	position:absolute;
	display:block;
	padding:2px 12px 3px 7px;
	margin-left:5px;
	background:#FFC2D0;
	color:#222222;
	border:4px solid maroon; 
	font-weight:bold;
}

Here's an example of a customized MultiDropDown control:

multidropdowncontrol/mddv2-4.png

Exploring the Source Code

The control is developed using Visual Studio 2010/.NET Framework 4.0. However, with little tweak it can be made to work with older versions of .NET. The project structure is like this:

multidropdowncontrol/mddv2-5.png

The MultiDropDown.cs file contains the ASP.NET Server Control and it inherits from System.Web.UI.WebControls.WebControl. It also implements the marker interface System.Web.UI.INamingContainer to ensure that the ASP.NET runtime assigns unique names to the child controls based on the MultiDropDown Control's Id. This helps us to write code in such a way that multiple instances of the control can be placed in the same ASP.NET Page. The control consists of a HTML Textbox (HtmlInputText), an HTML image (HtmlImage), a div element for the dropdown area (HtmlGenericControl) and an ASP.NET GridView control for the dropdown items and an Html table (HtmlTable with associated HtmlTableRow and HtmlTableCell objects) to arrange the child controls. I decided to use the GridView control instead of an HTML table to ease databinding.

The child controls are composed inside the control's class, this automatically takes care of the child control's ViewState. The child controls are initialized in the overridden OnInit() method. The CreateChildControls() method is overridden to add the child controls to the server control's Controls collection and to do the actual databinding. The OnPreRender() method is overridden to inject the link tag for the stylesheet.

The JavaScript files, the Stylesheet and the default button images are embedded inside the control assembly as WebResources. This enables the control to serve embedded resources as resources over the web. You may wish to search CodeProject to learn how to use WebResources. I'll explain how the main JavaScript file is rendered as a <script> tag in the page.

Right-click the file and select 'Properties' from the context menu and set 'Build Action' property to 'Embed Resource' in the properties window. Next, open AssemblyInfo.cs file and add this line:

[assembly: System.Web.UI.WebResource("MultiDropDownLib.js.multidropdown.js", 
	"text/javascript")]

where MultiDropDownLib is the project name and /js is the folder structure and multidropdown.js is the actual file name. Make sure you specify the precise content type. You can then use the following code to inject the JavaScript file to the web page.

Page.ClientScript.RegisterClientScriptResource(this.GetType(), 
	"MultiDropDownLib.js.multidropdown.js")

The rendered script tag will look something like this:

<script src="http://www.codeproject.com/Test/WebResource.axd?
	d=JA_U3mGno1O0AS_cetvr4oQvuwmDwmapV40Q5-daDigeJvW5b02MkDE-
	6WzvJ1qzJcIRasEbn9S-0WWjgjLSCq7jY1MMtoQe_fVrDuMLxnMX_
	Cp3ko0tZ6wmlon77boz5c3UXBvHxc0a2FZIGl-Xxw2&t=634450289371679687" 
	type="text/javascript"></script>

The other JavaScript files and the default button image are rendered in similar way.

The stylesheet is rendered using a similar technique by saving the css fie as a WebResource. An HtmlLink control is created and added to the Page's header using this code:

 protected override void OnPreRender(EventArgs e) {
    base.OnPreRender(e);
    HtmlLink linkCSS = new HtmlLink();
    linkCSS.Href = Page.ClientScript.GetWebResourceUrl(this.GetType(), 
			"MultiDropDownLib.css.multidropdown.css");
    linkCSS.Attributes.Add("rel", "stylesheet");
    linkCSS.Attributes.Add("type", "text/css");
    Page.Header.Controls.Add(linkCSS);
}

The GridView has three columns: A template column for the check box and two bound columns for the DataTextField and DataValueField properties.

  • The checkboxes in the first column (and the tr elements themselves) have an onclick event that checks/unchecks the row.
  • The second column holds the item's text and JavaScript uses this value to populated the textbox (txtNameList) with the comma separated list of items. The textbox's value is returned by the SelectedItems property.
  • The third column that holds the item's value is hidden. The JavaScript uses this column to populate the hidden control (hdnValueList) with selected values. This hidden control is used to return the list of selected values through the SelectedValues property.

Now coming to the JavaScripts, the main scripts to show/hide the dropdowns and check/uncheck items are in the multidropdown.js file. The functions ShowDropdown(), HideDropdown(), HideAllDropdowns(), SelectRow() (called from TR onclick), SelectItem() (called from Checkbox's onclick), SelectAll() do what their names suggest. A controlId parameter is passed to them that specifies the instance of the control they're supposed to work on. This enables us to place more than one instance of the control on the same ASP.NET page. The Initialize() function re-selects the selected items to restore state after a full postback or an AJAX partial postback. This function is called by code in the mddinitialize.js file. The full postback is handled by attaching the Initialize() function to window.onload event. The partial postback is handled by the predefined pageLoad(sender, args) function. The mddtooltip.js file contains the tooltip class.

Points of Interest

A single instance of the tooltip class is reused to show tooltip for all the controls on a web page. This saves us some memory and system resources and keeps the DOM footprint smaller. You may be wondering why I did not have just one instance of the dropdown and reuse it across all controls in the page, the reason is that the tooltip class is simple, you just need to change the text and the CSS class to make it work with multiple instances, whereas the dropdown portion encapsulates a complete table and it is quite difficult to make it work with multiple instances. However, this is something that could be done in future, so I am adding this to the wishlist for the time being.

Wishlist

Features that could be implemented in future:

  1. Multi-column dropdown (e.g. Names of people with their address)
  2. Design-time support
  3. Dynamic resizing of the dropdown area using mouse
  4. Customize everything about the control (including dropdown background color, selected row color, etc.)
  5. A 'Debug' mode that displays the Value column in the dropdown and the values in the tooltip to enable troubleshooting in cases where the control does not behave as expected.
  6. One dropdown for all instances of the control in a web page. (Similar to tooltip class)

I hope you will enjoy using this control as much as I enjoyed developing it. Feel free to explore the source code and make changes as you wish. If you make any significant changes to the control, I would love to hear from you about the changes you made.

If you like this control and this article, then please vote for this article, you can find the vote button just below the author profile. Please send in your comments, suggestions, likes, dislikes or whatever; I want to hear from you.

History

Version 1.0

  • The initial version

Version 2.0

  1. Search feature
  2. Minor bug fixes

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shameel
Architect
India India
I started programming in the late 90s using Visual Basic and Access, then I moved on to .NET and C#.
 
Technologies I use: VB6, COM/DCOM/ActiveX, .NET, ASP.NET, C#, VB.NET, Web Services, WCF, WF, WPF, WIF, JavaScript, HTML, XML, Microsoft Access, SQL Server, Oracle, MySQL.

Comments and Discussions

 
BugDropdown Lists Extending in IE 8 Pinmemberdinesh_5-Oct-12 20:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 8 Aug 2011
Article Copyright 2011 by Shameel
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid