views:

1604

answers:

4

I have a HTML select list with quite a few (1000+) names. I have a javascript in place which will select the first matching name if someone starts typing. This matching looks at the start of the item:

var optionsLength = dropdownlist.options.length;
  for (var n=0; n < optionsLength; n++)
  {
    var optionText = dropdownlist.options[n].text;
    if (optionText.indexOf(dropdownlist.keypressBuffer,0) == 0)
    {
      dropdownlist.selectedIndex = n;
      return false; 
    }
  }

The customer would like to have a suggest or autofilter: typing part of a name should 'find' all names containing that part. I've seen a few Google Suggest like options, most using Ajax, but I'd like a pure javascript option, since the select list is already loaded anyway. Pointers anyone?

+2  A: 

Change

if (optionText.indexOf(dropdownlist.keypressBuffer,0) == 0)

to

if (optionText.indexOf(dropdownlist.keypressBuffer) > 0)

To find dropdownlist.keypressBuffer anywhere in the optionText.

MDCore
While this will select the first option to contain the key pressed, it fails to filter results based on more then 1 keypress.
edosoft
+2  A: 

I would set up a cache to hold the options inside my select. And instead of filtering options in the select, I would clear the select, and re-populate it with matched options.

Pseudo-code galore:

onLoad:
    set cache

onKeyPress:
    clear select-element
    find option-elements in cache
    put found option-elements into select-element

Here's a little POC I wrote, doing filtering on selects from what is selected in another select--in effect chaining a bunch of selects together.

Perhaps it can give you a few ideas:

function selectFilter(_maps)
{
    var map = {};


    var i = _maps.length + 1; while (i -= 1)
    {
        map = _maps[i - 1];


        (function (_selectOne, _selectTwo, _property)
        {
            var select = document.getElementById(_selectTwo);
            var options = select.options;
            var option = {};
            var cache = [];
            var output = [];


            var i = options.length + 1; while (i -= 1)
            {
                option = options[i - 1];

                cache.push({
                    text: option.text,
                    value: option.value,
                    property: option.getAttribute(_property)
                });
            }


            document.getElementById(_selectOne).onchange = function ()
            {
                var selectedProperty = this
                                       .options[this.selectedIndex]
                                       .getAttribute(_property);
                var cacheEntry = {};
                var cacheEntryProperty = undefined;


                output = [];

                var i = cache.length + 1; while (i -= 1)
                {
                    cacheEntry = cache[i - 1];

                    cacheEntryProperty = cacheEntry.property;

                    if (cacheEntryProperty === selectedProperty)
                    {
                        output.push("<option value=" + cacheEntry.value + " "
                        _property + "=" + cacheEntryProperty + ">" +
                        cacheEntry.text + "</option>");
                    }
                }

                select.innerHTML = output.join();
            };
        }(map.selectOne, map.selectTwo, map.property));
    }
}


$(function ()
{
    selectFilter([
        {selectOne: "select1", selectTwo: "select2", property: "entityid"},
        {selectOne: "select2", selectTwo: "select3", property: "value"}
    ]);
});
roosteronacid
+2  A: 

The YUI libraries have a library for this sort of functionality, called AutoComplete.

The DataSource for AutoComplete can be local javascript objects, or can be easily switched to Ajax if you change your mind.

The YUI components are pretty customizable with a fair bit of functionality.

Edit: I'm not sure if you can get it to work with a select box as required by the question though. Might be possible.

Bazman
Although I swear by jQuery, this seems like a good solution. A good read: http://stackoverflow.com/questions/176324/why-does-everyone-like-jquery-more-than-prototypescriptaclous-or-mootools-or-wh
roosteronacid
I'll take a look at YUI, thanks
edosoft
+1  A: 

use this filter script http://www.barelyfitz.com/projects/filterlist/

vegatron
Excellent, I'll use this
edosoft