In most of the web pages we come accross a requirement of selecting multiple items form an list box. One of the best approach is to provide
two list boxes as shown in the figure below
Here user can easily select list items and move them back and forth. If we want improve the usability of your web page then we can provide following options
- On DoubleClick of an item move it to the other list box.
- On Enter key of an item move it to the other list box.
- In some cases selected items may have oders so here we may need move up and down.
- An increamental search for a list item can boost the usability to the web page.
Here is a common and simple function to move the list itesm
//Where parameter are
//src - id of Source Listbox Control
//dest - id of Destination Listbox Control
//strMessage - What message need to be displayed when listitem is not selected.
//bFlag - true if all items to be moved and false if only seleted items to be moved
function Move(src,dest,strMessage,bFlag)
{
var opt, o = 0;
src = document.getElementById(src);
dest = document.getElementById(dest);
//Check is list box is empty
if(src.length<1)
{
alert(strMessage + " is empty");
return;
}
//Check are all items to be moved or not
if(bFlag)
{
while (opt = src[0])
{
var obj = new Option( src.options[0].text , src.options[0].value ) ;
dest.options[dest.length] = obj
src[0] = null;
}
return;
}
//Check if only selected items should be moved then whether any listitem is selected
if(src.selectedIndex == -1)
{
alert("Please select item from " + strMessage );
return;
}
//Move all seleced list items
while (opt = src[o++])
{
if (opt.selected)
{
var obj = new Option( src.options[src.selectedIndex].text , src.options[src.selectedIndex].value ) ;
dest.options[dest.length] = obj
src[o-1] = null;
o--;
}
}
}
And here is a function which will handle keypress event
//Where parameter are
//src - id of Source Listbox Control
//dest - id of Destination Listbox Control
//strMessage - What message need to be displayed when listitem is not selected.
function fnHandleKey(evt,src,dest,strMessage)
{
evt = evt window.event;
var keycode = evt.which ? evt.which : evt.keyCode;
if(keycode == 13)
{
Move(src,dest,strMessage,false);
}
}
And here is a function fot moving list items up/down
//Moving Listitems Up/Down
//Parameters
//select - Object as ListBox
//bFlag is true when you want to move down
//bFlag is false when you want to move up
function MoveUpDown(select,strMessage,bFlag)
{
select = document.getElementById(select);
var i=0;
if(bFlag)
{
for(i=select.length-1;i>=0;i--)
{
if(select.options[i].selected == true)
{
var swapOption = new Object();
//check whether selected option is last
if(i!=select.length-1)
{
//Swap the positions of selected option and next option
//Copy all the propertis option to be moved
swapOption.text = select.options[i+1].text;
swapOption.value = select.options[i+1].value;
swapOption.selected = select.options[i+1].selected;
//Replace the properties
for (var property in swapOption)
select.options[i+1][property] = select.options[i][property];
for (var property in swapOption)
select.options[i][property] = swapOption[property];
}
}
}
}
else
{
for(i=0;i<select.length;i++)
{
if(select.options[i].selected == true)
{
//check whether selected option is first
if(i!=0)
{
//Swap the positions of selected option and next option
//Copy all the propertis option to be moved
var swapOption = new Object();
swapOption.text = select.options[i-1].text;
swapOption.value = select.options[i-1].value;
swapOption.selected = select.options[i-1].selected;
//Replace the properties
for (var property in swapOption)
select.options[i-1][property] = select.options[i][property];
for (var property in swapOption)
select.options[i][property] = swapOption[property];
}
}
}
}
}
To provide an incremental search on list box you will have to just add the behaviour to the select html tag or create a style for the select.
This can be achieved by creating one HTC file and the code for the same is as below
<public:component>
<script>
<!--
/*------------------------------------------------
Event Handler Function
---------------------------------------------------*/
function setSelectedIndex()
{
var obj = window.event.srcElement;
if(obj.type.toLowerCase().indexOf('select') == -1)
{
return true;
}
if(window.event.keyCode == 27)
{
obj.selectedString = '';
obj.selectedIndex = -1;
}
else if(window.event.keyCode == 9 window.event.keyCode == 38 window.event.keyCode == 40 window.event.ctrlKey window.event.altKey window.event.type.toLowerCase() == 'blur') // tab, arrow-up, arrow-down, ctrl, or alt keys
{
obj.selectedString = '';
//obj.fireEvent("change");
return true;
}
else
{
if(typeof obj.selectedString == 'undefined') obj.selectedString = '';
if(window.event.keyCode == 8) // backspace
obj.selectedString = (obj.selectedString.length != 0) ? obj.selectedString.substring(0, obj.selectedString.length - 1) : '';
else
obj.selectedString = obj.selectedString + String.fromCharCode(window.event.keyCode);
var newSelectedIndex = -1;
for(var i = 0; i < obj.options.length; i++)
{
if(obj.options[i].text.toLowerCase().indexOf(obj.selectedString.toLowerCase()) == 0)
{
newSelectedIndex = i;
break;
}
}
if(newSelectedIndex != -1)
obj.selectedIndex = newSelectedIndex;
else
{
obj.selectedString = String.fromCharCode(window.event.keyCode);
obj.fireEvent("onchange");
return true;
}
}
obj.fireEvent("onchange");
return true;
}
// -->
</script>
<public:attach event="onkeydown" onevent="setSelectedIndex()"/>
<public:attach event="onblur" onevent="setSelectedIndex()"/>
</public:component>
Now to acctach this behaviour to the select you can use where the above code is palced in "keydown.htc" and the class "selectIncSearch" is specified in the HTML file for the all the html select tags.
.selectIncSearch
{
behavior:url(keydown.htc);
}
If you want to look at the complete sample please click here to download.
In case of any problem or if the code is not functioning properly please feel free to write to me @ bharat.mane@gmail.com
Bharat Mane