In my work, I came across the need for a web control that would allow me to have two <select>
elements, and be able to easily transfer <option>
elements between them. The idea is to have a base list of options, from which you can choose a subset to be saved, or whatever you might wish to do with them. As a perk, I decided to add the extra feature of filters, which can be used to search for items contained within either box. Because the application I was developing this for was a legacy ASP app, I decided the easiest way to accomplish this goal would probably be javascript. To this end, I created the Dual Listbox plug-in. With this plug-in, all you have to do is create the HTML structure, in whatever configuration you like, and give the elements of the control IDs. The plug-in will do the rest of the work for you. If you like this plug-in (or I suppose even if you don't), please do me a favor by heading over to its project page on jQuery's website and rating it, so that other users can benefit from your experience.
To get started, you will need the following:
Once you have these, and have included them in your project and the file you intend to use them in, Dual Listbox is as easy as:
$.configureBoxes();
Yup, that's it! Of course, if you don't want to use the default settings, you'll have to get a bit fancier but that's the basic idea. If you do want to rock the boat a little I've provided an options
parameter, which is a JSON object which will allow you to pick and choose the settings you like. See section Options for a full listing and description of the available options.
A brief description of how to use this control: Select one or more items from one of the boxes, then click the ">" or "<" button to move the selected items to the opposite box. Click the ">>" or "<<" button to move all items from one box to the other. You may also double-click an individual item to move it to the other box. Type into either filter box to limit the values in the corresponding <select>
to those items that contain the string that you enter. Note that while you are filtering, all move operations affect ONLY visible elements (aka, if you filter box one, then move all from one to two, elements that did not match your filter will not be moved to box two). Click the "X" button to clear the filter.
This plug-in allows you to "transfer" the <option>
elements between the <select>
s in two distinct ways:
<option>
elements will be removed from the <select>
in which they currently reside and moved to the other <select>
. This is the default. <select>
will ALWAYS remain in the first <select>
(unless they are hidden by filtering). When they are selected for transfer they will be copied to the second <select>
and will be given the class 'copiedOption' in the first <select>
(my default styling for this class is yellow background but you may choose whatever styling suits you). If they are then transferred from the second <select>
, they disappear from the second <select>
, and the 'copiedOption' class is removed from the corresponding <option>
in the first <select>
. Here is the default document structure (which I used to develop this plug-in):
000. | | | < table > |
001. | | | < tr > |
002. | | | < td > |
003. | | | Filter: < input type = "text" id = "box1Filter" /> |
004. | | | < button type = "button" id = "box1Clear" > X</ button > < br /> |
005. | | | < select id = "box1View" multiple = "multiple" style = " height :500px ;width :300px ;" > </ select > < br /> |
006. | | | < span id = "box1Counter" class = "countLabel" > </ span > |
007. | | | < select id = "box1Storage" > </ select > |
008. | | | </ td > |
009. | | | < td > |
010. | | | < button id = "to2" type = "button" > > </ button > |
011. | | | < button id = "allTo2" type = "button" > >> </ button > |
012. | | | < button id = "allTo1" type = "button" > << </ button > |
013. | | | < button id = "to1" type = "button" > < </ button > |
014. | | | </ td > |
015. | | | < td > |
016. | | | Filter: < input type = "text" id = "box2Filter" /> |
017. | | | < button type = "button" id = "box2Clear" > X</ button > < br /> |
018. | | | < select id = "box2View" multiple = "multiple" style = " height :500px ;width :300px ;" > </ select > < br /> |
019. | | | < span id = "box2Counter" class = "countLabel" > </ span > |
020. | | | < select id = "box2Storage" > </ select > |
021. | | | </ td > |
022. | | | </ tr > |
023. | | | </ table > |
<noscript></noscript>
You might be wondering why there are four <select>
boxes, instead of just two, as you might expect. These are there to allow the filtering functionality to operate smoothly in all browsers. I would like to have just added style="display:none;"
to elements that shouldn't be visible, but several browsers do not support hiding <option>
elements. Thus, the filtering works by moving elements that have been filtered out to this second hidden <select>
. If you are not planning on using filtering, you may omit the "storage" boxes (as well as the counters, filters, and clear buttons if you wish). Note that this structure is not required, as the plug-in relies on the ids of the elements to locate and manipulate them. I simply found this configuration easiest to work with while developing, but you should feel free to get creative.
The following table has a listing of all the possible option settings, their default values, their valid values, and a brief description of each.
box1View | 'box1View' | Any valid HTML id string. | The id attribute of the first visible <select> element. |
box1Storage | 'box1Storage' | Any valid HTML id string. | The id attribute of the first hidden <select> element. (See section Document Structure for an explanation of visible/hidden <select> elements.) |
box1Filter | 'box1Filter' | Any valid HTML id string. | The id attribute of the textbox used to filter the first <select> element. |
box1Clear | 'box1Clear' | Any valid HTML id string. | The id attribute of the element used to clear the filter for the first <select> element. This is typically a button, but can technically be any element. |
box1Counter | 'box1Counter' | Any valid HTML id string. | The id attribute of the element used to display counts of visible/total <option> s in the first <select> element. (used when filtering). |
box2View | 'box2View' | Any valid HTML id string. | The id attribute of the second visible <select> element. |
box2Storage | 'box2Storage' | Any valid HTML id string. | The id attribute of the second hidden <select> element. |
box2Filter | 'box2Filter' | Any valid HTML id string. | The id attribute of the textbox used to filter the second <select> element. |
box2Clear | 'box2Clear' | Any valid HTML id string. | The id attribute of the element used to clear the filter for the second <select> element. This is typically a button, but can technically be any element. |
box2Counter | 'box2Counter' | Any valid HTML id string. | The id attribute of the element used to display counts of visible/total <option> s in the second <select> element. (used when filtering). |
to1 | 'to1' | Any valid HTML id string. | The id attribute of the element used to transfer only selected <option> s from the second <select> to the first. |
to2 | 'to2' | Any valid HTML id string. | The id attribute of the element used to transfer only selected <option> s from the first <select> to the second. |
allTo1 | 'allTo1' | Any valid HTML id string. | The id attribute of the element used to transfer ALL <option> s from the second <select> to the first. |
allTo2 | 'allTo2' | Any valid HTML id string. | The id attribute of the element used to transfer ALL <option> s from the first <select> to the second. |
transferMode | 'move' | 'move','copy' | The type of transfer to perform on moved items. See section Transfer Modes for a full description of each. |
sortBy | 'text' | 'text','value' | The value to sort <option> elements by. 'text' causes them to sort alphanumerically (ascending) by the visible text of the option. 'value' causes them to sort alphanumerically (ascending) by their 'value' attribute. |
useFilters | true | true,false | True to enable filtering, false to disable it. If this setting is false, it is recommended that useCounters also be set to false, as the counters will not serve a purpose. |
useCounters | true | true,false | True to enable counters, false to disable them. |
useSorting | true | true,false | Sorting enforces a consistent sort order on the <option> elements, regardless of what order they are transferred in. Set this to false if you do not want them to (or do not care if they) maintain a consistent order. |