Multiple select with checkboxes and jQuery

Updated 17 April 2012

A recent project that we worked on required a <select> element that allowed multiple selections. An example is shown below:

 

The advantages

This allows more than one option to be selected if the user holds down the modifier key (the CTRL key in Windows) whilst making their selection. The depth of the select element can also be limited if the list is very long, although generally you’d want more than one option on display.

The disadvantages

However, there did seem to be a couple of disadvantages. Firstly, not all users would be aware of the modifier key or how to use it. Secondly, pre-selected values could inadvertently be unselected if the user makes additional choices without holding down the modifier key. If several options are pre-selected when the page loads this could prove to be a nightmare for the user to untangle.

The solution

Replacing the select element with checkboxes seemed like the obvious choice, but this would take up more space on the screen and potentially look messy. The solution? Checkboxes that are styled to look like somewhat like a multiple select element.

First of all we changed the select element into a series of checkboxes, wrapped in a div with an appropriate class name:

<div class="multiselect">
	<label><input type="checkbox" name="option[]" value="1" />Green</label>
	<label><input type="checkbox" name="option[]" value="2" />Red</label>
	<label><input type="checkbox" name="option[]" value="3" />Blue</label>
	<label><input type="checkbox" name="option[]" value="4" />Orange</label>
	<label><input type="checkbox" name="option[]" value="5" />Purple</label>
	<label><input type="checkbox" name="option[]" value="6" />Black</label>
	<label><input type="checkbox" name="option[]" value="7" />White</label>
</div>

Next we apply some CSS styling to give the desired effect:

.multiselect {
	width:20em;
	height:15em;
	border:solid 1px #c0c0c0;
	overflow:auto;
}

.multiselect label {
	display:block;
}

.multiselect-on {
	color:#ffffff;
	background-color:#000099;
}

The final touch

We can extend this idea using jQuery to highlight the selections. We should of course highlight pre-selected checkboxes when the page first loads, as well as selections that the user makes afterwards. Here’s a function that we knocked together for this purpose:

jQuery.fn.multiselect = function() {
	$(this).each(function() {
		var checkboxes = $(this).find("input:checkbox");
		checkboxes.each(function() {
			var checkbox = $(this);
			// Highlight pre-selected checkboxes
			if (checkbox.prop("checked"))
				checkbox.parent().addClass("multiselect-on");

			// Highlight checkboxes that the user selects
			checkbox.click(function() {
 				if (checkbox.prop("checked"))
					checkbox.parent().addClass("multiselect-on");
				else
					checkbox.parent().removeClass("multiselect-on");
			});
		});
 	});
};

We can then apply the functionality to any group of checkboxes inside a container with the classname “multiselect”

$(function() {
     $(".multiselect").multiselect();
});

Don’t forget you need to include the jQuery library too:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

Here’s the final results:







 

 

 

