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

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

By , 8 Aug 2011
 

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)

About the Author

Shameel
Architect
India India
Member
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.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGreat...professionalsumit wagh7 May '13 - 19:45 
Great...
IT WORKS Smile | :) Smile | :) Smile | :)
Questionthank youprofessionalMember 100294845 May '13 - 0:51 
Smile | :)
QuestionUnselect itemsmemberionimus200026 Mar '13 - 22:53 
Is there a way to unselect selected items using code behind? (vb.net)
GeneralMy vote of 4memberSarangzone17 Jan '13 - 4:24 
Great but works on Framework 4.0 only.
QuestionRun Code on Older versionmembervkritolia18 Jan '13 - 0:11 
I m unable to find out the changes to be made to make it work on older version . so plz help me out.....
QuestionCan I generate the drop down list (search list) at runtime ? I f dont want to populate all item on load itself?memberraju walawalkar19 Dec '12 - 18:43 
Can I generate the drop down list (search list) at runtime ? I f dont want to populate all item on load itself?
QuestionControl clears with the PostBack and on Eventsmemberkadlubek31 Oct '12 - 8:18 
Hello,
 
The Control is great, but I have some issue on adding rows on events from other controls.
I bind the DataTable :
 
...
MultiDropDown1.DataSource = dtTable2;
MultiDropDown1.DataTextField = col_name;
MultiDropDown1.DataBind();
..
 
But after that I got the MultiDropDown Control with no items but with the Search textBox.
Can You help me ?
I`m building the application on .NET Framework 4.0 and tried to set the
ViewStateMode="Enabled" on this control with no effect.
 
<MultiDropDownLib:MultiDropDown
    ID="MultiDropDown1"
    runat="server"
    DropdownOnMouseOver="true"
    TextBoxClass="textbox1"
    ImageButtonClass="imagebutton1"
    TooltipClass="tooltip1"
    DropdownClass="dropdown1"
    SelectAllAtStartup="true" ViewStateMode=Enabled
    />

BugDropdown Lists Extending in IE 8memberdinesh_5 Oct '12 - 20:06 
After a long search..i found this golden article..Thanks for posting Blush | :O Blush | :O .But the error is dropdown listed items are Extending to end of page in IE8.though I'm a noob programmer
Reply me...Sir please... Cry | :(( Cry | :((
QuestionExample who mark items code level.memberFMurgueytio23 Sep '12 - 17:37 
Anyone have any examples in C #, how to mark some items but at the code level.
 
thanks
 
Excuse me, my English is too bad...
AnswerRe: Example who mark items code level.memberFMurgueytio5 Oct '12 - 17:46 
Nadie que pueda ayudarme a marcar por código los items mostrados por este control?
Questionit can't work with reportviewer control?memberAntSmort21 Sep '12 - 0:03 
it can't work with reportviewer control?
QuestionMicrosoft JScript runtime error: 'rows' is null or not an objectmemberpptty21 Aug '12 - 15:25 
Microsoft JScript runtime error: 'rows' is null or not an object? why?
QuestionCan't Select Checkboxesmemberwesticle21 Aug '12 - 5:57 
I can't select items by selecting the checkboxes. I can only select them by clicking on the text.
 
Is this how the control is supposed to behave?
Westie

AnswerRe: Can't Select CheckboxesmemberShameel21 Aug '12 - 6:21 
I tested it in IE and Firefox and I can select by clicking on the check box as well as the text.
 
What browser do you use?
GeneralRe: Can't Select Checkboxesmemberpptty21 Aug '12 - 15:14 
you can select by text
GeneralRe: Can't Select Checkboxesmemberwesticle21 Aug '12 - 22:48 
Ahh. I can't select them in IE8 but Chrome and Firefox both work.
 
Most of my users will be on IE though and I think this is going to be a usability issue.
Westie

GeneralRe: Can't Select Checkboxesmemberwesticle22 Aug '12 - 0:57 
Ok, I've found another control that does exactly what I want and works in IE as well.
 
Thanks for your help.
Westy

GeneralRe: Can't Select Checkboxesmemberneanua28 Nov '12 - 23:21 
I have the same issue.
Which another control you found?
GeneralRe: Can't Select Checkboxesmemberwesticle29 Nov '12 - 3:25 
Turns out it didn't quite work in IE I'm afraid. Can't remember what it was called but it had some major problems so I didn't use it.
Westy

GeneralRe: Can't Select Checkboxesmemberjwaldbauer3 Jan '13 - 15:25 
I am having the same problem. It works unless I am trying to use it in a page that uses a master page in Internet Explorer. With a master page, it works in Chrome. In IE, I cannot use the check boxes, but can select with the text.
Questionset some of the item selected = true on startupmemberyadavr19 Jul '12 - 1:10 
Hi, I am using this control in one my application. Its a great control. I have a small requirement, i would like to show to user some of the items on start up. i.e. some of the items that already been selected by the user,
 
As page loads it should show the items that assigned to the list and also there check box part should also be checked.
Questionsorting the gridview based on selected checkboxesmemberjpr chaitanya7 Jun '12 - 5:09 
Hi ,
Excellent control(i have very usefull) but one small problem please give me suggistion, my problem is, I have to bind 4000 records in dropdown list(gridview), now i search the name like "j" and checked one record and clear the text and search another time like "p" and checked one record, now i have to display the checked items in top of the grid rows and search any letter <b>first display the checked items first, after display the searched letter items</b>, it is possible or not, please give me any suggestion very urgent
Questionset selected items in Dropdown on startup [modified]memberyadavr24 May '12 - 21:25 
Hi, I am not able to set some of the items on startup or on forms load. This ctrl already have an option for "SelectAllAtStartup=true/false", but what in case if i wanted to set some of the items not all at start up of the form ? where i need to change in the code? It should be something in such a way so that i can set the selected index of the items that i want to show on page startup instead of all the items.

modified 25 May '12 - 7:17.

QuestionDrop down list items clear on postback [modified]memberSubinal19 Apr '12 - 2:41 
Hi Shameel,
 
This is a great control has a great look and feel and I badly want to use this o my project. But I am facing an issue while using this. On postbacks the drop down list clears. I have tried databinding the dropdown on postbacks but still it loads with just the search text box. In essence the drop down has items only in the first load of the page. I am binding the dropdown on Page_Load and i have tried removing the IsPostback condition as well. Can you please help?
 
Jus noticed that the dropdown doesn't clear. but the list items are not being displayed. I think it has something to do with the display styling because the view source has the drop down items. Do you have any pointers?
Thanks & Regards,
Subinal


modified 19 Apr '12 - 14:04.

AnswerRe: Drop down list items clear on postbackmemberShameel19 Apr '12 - 8:33 
Hi Subinal,
 
Thanks for your feedback. The attached demo shows you a working web app that retains the list after a postback. The only way I could reproduce your issue is by setting ViewState="Disabled" on the controls.
 
It may be that ViewState is disabled at the page level and gets inherited by the controls. Try setting ViewState="Enabled" on the controls.
 
Thanks,
Shameel

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 8 Aug 2011
Article Copyright 2011 by Shameel
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid