multiselect updates

Thanks to all the people who have tested and used the multiselect before. I’ve taken the improvements, suggestions, and bug-fixes and am now happy with a new version of it.

Multiselect takes a normal <select multiple="multiple"> and converts it dynamically into a more user-friendly interface.

An example of the new and improved version can be found here.

Points of note

  • you can now “select all” and “select none”
  • a new “reset” link brings the select box back to how it was originally
  • the script works even if you have more than one multiselect box

caveats: the name of the <select> must end in ‘[]‘. While this is specifically against W3C rules, there does not seem to be any alternative method to pass on multiple values for one variable.

To use, simple download the script and link to it in your webpage.

This script should work in all major browsers. If it doesn’t work in the one you’re testing in, then please alert me.

33 Comments.

  1. This script is a thing of beauty! Unfortunately, I’ve hit a minor snag. My CMS allows for subcategories, and it denotes them in the multi-select box by indenting them using &nbsp.

    When I use this script to publish articles- the &nbsp actually shows in the mutliselect box. So it looks like:

    [box] Parent category name
    [box] &nbsp&nbspSubcategory name

    I actually love this script enough I hacked the backend of the CMS to use dashes instead of entities to indent, but I’d really like to figure a way to do it with the entities instead. I’d also prefer to do it by changing the js rather than hacking, as I’d like to add it as a ‘tip’ on my CMS forums, but I don’t like to encourage hacking the backend. Unfortunately, while my php skills are adequate, my js skills are non-existent. Any hints on WHY this is happening and whether/how I could fix it would be very appreciated!

    Either way, thanks a ton for sharing this! It’s vastly preferable to the standard mutlti-select!

  2. okay – I’ve fixed that in the script. It will now escape &nbsp;, &lt;, and &gt;.

    make sure that you remember the closing semi-colon on those entities! they may work in internet explorer, but the world is much larger than that browser.

    the reason it was happening is that JavaScript prints out characters to the screen /exactly/ as it is asked to. This includes HTML entities.

  3. Wow- I really appreciate the fast reply- and the fix! I made one little change, as it was only replacing the first occurrence and my subcats have multiple spaces:

    text=text.replace(/\&nbsp;?/g,’ ‘);
    text=text.replace(/\&lt;?/g,”);

    Thanks again- I’ll note that it’s now working latter this afternoon in the EE forum thread on it- this is just a REALLY handy widget!
    http://www.pmachine.com/forum/threads.php?id=29848_0_26_0_C

  4. Thanks for fixing this up for me. I use it with the same CSMS that rob1 uses and it is working great. Thank you so much =)

  5. How to retrieve the post with this select replacement ?

    Should I get the cbox values or the select values ?

    Please could you explain how to retriev the values ?

    Thanx.

    P.

  6. You retrieve the values in exactly the same way as you would if there was no JavaScript involved.

    In the case of a normal select box named “vars[]”, the values would be retrieved as an array named $vars (in PHP – I’m not certain about other languages).

    In the case of the multiselect, the select box is removed from the DOM tree completely, and replaced with checkboxes (named “vars[0]”, “vars[1]”, …). In this case, an array is also created called $vars.

    If you have trouble, please tell me what programming language you are using on the server side.

  7. I’m using javascript. I’ve tried to retrieve the checked elements, but I couldn’t cause in these comands I’ve receveid 0(zero) as result:

    alert(document.getElementsByName(‘sel_name[]’).length);
    alert(document.getElementsByTagName(‘SELECT’).length);

    So, what’s the correct way to do that?

  8. Kleuber, once the multiselect has run, the select boxes do not exist anymore. They are replaced by check boxes.

    Try looking at the results of getElementsByTagName(‘input’). You should be able to build a function that can retrieve an array of the checkboxes by checking the name against a regular expression.

    For instance, if the original selectbox had the name “select1[]”, the following should retrieve all checkboxes to do with that (not tested):

    var arr=[];
    var els=document.getElementsByTagName(‘input’);
    for(var i=0;i<els.length;i++)
    if(els[i].name && els[i].name.match(/^select\[))
    arr[arr.length]=els[i];

    In this case, “arr[]” should contain the inputs you’re looking for (provided the code is correct πŸ™‚ ).

  9. This is a slightly modified version of the script posted here. The approach is different. This script hides the original selectbox, then it displays the new rendered checkboxlist and then just before the submit it copies the values back to the selectbox (so they wont be send back to the server).

    Tested in Firefox only (yet).

  10. That’s pretty cool – nice edit of the code, but why? As far as I know, it will make no difference to the server whether the data comes from multiple options, or a select multiple. Rob, can you shed some light on why you did it?

    btw: I really like the email trick on the sandbox page. Very handy anti-spam device! Although – the link it creates is lacking a “mailto:” πŸ˜‰

  11. Very nice widget!!!

    But, how to remove the first line with “all, none, reset” ??
    I do not need that line, so is there any way to remove it from the script?

    Thanx, Frank

  12. ‘fraid I’m a bit busy at the moment to write up a solution to that problem, Frank, but if you look through Rob’s demo code, you can see that he has done that for the version he edited.

  13. Hmmm, after some little investigation I have to admit that you are right. I’m using Java for form handling and Java doesn’t understand the []. I thought it had something to do with checkboxes and multiple values that Java cannot handle.

    Ok, I learned something new and thank you for this idea en sourcecode πŸ™‚

    Btw, the anti-spam trick is just a quick hack.

  14. Rob, you could have a point. I insist on the [] symbols because it is just so handy for PHP, but according to W3C specs, those symbols are illegal for use in form names.
    The problem is on the server side – if you have a parameter string such as “blah.php?test=one&test=two“, then a quick check shows that only the second test is recorded in the $_GET array. That can be fixed by writing a short server-side function that re-examines the parameter string and creates arrays from everything, instead of scalars.
    …but that makes the solution more complex than I like πŸ™‚ I prefer the idea of a one-script solution (the multiselect.js) that will work for most environments, than the idea of a multiple-script solution, which involves more preparation.

  15. Kae,

    First of all, thanks for the use of your code. It’s very useful.
    I am one of those guys using Java, so I had to make some changes to
    your code to get it to work. I removed the ‘[]’ name dependency, as
    that will not work in Java. Next I added a different test for
    determining if the Select was multiple or not. For some reason, your
    original code was not ignoring Selects without multiples. Finally, I
    removed some of the bells and whistles (All, None, Reset). Mainly,
    because I could not get them to work and didn’t have time to re-work
    them. Anyway, for what it’s worth, I am posting my changes at the
    end of this note. Thanks again.

    code can be accessed here – Kae.

  16. Thanks Mike – that confirms that the [] symbols are bad for a Java server. I think it’s time for another update, with variable-toggled ‘[]’ symbols, ‘all, none, reset’ links, etc.

    Anyone have any other ideas that would drastically improve this?

  17. I have a multi-select which is sectioned off with the used of several disabled items in the list. I was wondering if there is a way for those items in the list that are disabled to not have a checkbox next to them. For example:

    :::: Group A ::::
    Item 1
    Item 2
    :::: Group B ::::
    etc.

  18. Brenda, that’s interesting. I never even considered that an <option> might be capable of being disabled. I will code up an answer to that as soon as I get home. There were some other thoughts expressed in other comments that might need an expansion of the code – disabling the “all, none, reset” links, for example, and getting rid of the ‘[]’ symbols.

    Okay – I’ll have a new version of the multi-select available for download later today with all the above thoughts combined into it. Thanks for all of the contributed ideas.

  19. Updates are noted here

  20. This is the most awsome drop down mod i have every seen. Thanks Kae…
    Suggest though that there is an option to include or exclude all selects with or without the []. default is for all selects .. with our with out this [] in the name.

    I replaced the line:
    If(ms.multiple){

    With the line (22) from your old one:

    If(ms.name.substring(ms.length-2,ms.name.length)=='[]’) {

    This keeps the improved version to only apply your mods to the selects with [] in the name !!

    Thanks much for a great tool!

  21. um.. id like to update my entry above with the correct code (sorry)

    Replace
    If(ms.multiple){

    with:
    With the line (22) from your old one:

    if(ms.name.substring(ms.name.length-2,ms.name.length)=='[]’){

  22. Stripe-man, please note that some people will be using this code without square brackets in the <select>’s name, so your code will not apply in those cases.

    I think a better solution may be to have a class which, when applied to the selectbox, will de-activate the multi-select script for that particular case.

    For instance, the following will be converted:
    <select name=”blah” multiple=”multiple”>

    but the following won’t:
    <select name=”blah” multiple=”multiple” class=”nomultiselect”>

  23. oh yea.. that would be good!

  24. Hi kae,

    First of all, congratulations! This javascript code is underful!

    Sorry about my english, hope you understand it.

    I wondering if it’s possible to have a multiple choice (with the checkboxes) but not with a multiple select. Just on a simple select or drop down menu.

    The ideia was to have your multiple select in a drop down menu. When you open the combo, you will be able to check the options you want and then, by clicking (I’m just wondering!!) in the combo again, the combox litle window closes the options view…

    Thanks!

  25. This is a great script – very easy to implement and does 90% of what I’m looking for. Any thoughts on how to achieve the remaining 10% would be greatly appreciated!

    I am displaying a grid of rows and columns from a database and I am using multiple selects to have some filters at the top of some of the columns. Your multiple select is just how I would like users to be able to select their chosen filters, but I would ideally like the initial appearance of the filter to be as a simple doprdown select list. The sort of thing I am referring to is as with : http://www.easylistbox.com/demoMultiDropDown.aspx or http://www.codeproject.com/asp/multiselectdropdown.asp

    Many thanks.

  26. willogee – fantastic demos! Unfortunately, I think that that method might be a bit unwanted in the end, due to one behavioural problem – the multi-select code does its magic after everything has been loaded. So, as the page was downloading, you would have a large normal multiselect, which would then jump, at the end, to a smaller-sized one.

    unless…

    I have a solution. I’ll code it tonight.

    You know – I was wondering what Bruno was saying (sorry Bruno – but your English is hard to understand πŸ™‚ ), but it looks like you’ve clarified that.

    There may be an accessibility issue, in that the designer may be tempted to design as if the script will work in all cases. This may result in broken interfaces where the designer tried to use absolute positioning for everything, but the end user did not have JavaScript enabled (thus breaking the script, and thereby also breaking the design), but I guess that’s not for me to worry about :).

  27. kae,

    Looks like a great solution that should do most (if not all what I need).. so I’m planning to bring up your routine under java. Does the latest download include the changes you made for Topic#27?

    Regards

  28. This thing just gets better and better!! …

    I think the prob i was having iwth the array getting dumped is fixed with the java version… i will test at work tomorrow Kae….

    FYI – creating the article (and selecting items in drop down was never the prob.. it was when the article was edited (was reselected fine) and submited the array was dumped… ) odd.

  29. This script is great…
    I was able to used it in my app

    My prob right now is how to retrieve the data selected from the checkbox. I know that is the same comment that Kleuber posted. But still i am having hard time to figure it out. One main reason is that i am just starting to learn this language(javascript)-self learn. If anyone can post working script that i can download it would be greatly appreciated

    Thanks in advance

  30. MJP – how you gather the information depends on the server-side language that you are using. You should get your form working first in plain HTML, before trying to apply this script to it.

  31. I like the simple things, try it into table tags it works fine! Thanks Kae! It will be nice to add something to first letter to jump to that zone in future(Ex: (M)onday if you press M to goto that zone)."<html>
    <head><form name="cucu"><style type="text/css">li.row1 {background-color :#EFEFEF;}</style>
    <script language="Javascript">
    function deselectare()
    {
    for(var i=0;i<document.forms[0].chk.length;i++)
    {
    if (document.forms[0].chk[i].checked)
    {
    document.forms[0].chk[i].checked=false;
    }
    }
    }
    function selectat()
    {
    var x="";
    for(var i=0;i<document.forms[0].chk.length;i++)
    {
    if (document.forms[0].chk[i].checked)
    {
    x=x+’,’+document.forms[0].elements[i].value;
    }
    }
    alert(x);
    }
    </script>
    <div style="width: 210px">
    <ol style="height: 7em;overflow: auto;list-style-type:none;padding: 8px;margin:0;border: 4px ridge grey;" id="select">
    <li><A href="javascript:deselectare()">None</A>&nbsp;&nbsp;&nbsp;&nbsp;<A href="javascript:selectat()">Selected</A></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="1">Field1</label></li>
    <li class="row2"><label><input type="checkbox" name="chk" value="2">Field2</label></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="3">Field3</label></li>
    <li class="row2"><label><input type="checkbox" name="chk" value="4">Field4</label></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="5">Field5</label></li>
    <li><label><input type="checkbox" name="chk" value="6"> Field6</label></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="7"> Field7</label></li>
    <li><label><input type="checkbox" name="chk" value="8"> Field8</label></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="9"> Field9</label></li>
    <li><label><input type="checkbox" name="chk" value="10"> Field10</label></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="11"> Field11</label></li>
    <li><label><input type="checkbox" name="chk" value="12"> Field12</label></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="13"> Field13</label></li>
    <li><label><input type="checkbox" name="chk" value="14"> Field14</label></li>
    <li class="row1"><label><input type="checkbox" name="chk" value="15"> Field15</label></li>
    <li><label><input type="checkbox" name="chk" value="16"> Field16</label></li>
    </ol>
    </div>
    <br><br><br><br><script language="Javascript">
    function afis_id()
    {
    for(var i=0;i<document.forms[0].chk.length;i++)
    {
    if (document.forms[0].chk[i].checked)
    {
    alert(document.forms[0].chk[i].value);
    }
    }
    }
    </script>
    <p>
    <input type="button" value="Selectare" onMouseOver="javascript:afis_id()">
    <input type="reset">
    </p>
    </form>
    </head>
    <body>
    </body>
    </html>

  32. Hey, great script!
    Don’t know if you still update it..
    It’s one problem with it. I want the “label” to be clickable. You know like using:
    This is a test

    If I try to add something like this:
    text = ”+text+”;

    it will not work, cause the createTextNode function don’t take HTML-chars.. so what should I do?
    The other demo with fully clickable rows looked interesting, i’ll look into that.

    Thanks for your time πŸ™‚

%d bloggers like this: