Posted At : June 6, 2008 7:58 PM | Posted By : Adrian J. Moreno
Related Categories:
Javascript, Primers
I've done this countless times, yet I can never seem to remember how I did it the next time I need the code. This is so I don't have to hit up Google next time.
Move a single option between menus
So here's the basic form:
The code is simple enough.
Rather than have two functions moveLeft() and moveRight(), I'm going to go with a single function that uses the ID of both select menus to swap an option from one to the other.
Let's go through this line by line:
1. Get the index of the option selected in the left menu.
var i = document.getElementById( fromID ).selectedIndex;
2. Get the option object associated to the index i in the left menu.
var o = document.getElementById( fromID ).options[ i ];
3. Create a new option object based on the select option.
/*
The Option object has 4 properties
Option( text, value, defaultSelected, selected )
*/
var theOpt = new Option( o.text, o.value, false, false );
4. Put the new option object into the array of options in the right menu.
document.getElementById( fromID ).options[ i ] = null;
Moving multiple options between menus
Here's the same form where we can select more than one option at a time.
The HTML code has a slight change to allow for multiple options to be selected.
Now, the original Javascript function need a slight alteration to allow for the option's index to be passed into it. This only runs if the value of idx is not empty.
All we need to do is to loop over the entire array of options in the requested select menu and move only the options that are selected. When an option is selected, rather than rewrite code, this function will tell the original function which option to move.
Why count down instead of counting up?
The only important piece of code here is the definition of the for loop.
Normally, you'd use something like this:
for (var x = 0; x < document.getElementById( fromID ).options.length; x++)
With 10 options, this evaluates to
for (var x = 0; x < 10; x++)
The problem is that as each option is moved from one menu to the other, it is also removed from the original menu. This means that the length of the option array changes as each option is removed.
If you start at the first option (0) and moving towards the tenth option (9) as each option is removed, the remaining elements shift position in the array. So after the first option is moved, you'll get the wrong options moved afterwards and eventually error out once the value of x goes past the length of the altered array.
So instead we start with the last element and step through it in reverse.
for (var x = document.getElementById( fromID ).options.length - 1; x >= 0 ; x--)
With 10 options, this evaluates to
for (var x = 9; x >= 0 ; x--)
Now you'll always move the correct option and never encounter an error.
Great Post Adrian! I did notice that on the multiple select move, when moving items from right to left, the last item selected is not moved. I don't have a solution, but I thought I'd point that out.
@dexter.ba Close, but that only allows the function moveOption() to work on the 2nd form and not both. Thanks for submitting the comment, I'd forgotten I needed to fix this post and you put me on the right track.
I've updated the entry with code that will work for both single and multiple select menus. I knew I was forgetting something when I posted the entry. Updates are marked.
<a href="http://www.markireland.com.au/blog/client/index.cf...;
>order-a-slushie</a>
Again, great post otherwise!
http://www.massimocorner.com/libraries/spry/linked...
Not sure if it would fit your needs. Hope it could help somewhat
Massimo
if (idx != "") should be
if (idx >=0)
and moving the last item in the list should now work:)
I've updated the entry with code that will work for both single and multiple select menus. I knew I was forgetting something when I posted the entry. Updates are marked.