As Web Developer we are always striving to give our users an experiance that will make the technology they are using as transparent as possible. Not having to put a lot of thought into how to use the interfaces we create and just using that technology to interact with the web. As always there are those time where there is soo much information on a page or that the user has to interact with that things be come trouble some.

One of those areas is often the select box. Even though it has a nice tidy little package we as developers some time like to cram a little bit too much in there then add to that a user needing to select multiple values and you end up leaving the users to sort through a lot more information then is needed.

After all I am sure that the user knows what values they want to select in most cases and really doesn't need to see all the values. How do we give them just the values they want? With a single select box its easy enough and most usere know you can just type the value they are looking for and the selct box will work its magic,but this doesn't work so well with a multiple select box.

I begin with the HTML parts, a select set up as multi with a lot of values (list of 600+ countries should work) a text input and a div to hold the results.

view plain print about
1<input id="autocomplete" style="width: 48%;" name="autocomplete" type="text">
2    <select id="Country" style="width: 48%;" multiple="multiple" name="Country" size="4">
3        <option value="UNITED STATES">UNITED STATES</option>
4        <option value="AFGHANISTAN">AFGHANISTAN</option>
5        <option value="AKSAI CHIN REGION">AKSAI CHIN REGION</option>
6        <option value="ALBANIA">ALBANIA</option>
7        <option value="ALGERIA">ALGERIA</option>
8        <option value="AMERICAN SAMOA">AMERICAN SAMOA</option>
9        <option value="ANDORRA">ANDORRA</option>
10    </select>

This gives us our base to begin working towords our goal. Next step was searching the text box values from the text box, onkeyup should handle this for us.

view plain print about
1<input id="autocomplete" onkeyup="acomplete(this,'Country','aoResults')" name="autocomplete" type="text">

As you can see I am now calling the autocomplete javascript function and passing it some paramaters. The input object to get the value they are typing, the ID of the select box we are targeting and the ID of the div that holds our results.

Below is the autocomple function and I will spare you the going over it line by line and just let you read the comments in areas where I thought some explination was warranted.

view plain print about
1function acomplete(obj,listId,results,autocomplete) {
2        var list = document.getElementById(listId);
3        var curVal = "^"+obj.value.toLowerCase();
4        var results = document.getElementById(results);
5        //if for any reason the result list is still open here close
6        //it since this is a fresh start.
7        if(document.getElementById('resultList') != null) {
8            results.removeChild(document.getElementById('resultList'));
9        }
10        var ul = document.createElement('ul');
11        ul.id = 'resultList';
12        ul.onmouseout = function(e) {
13            if (!e) var e = window.event;
14            var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
15            while (reltg.tagName != 'BODY'){
16                if (reltg.id == this.id){return;}
17                reltg = reltg.parentNode;
18            }
19            results.removeChild(this);
20        }
21        for(i=0;i<list.length;i++) {
22            //THis will search through the values
23            var listVal = list[i].value.toLowerCase();
24            //Use this if you want to search through displayed value
25            //var listVal = list[i].innerHTML.toLowerCase();
26            if(listVal.search(curVal) >
= 0) {
27                var li = document.createElement('li');
28                //mouse over for the li element
29                li.onmouseover = function() {
30                    this.className = 'on'
31                }
32                //mouse out for the li element
33                li.onmouseout = function() {
34                    this.className = 'off';
35                }
36                //click on the list element.
37                li.onclick = function() {
38                    //here we loop over the list again and we
39                    //looked for the item we clicked on and
40                    //when it matches we select the item if its
41                    //not selected and deselecte it if its selected
42                    var list = document.getElementById(listId);
43                    for (s = 0; s < list.length; s++) {
44                        var listVal = list[s].value
45                        //var listVal = list[s].innerHTML
46                        if (listVal == this.innerHTML) {
47                            if (list[s].selected == true) {
48                                list[s].selected = false;
49                            } else {
50                                list[s].selected = true;
51                            }
52                        }
53                    }
54                    //Once have our values we destroy the list and empty the text input
55                    results.removeChild(document.getElementById('resultList'));
56                    ob j.value = '';
57                }
58                //This portion creates the LI's for the UL and put
59                //the values we find into it.
60                var txt = document.createTextNode(list[i].value);
61                li.appendChild(txt);
62                ul.appendChild(li);
63            }
64        }
65        //when we are all done we append the UL to the results div and show it to the user.
66        results.appendChild(ul);
67    }

A fairly simple solution for the problem of large multiple select lists. This works in all the latest browsers with no issues. If you need this to work in IE 6 you will need to hide the select box when you show your matches due to the Z-index Issue with IE 6.

Head on over to the Demo and try it out!