How to get selected items from <select multiple ... > using Javascript

17 July 2004, 12:06 am ISTFiled under: Javascript

While working for one of our products BookShelf, I was faced with a problem of getting the selected items from

<select multiple='multiple' ... > </select>

tag using JavaScript. After thinking, figured out a simple way to do it. The trick was to make the de-select the selected items and keep them adding to an array for further processing. Here is the JavaScript code:

var arSelected = new Array(); function getMultiple(ob) { while (ob.selectedIndex != -1) { if (ob.selectedIndex != 0) arSelected.push(ob.options[ob.selectedIndex].value); ob.options[ob.selectedIndex].selected = false; } // You can use the arSelected array for further processing. }

Lets look at a simple html code ...

<form name='frmSelect'> <select name='numbers' multiple='multiple' onblur='getMultiple(document.frmSelect.numbers);'> <option value='1'>One</option> <option value='2'>Two</option> <option value='3'>Three</option> <option value='4'>Four</option> <option value='5'>Five</option> </select> <input type='submit' value='Submit' onclick='return confirm("You have selected: " + arSelected.toString();' /> </form>

User comments

dak (elideli at hotmail dot com)     23 July 2004, 11:43 pm IST
An easier--although linear in time--method is to simply walk through the list of options, testing each to see if it's selected: selected = new Array(); for (var i = 0; i < ob.options.length; i++) if (ob.options[ i ].selected) selected.push(ob.options[ i ].value); This is actually one of my annoyances, so I was delighted to see that Web Forms 2.0 fixes it.

Editor's note: The spaces between the options[ i ] are added to prevent it from conflicting it with the BBCode. It is not there in the original code.

dak (elideli at hotmail dot com)     23 July 2004, 11:45 pm IST
How embarrassing. Shame on me for using "i" as an index without noticing how it would collide with the BB italics tag. Hopefully this will close it.
Amit Arora (digitalamit at gmail dot com) from digitalamit.com     24 July 2004, 06:15 am IST

Thanks for the input! I use to do this the same way (earlier) as you mentioned, but there is a slight change which has a huge performance implication.

But consider a situation. Lets say there are 1000 options in the select element and 5 are selected. Your code would traverse through all 1000 to get just those 5 selected. However my approach would only traverse through those selected 5 items.

robin     23 September 2004, 11:03 pm IST
Thank for this article. I've been thinking about a problem for two hours. Your article helped me figure out how to solve it~~~ Thanks a lot :)
Amit (digitalamit at gmail dot com) from digitalamit.com     3 October 2004, 04:07 am IST
Glad to be of help!
Amita (amita293 at yahoo dot com)     2 November 2004, 11:10 pm IST
Hi, it solved my problems also.. Thanks
ssayeeds     9 December 2004, 07:26 am IST
Great technique!!! But the logic does not read the first element (index 0). You have to delete the part: if (ob.selectedIndex != 0) to make it working.
vishal     17 June 2005, 11:03 am IST
How should i use the array arSelected in php through POST
marino     23 August 2005, 05:11 am IST
create string from array, separate it with something you know it cannot be in array (; or # for example, so it looks like item1;item2;item3; or item1#item2#item3# ), put it in a input type=hidden, and split it where you send form by separating character. Works for me.
Thomas Ene     27 February 2006, 06:16 am IST
The frist method for getting the data is very efective; If you have a long array (2000 elements) and if the user uses a slow browser like IE it will be a pain for him to wait the browser to iterate through all of the values. It is much faster to get the selected items by unselecting them one by one. Excelent idea.
R. Worawanna     18 April 2006, 10:46 pm IST
it solved my problems also, Thank you so much
Davide Andrea (1davide at excite dot com)     27 April 2006, 06:19 am IST
Nice approach. However: 1) This code deselects the selections, leaving you with a totally unselected list. 2) I am not so sure that your code uses a faster algorithm. Let's say you have 100 items, of which 10 are selected. The standard approach of going down the entire list and noting which items are selected. True, in your code JavaScript calls selectedIndex only 10 times, while the standard approach calls options[ i ].selected 100 times. At first sight, your approach is better because it calls a Javascript function 10 times instead of 100 times. However, you may be forgetting that the underlying code implementing selectedIndex is going down the list looking for a selected item. (I may be wrong about this assumption, someone please let me know). Therefore, in your approach, the underlying code is going through the list of items *10 times*, instead of going through the entire list just once. (The last time through, the underlying code will go through the entire list; the previous times it will go through only part of the list.) That's why I think you approach will actually take longer. (No, I didn't run an actual test to verify my claim.)
Amit Arora from digitalamit.com     6 May 2006, 11:07 am IST
David, Yes, it may be possible that this may be not be the efficient method for selection in the example you mentioned and other method would be better suited. However, I had a very special situation which needed to parse to huge list for getting few selected items. If the situations were reversed, it would definately take longer. But as I have mentioned earlier, the implementation is upto you. :)
Scott Bryan (ananias at mac dot com)     11 June 2006, 05:42 pm IST
I was wondering why the test for index 0? It looks to me like your code will not add the first item to the reported selections.
Bernardo     28 July 2006, 11:21 am IST
I found a better solution for multiple selects. I use this function to update the Title (Tooltip) of my SELECTs: function updateTitle(src, lst){ var txt = ''; var arSelected = new Array(); var arReselect = new Array(); while(lst.selectedIndex!=-1){ arSelected.push(lst.options[lst.selectedIndex].text); arReselect.push(lst.selectedIndex); lst.options[lst.selectedIndex].selected = false; } for (i=0; i].selected = true; } for (i=0; i; txt += '\n'; } if (txt!=''){ txt = txt.substr(0, txt.length-1); } if (src.title!=txt){ src.title = 'Itens Selecionados:\n' + txt; } }
Ted     14 December 2006, 01:19 pm IST
Amit, Davide's comments apply to any size multiple select box with any number of selected items. I'm sorry to say it, but your algorithm will take longer in _every_ case.
sun     4 January 2007, 03:25 pm IST
I agree that amit's while loop should be faster than the for loop with large selection list in general. Of course this is also depending on the browser. In some cases I have to pick up 50 out of 6000 items and i am using the while loop for sure.
Carlos Pantelides (carlos_pantelides at yahoo dot com)     28 January 2007, 12:47 pm IST
if you dont need the intermediate array, this code is for moving options from one select to another, based in earlier comments: //uses $() from http://prototypejs.org/javascripts/prototype.js function move(from, to){ var selected = $(from); var pool = $(to); while (pool.selectedIndex != -1) { selected.appendChild(pool.options.item(pool.selectedIndex)) } }
jasvir (jasvir dot singh at ge dot com)     12 April 2007, 11:59 pm IST
THisis really great help i got , i was getiing stucked bcoz of thi sproblem, now i got the solition Thankss alot
Ralph     20 July 2007, 10:06 pm IST
There's an issue. In my case I was getting the first selected value repeated as many times as selected items are. Thinking a little, I remembered I once read that the events will run through the whole tree before any other event takes place, though I'm not sure of it, this may the cause of my problem. Either way, is helpful.
Narayan (narayan19 at rediffmail dot com)     27 July 2007, 02:36 pm IST
This script has been such a timesaver. Thanks, Amit, and keep up the good work!
Milton Waddams (miltonwaddams42 at yahoo dot com)     11 August 2007, 12:20 pm IST
So basically, there is no good (better than linear) way of doing this? Seems like an annoying oversight...
I did some testing. Made a drop down containing 10,000 items and used both methods described above to determine which is better. Came up with the following:
Method 1: while(selected index>-1)
Method 2: for(every element) if(selected)

