I have implemented the jquery multiselect addon and got it working fine. I have a long list of select options and are divided by optgroups. While optgroups organizes my long list but still users still have to scroll for a while to get to the bottom option. I am simply looking for a solution to have the optgroup collapsed by default and un-collapsed when you click on the group.
At the moment when you click on the optgroup it automatically selects all options under it which I would like to prevent and instead replace that with a hide function instead. I know that jquery by default cannot target a select's optgroup but the Jquery Multiple select addon has an event handler that apparently allows you too. If you scroll a bit half way down their site it gives you all the event handlers this addon supports. I was really interested in the optgrouptoggle
event:
Fires when an optgroup label is clicked on. This event receives the original event object as the first argument, and a hash of values as the second argument: js
$("#multiselect").bind("multiselectoptgrouptoggle", function(event, ui){ /* event: the original event object, most likely "click" ui.inputs: an array of the checkboxes (DOM elements) inside the optgroup ui.label: the text of the optgroup ui.checked: whether or not the checkboxes were checked or unchecked in the toggle (boolean) */ });
I tried implementing a show hide function as follows but I still new with jquery and might be botching this completely. Any help would be appreciated.
http://jsfiddle.net/akhyp/1986/
$("#selected_items").bind("multiselectoptgrouptoggle", function(event, ui){
$(this).children().show();
}, function() {
$(this).children().hide();
});
A few problems with this approach, some in your code, some in the plugin's API:
Your demo code references $("#selected_items")
, which is nowhere in your markup. Change the selector to $("select")
to match your declaration of the multiselect
above. Better still, cache the jQuery object in a variable: var $multiselect = $('select');
The docs specify using bind
to attach an event listener, but bind
is deprecated in recent versions of jQuery. Use on
instead.
You're passing two functions to the on/bind
method--it only takes one. Instead of using hide()
and show()
, you can just use jQuery's toggle
method.
The multiselect
plugin isn't structuring its generated markup semantically, so optgroups
and their child option
elements are translated into straight-up li
elements, with the optgroup
and option
elements as siblings. That means you can't use children()
the way you would hope. However, the API provides you with a way to find the checkboxes that were associated with the optgroup
: ui.inputs
. From those, you can find each of the parent li
elements and hide them. Unfortunately, it doesn't look like the API gives you a way to directly address them, but you can use a code snippet like so:
var parentLiOfInput = function(input) {
return $(input).closest('li');
};
var $listEls = ui.inputs.map(parentLiOfInput);
// $listEls is now an array of jQuery objects
// Note this isn't the same as a jQuery wrapped set--
// you can't do $listEls.hide(), for example.
Hiding the generated "option" elements will prevent the plugin from working--it uses a jQuery selector to toggle the checkboxes, and that selector relies on the associated elements to be visible.
That last point is the blocker: Once you hide the checkbox, the plugin will fail on the next optgroup click. Demo of the failing behavior.
I don't really see any options for you at this point, without directly modifying the code of the plugin.