24 replies to “Multiple select with checkboxes and jQuery”

  1. Derek Brock says:

    IE can get weird with the onChange event of a checkbox. I switched the function from:

    checkbox.change(function() {

    to:

    checkbox.click(function() {

    This allowed IE to fire the event immediately on the click event instead of when the checkbox loses focus.

    Thanks for the great article, very useful!

    • Gareth says:

      Thank you Derek, I have modified the code in the example above to use click() rather than change() as per your suggestion.

      Another modification I made is to use the addClass() and removeClass() functions. This prevents it from interfering with any other classes that you might manually assign to the checkbox labels.

  2. Dave says:

    Nice widget. Would like it even more if it supported option groups and params to allow for checkboxing of option groups as well as option to select all options in a group if the group is selected.

    Thanks.

  3. Hello there,

    I have a problem with my checkboxes (onclick). I have 3 checkboxes but I only can choose one e.g if I choose box 1, I wont be able to check box 2 & 3
    what I want is I can check more than one box. how can I do that?

    • Gareth says:

      The code shouldn’t stop you from selecting more than one checkbox. The jQuery adds progressive enhancement so that the selections appear “highlighted” but the checkboxes should function in the usual manner. Drop me an email if you’re still struggling.

  4. Sergio says:

    Hi Gareth, i can’t see the scroolbar. i generate the code of the checkboxs dinamicaly with this code:

    var xd=$(“lstMedida”);
    var mlbl;
    var mchk;

    for (i=0; i<rs.length; i++) {
    mlbl=document.createElement("label");
    mchk=document.createElement("input");
    mchk.type="checkbox";
    mchk.name="option[]";
    mchk.value=i;
    mlbl.appendChild(mchk);
    mlbl.innerHTML=mlbl.innerHTML+rs[i][1];
    xd.appendChild(mlbl)
    }
    $j(".multiselect").multiselect();

    and i replace the $ in the jquery function with $j
    var $j = jQuery.noConflict();
    but the first line i don't modify anything.
    jQuery.fn.multiselect = function() {

    in the html only:

    i see the dinamic code generated and looks like in your example.

    can you help me? thanks.

  5. Sergio says:

    one more try? div id=”lstMedida” class=”multiselect” /div

    • Gareth says:

      Sergio, did you get this working in the end? The .multiselect class in the CSS has overflow:auto which should provide you with a scroll bar. You could also check there isn’t another class or id over-riding the height. Drop me an email if you’re still struggling.

  6. Per says:

    This solution is nice, but I have a problem to display the jQuery validation error right. It shows up just under the fist checkbox… I would like it to show up below the multiselect div or at least below the last checkbox.

    Do you have a solution for this?

  7. Gerry says:

    Awesome solution. Now how do I pass that array into an AJAX call?

  8. Saravanan says:

    I got a script error of find() is not a function.

    I solved it by changing $(this).find to jQuery(this).find

    • Gareth says:

      Hi Saravanan – my understanding is that $() is the same as jquery() and you are simply passing “this” as a parameter, so I wouldn’t expect it to make a difference either way. However, there could be some other conflict but the fact you got it working is great.

  9. Mani says:

    hi i am new to jquery and ajax. my scenario is i need to create one cascading select box with multiselect checkbox as in your example. here no matter i can choose one option or mulitiple options but i need to load another dropdown box based on this options. i can load second dropdown box by single select but i cant able to load it by multiselect checkbox options. can you help me.. thanks in advance

  10. Birva Shah says:

    Very Helpful! Thank you so much!

  11. khalil says:

    Hi Gareth,

    I got a code from stackoverflow.com before seeing your helpful code, here it is:

    $(document).ready(function(){
    $(‘:checkbox’).bind(‘change’, function() {
    var thisClass = $(this).attr(‘class’);
    if ($(this).attr(‘checked’)) {
    $(‘:checkbox.’ + thisClass + “:not(#” + this.id + “)”).removeAttr(‘checked’);
    }
    else {
    $(this).attr(‘checked’, ‘checked’);
    }
    });
    });

    what I was looking for to get only one check box selected at one time by the user.

    But the per-selected check box keep showing on page normal refresh, which I don’t want, how to stop this.

    Thank you

    • Gareth says:

      Hi Khalil

      If I understand you correctly, you only want people to be able to select a single checkbox. Normally I would recommend simply using a select element for this, but if you really need to do it this way I’ve included the modified code below. Please note there might be a more efficient way of doing this. Furthermore, it won’t work if the user has JavaScript turned off, so your server side processing should ensure only one value is submitted:

      jQuery.fn.multiselect = function() {
      $(this).each(function() {
      var checkboxes = $(this).find("input:checkbox");
      checkboxes.each(function() {
      var checkbox = $(this);
      // Highlight pre-selected checkboxes
      if (checkbox.prop("checked"))
      checkbox.parent().addClass("multiselect-on");

      // Highlight checkboxes that the user selects
      checkbox.click(function() {
      if (checkbox.prop("checked")) {
      /* Only allow a single checkbox to be selected */
      checkboxes.removeProp("checked").parent().removeClass("multiselect-on");
      checkbox.prop("checked", "checked").parent().addClass("multiselect-on");
      } else {
      checkbox.parent().removeClass("multiselect-on");
      }
      });
      });
      });
      };

  12. Sangeetha says:

    Very nice article Gareth!

    If I want to bind this multi-select list to a model so I can get user selections, how can I do it?

    Thanks

  13. sam says:

    after selecting multiple check box , how can i get values of selected box in asp page where i can process the data.
    note it is asp and not asp.net

    • Gareth says:

      I’m afraid I’m not familiar with ASP. In PHP the values of the selected boxes will be in PHP’s post array (assuming you use the post method on the form). So they’d be accessible like this: $_POST[‘option’][0], $_POST[‘option’][1], etc.

  14. Ravi says:

    should i paste this code inside $(document).ready(function ()

  15. Igal says:

    Hi, I was wondering if this javascript wouldn’t be enough instead of your complex jquery extension
    checkbox.change(function(){
    checkbox.parent().toggleClass(“multiselect-on”)
    })
    checkbox in this piece of code would be a jquery selector (ex: all checkboxes in div.multiselect)

    • Gareth says:

      Yes your code is good, but you’d need to also account for checkboxes that are already ticked on page load.

      Off the top of my head, something like:

      checkbox.filter(“:checked”).parent().addClass(“multiselect-on”);

  16. […] Magento. While you cold go the painful way of doing a full implementation on this one, I recommend http://www.1stwebdesigns.com/blog/development/multiple-select-with-checkboxes-and-jquery . This plugin will transform a multiple select list into multiple checkboxes via […]

Leave a reply to khalil

Cancel Reply

(won't be published)
Email us Web enquiry form