Method 1 worked faster for a very low percentage (only one or two) of selected elements. Biggest downside is that it clears the selections and runs slower for more selected items. Restoring the selection after running this method took longer than method 2 in almost all cases
Method 2, for a list of 10,000 items, only took about a second to complete (2.00 GHz processor)
For short lists (for example, 10 items or so) you won't notice a difference.
Basically, if you've got a page with a very large list of items of which only a few will be selected, and do not need to keep track of what was selected: (i feel sorry for the users that have to filter through that to find the two elements they want) Use method 1. You may want to consider revising the provided code by saving document.getElementById('dropdown_name').selectedIndex to a variable instead of calling it multiple times. This call does take time to run.
For everyone else, use Method 2. It actually runs faster for a higher percentage of selected items. It's also simpler to read and write.
Anyway, hope that's helpful to someone. If you feel the need to pay me for it, my email address is above :)
--
Milton
...i believe you have my stapler...
max (anagramster at yahoo dot com)     17 August 2007, 07:44 pm IST
just use jquery: $('option:selected',selobj).each( function() { vals.push( this.value ) } );
IT Outsourcing (globalprompt at gmail dot com) from globalprompt.net     17 January 2008, 10:47 am IST
Its great, It helped me to solve my problem. I have solved my problem using this article. Thanks
Omer Kiremitci (omerkiremitci at yahoo dot com)     26 January 2008, 06:04 am IST
Hello everyone, I have a problem that cannot be solved during my project development which was started 2 weeks ago. The problem is; I want to import lots of .csv files from client side, after check all of them. During checking process i would like to look all files at one time, surely one by one, but i could not. Because I can not select files with multiple selection. I now select them one by one with using fileopen diolog box. If you please help me if you know the solution. How can I select multiple files from client side? Thanks in advance.
Newbii (newbii at you dot com)     27 February 2008, 03:07 am IST
Thanks for that great Tutorial. But, how can i use this array for a sql select statement? Can i send the hole array in a hidden field to the sql select? Or do i have to do something else? Thanks for any answers...
egg (egg at eggmail dot com)     25 March 2008, 02:11 pm IST
If you are only going to have a few selections out of say 1000 or six thousand why would you parse the whole list anyways? Why not just write a string to a hidden input? and if you needed even more space or the resulting string of select values is going to be real big consider using ajax and pass the items one at a time. It's really low overhead. Either way you only call the function once for each change? If this is dumb post a reply. I only started this stuff a few months ago. egg
egg (egg at eggmail dot com)     25 March 2008, 02:14 pm IST
should put code tags around this....I assumed the forum would do that naturally. Sorry. If you are only going to have a few selections out of say 1000 or six thousand why would you parse the whole list anyways? Why not just write a string to a hidden input? and if you needed even more space or the resulting string of select values is going to be real big consider using ajax and pass the items one at a time. It's really low overhead. Either way you only call the function once for each change? If this is dumb post a reply. I only started this stuff a few months ago. egg
indoCoder     9 April 2008, 03:28 am IST
...The Above text will select the index which id is "myId".
Eric (xtentic at hotmail dot com) from gfxpoll.com     2 May 2008, 09:33 pm IST
Great tut, now i need to know how to transfer items to another select wich aren't selected...
Jasur (j dot atadjanov at gmail dot com)     5 May 2008, 04:36 am IST
To send multiple SELECT object by FORM to Server, just use name[] (array format) example: and server side i can get selected items such as elemts of sObj[] array
Sneha (snehashah30 at yahoo dot com)     14 May 2008, 06:00 am IST
Hey thnx a lot everyone....it solved my problem ..was searching for the solution since long...thnx again..
Anonymous     28 May 2008, 02:49 am IST
From MSDN site, it is better to use "selected" for "multiple" types than to use selectedIndex.
Jackson     1 August 2008, 01:37 pm IST
If the while loop performs a linear search through the array during each iteration then the method using for loop is faster because it goes through the array once. If not, then it can be very possible that they'll operate at the same speed. From one of the posts here, it seems to indicate that the for loop version is faster than the while loop version which would lead me to conclude that the while loop version is probably restarting the search from the beginning of the array. Interesting post.
Nippala (vesa at webmonkey dot fi) from lelutalo.fi     2 September 2008, 11:11 pm IST
The code above doesn't work if there are [] -marks in the select name. Eg select name="numbers[]'. I guess someone has a simple solution for this?
Vesa Nippala (vesa at webmonkey dot fi) from webmonkey.fi     2 September 2008, 11:39 pm IST
Hi again, I'm replying to my own post, because I already found a solution. I kept []-marks in the select name as it was, but instead I added id attribute to the select and modified the function to work by using getElementById: element = document.getElementById(ob); for (var i = 0; i < element.options.length; i++) { element.options.selected = false; }
raul (raul1985singh at gmail dot com)     3 September 2008, 12:12 am IST
wonderful solution got my answer really thankful to u
Jimit (info at beyondmart dot com) from beyondmart.com     21 January 2009, 10:08 pm IST
good
Tomiwa Adefokun (tomiwa dot adefokun at gmail dot com) from softandsmart.com     21 April 2009, 09:25 am IST
I have a solution but can get to post it, some errors occurred.
Tomiwa Adefokun (tomiwa dot adefokun at gmail dot com) from softandsmart.com     21 April 2009, 09:26 am IST

