Demo Options:

(Click "Convert" for demo!)

toChecklist plug-in for jQuery

By Scott Horlbeck

This plug-in is now available on GitHub along with the updated documentation.

Please see the included README.md file. The documentation below will eventually be moved to the GitHub wiki

The toChecklist plug-in for jQuery will give you the functionality of a SELECT box without the need to ctrl+click items to select them. The Demo Options in the upper right show a standard HTML multi-SELECT box (annoying and difficult for average users!). Click the "Convert" button immediately below it for a quick demo of what this plug-in will do.

Introduction

The standard <select> element has a "multiple" attribute that you can set, which allows users to choose multiple items from the list. Unfortunately, the average user doesn't know that you have to hold down CTRL to select multiple items. Furthermore, you have to hold down CTRL to completely deselect everything in the list. This severely hinders the usability and usefulness of a SELECT box with the "multiple" attribute set. Furthermore, IE does not respect the "disabled" attribute on the <option> tag, making it difficult to disable items. All of this makes the multi-SELECT box a great idea in theory but a horrible idea in practice. Enter toChecklist...

Advantages

  • No need to change existing HTML.
  • Accessibility—I specifically wanted this plug-in to be as accessible as possible to users with disabilities. The ability to navigate by keyboard is excellent, especially with the search box enabled (see the side note next to "selectBox2" below). Feedback on accessibility is always appreciated, since I'm sure it's not perfect.
  • More intuitive to average users than the standard multi-SELECT box.
  • Cross-browser compatible. (Although IE7 and below is slightly less than perfect—sorry.)
  • Customizable (see Settings section below).
  • If you have a really long list, it is easy to see if something is selected in the checklist. (The left-border stays highlighted as an indicator, which is very useful for long lists). I hope to make this an optional setting in the future, but for right now you must manually edit the CSS to disable it.
  • Flexible, in the event that there are conflicts with pre-existing CSS class names.

Usage

First, make sure you have the plug-in "installed" as per the README.

To use, just create the HTML as usual, for example,

<select id="mySelectBox" multiple="multiple">
	<option>Value 1</option>
	<option>Value 2</option>
	<option>Value 3</option>
</select>
And in your js, call:
$('#mySelectBox').toChecklist();
That's it! You don't have to change any of the HTML from what it was before. Furthermore, using this plug-in allows you to disable <option> tags (e.g. <option disabled="disabled">Some option</option>) without confusing IE!

If you want, you can convert all select menus with a class of "checklist" in one jQuery call, rather than referencing them individually:

$('select.checklist').toChecklist();

Or just grab all selects with a multiple attribute

$('select[multiple]').toChecklist();

Settings

There are a number of settings that you can pass in, if you want to customize each (or every) checklist. Just pass in the settings as below.

$('select[multiple]').toChecklist({

	/**** Available settings, listed with default values. ****/

	addScrollBar : true,
	addSearchBox : false,
	animateSearch : 'normal', // Set this to false if your list is going to be really long.
	                          // (Ironically, that's why you would need a search box! Oh well.)
	                          // Otherwise, it can be set to any value that jQuery.slideUp() and
	                          // jQuery.slideDown() accept.
	searchBoxText : 'Type here to search list...',
	showCheckboxes : true,
	showSelectedItems : false,
	submitDataAsArray : true, // This one allows compatibility with languages that use arrays
	                          // to process the form data, such as PHP. Set to false if using
	                          // ColdFusion or anything else with a list-based approach.
	preferIdOverName : true, // When this is true (default) the ID of the select box is
	                         // submitted to the server as the variable containing the checked
	                         // items. Set to false to use the "name" attribute instead (this makes
	                         // it compatible with Drupal's Views module and Ruby on Rails.)
	maxNumOfSelections : -1, // If you want to limit the number of items a user can select in a
	                         // checklist, set this to a positive integer. If (somehow) the
	                         // number of preselected items in your <select> box is greater
	                         // than this number, toChecklist will still constrain it to
	                         // this amount, in order of appearance.

	// This next option is a function that gets called whenever you go over the max number of
	// allowable selections in any given checklist. 99% chance you can leave it as is, but if
	// you really like to customize, you may redefine this function to suit your needs.
	onMaxNumExceeded : function() {
		alert('You cannot select more than '+this.maxNumOfSelections+' items in this list.');
	}

	//
	// The following options were added by Claudio Nicora
	// (http://coolsoft.altervista.org)
	// There are no examples on this page, so you'll have to play around
	// with them (multicolumn select!)
	//
	listWidth : 0, // force the list width, if 0 the original SELECT width is used
	itemWidth : 0  // 0   : each item will be large as the list (single column)
	               // > 0 : each item will have a fixed size, so we could split
	               //       list into more than one column
	               // WARNING: vertical scroll bar width must be taken into account
	               // listWidth=200, itemWidth=50 DOES NOT GIVE  a 4 columns list
	               // if list scroll bar is visible

});

The above settings are the default settings. You do not need to specify them manually, unless you want something different. Therefore, if you only want to change one setting, then you only have to specify that one setting, for example:

$('select').toChecklist({
	addSearchBox : true
});

If you have showSelectedItems enabled, then you should create an empty <ul> in your HTML somewhere, and give it an id that matches the corresponding SELECT box's id, and append _selectedItems to the end of it. For example:

<select id="products">
	<option>Deodorant</option>
	<option>Soap</option>
	<option>Lotion</option>
	<!-- etc. -->
</select>

<ul id="products_selectedItems">
</ul>