function getMultipleSelection(formName,elementName,array){ var selected = new Array(); var mySelect = document.forms[formName].elements[elementName]; for(i = 0; i < mySelect.options.length; i++) { if(mySelect.options.selected) { selected.push(mySelect.options.value); } } if(array != 'true') return selected.toString(); else return selected; }

deepak     25 June 2009, 06:21 am IST
few changes. function getMultipleSelection(formName,elementName,array){ var selected = new Array(); var mySelect = document.forms[formName].elements[elementName]; for(i = 0; i < mySelect.options.length; i++) { if(mySelect.options.selected) { alert(mySelect.options.value); selected.push(mySelect.options.value); } } if(array != 'true') return selected.toString(); else return selected; }
Tomiwa Adefokun (tomiwa dot adefokun at gmail dot com) from softandsmart.com     14 July 2009, 06:35 am IST
I just notice some errors in my former post which was because I used var i, which could not be accessed in an array using square brackets since it is reserved for formatting, I have change the variable to j:

function getMultipleSelection(formName,elementName,array){ var selected = new Array(); var mySelect = document.forms[formName].elements[elementName]; for(j = 0; j < mySelect.options.length; j++) { if(mySelect.options[j].selected) { selected.push(mySelect.options[j].value); } } if(array != 'true') return selected.toString(); else return selected; }

KOCMOC (kocehbka at gmail dot com) from weblancer.net/users/kocehbka/     6 August 2009, 06:56 am IST
Thank you very much. It's the best idea for this problem. You saved me =)
Impex Solutions (impex at impexsolutions dot net) from impexsolutions.net     7 October 2009, 10:05 pm IST
thanks
blog comments powered by Disqus

Syndicate

RSS1
RSS2
Feedburner
Add to MyMSN
Add to MyYahoo
Add to Google

Topics



About

Amit Arora is web developer with expertise in developing eCommerce enabled websites for the businesses.

Contact | Resume

Subscribe to newsletter




Get Firefox

Monitored by Site24x7
Uptime