The appropriate CSS class will be added to the list dynamically.

Check or Uncheck All Items

As of version 1.1.0, you can check/uncheck all items in a pre-existing checklist, or invert the selection, by passing in different actions as strings:

$('#existingChecklist').toChecklist('checkAll');

You may use 'checkAll', 'clearAll', or 'invert'.

Note that this will fail if pointing to a multi-SELECT box, or any other element that isn't already a checklist.

The 'val' method

"So how do I get the value of the checklist?"

Sadly, you cannot use jQuery's .val() method to get or set the value of the checklist, but you can use $('#checklist').toChecklist('val') instead. Currently, this is a getter only. You can use methods such as 'checkAll' or 'invert' (see above) to set some values.

isChecklist()

Version 1.1.0 also introduced the method isChecklist(), which simply returns true or false based on whether an element is a checklist created by this plug-in. IMPORTANT: Starting with version 1.6.0 I am phasing out .isChecklist() in favor of this usage instead:

$('#regularDivElement').toChecklist('isChecklist');  // Returns false
$('#regularDivElement').toChecklist('is');  // Shorthand for the above method

For the time being, it still works with the old notation of $('#elem').isChecklist() but do not use this in new development.

Styling

The plug-in grabs the original width/height of the SELECT box, so if you want to adjust the dimensions, you can do it as if you were not using the plug-in (this also helps users who don't have scripting enabled and are forced to use the original SELECT boxes): select#mySelectBox { width: 100px; height: 100px; }

or...

select { width: 100px; height: 100px; }

or...

#mySelectBox { width: 100px; height: 100px; }

Feel free to edit the stylesheet if you want to change the appearance. If you decide to change the name of one or more of the CSS classes, you will need to pass in the new name when you call the plug-in:

$('select').toChecklist({
	// Change any of the values on the right to match the classes in your stylesheet...
	cssChecklist            : 'checklist',
	cssChecklistHighlighted : 'checklistHighlighted',
	cssEven                 : 'even',
	cssOdd                  : 'odd',
	cssChecked              : 'checked',
	cssDisabled             : 'disabled',
	cssListOfSelectedItems  : 'listOfSelectedItems',
	cssFocused              : 'focused', // This is for the li's in the checklist.
	cssFindInList           : 'findInList',
	cssBlurred              : 'blurred' // This is for the search boxes, when blurred.
});

Multiple Checklists On One Page

You can have several checklists on the same page. If you want them to all appear the same, then you can select all of them at once with jQuery, e.g. $('select').toChecklist();. However, if you want to pass in options unique to each one, then reference each one individually with your jQuery selector, e.g.

$('#selectBox1').toChecklist({
	showCheckboxes : false
});

$('#selectBox2').toChecklist({
	showCheckboxes : true,
	addSearchBox : true,
	addScrollBar : false,
	maxNumOfSelections : 3
});

The above code should turn your SELECT elements into checklists similar to these ones:

selectBox1

Note that this select box also used optgroup tags in the original HTML (new in version 1.4.0).


selectBox2

Notice that we have two checklists with different options enabled. You can even search this list with scrollbars are disabled!

A brief sidenote: The search box is NOT completely pointless on checklists with no scrollbar. It allows for easier keyboard navigation. Type the first few letters (or numbers) of a checklist item into the search box, and you can tab immediately to it, press spacebar to check it, and then move immediately back to the search box with shift-tab.


Troubleshooting

Here are some tips in case you run into problems:

  • Make sure your select box has the multiple="multiple" attribute set!
  • If your site is hosted on Linux or the like, then filenames are case-sensitive, so be sure you linked to the filename correctly.
  • COLDFUSION programmers — Since version 1.2.0, this plug-in has been designed to work in a PHP environment by default. If you are running into problems with form processing on the server side, try passing in the option submitDataAsArray : false.
  • IE 7 Problems
    • As of 1.2.0, the checklist items no longer highlight themselves as you mouse over them; I have no clue why, or how to fix this. I welcome suggestions.
    • If you cannot select an item by clicking on the blank part of the list, try making sure that your parent element(s) containing the checklist doesn't have its CSS set to overflow: visible (which is often the default). Set to overflow: hidden or overflow: auto.
  • If you have addSearchBox set to true, the position property (CSS) of the resulting checklist div must be set to relative or absolute or else it will not work properly in Firefox. (Don't worry, the plug-in assigns it to relative by default, so there's a 99% chance you won't have to do this unless you're messing around with the styles significantly.)
  • If it seems like the bottom margin of the checklist is pushing the elements below it farther away than it does as a multi-SELECT box, it has to do with the CSS display property being different as a checklist (the original being display: inline and, after conversion, the checklist being set to display: block. The checklist div cannot handle being set to display: inline or else it gets messed up.
  • I haven't discovered a work-around yet, but it appears that the checklist's height gets screwed up if you enclose it in a hidden div that you later reveal using jQuery's slideDown() method. I welcome suggestions. [UPDATE: See this thread.]
  • iPhone/iPod Touch users: you can scroll the checklist by sliding two fingers across the screen inside the checklist div. Unfortunately, this is not obvious because Mobile Safari does not display the scroll bars, so you will have to design your pages with some indication that the lists do scroll for mobile users. (Or, disable the plug-in entirely for iPhone users, since Apple got the UI right in the first place!)

If this plug-in does not suit your purposes, try asmSelect (a very nice plug-in!).
If you are working on something completely unrelated, but you're having js errors in IE, read this page.

Other Problems

Please post an issue here on GitHub.