Google Answers Logo
View Question
 
Q: Force an HTML Form SELECT field to drop down using JavaScript ( No Answer,   0 Comments )
Question  
Subject: Force an HTML Form SELECT field to drop down using JavaScript
Category: Computers > Programming
Asked by: mr_zorg-ga
List Price: $20.00
Posted: 14 May 2004 13:27 PDT
Expires: 24 May 2004 11:43 PDT
Question ID: 346484
Given the following example HTML page, how can I force the cbxSelect
box to drop down and show its contents when the user starts typing? 
The current example works in Netscape 6, 7, Mozilla and IE 5.x & 6,
and so should the answer.

<html>
<head>
<title>Editable Select Box</title>
<script type="text/javascript">
    function setSelectionRange(input, selectionStart, selectionEnd)
    {
        if (input.setSelectionRange)
        {
            input.focus();
            input.setSelectionRange(selectionStart, selectionEnd);
        }
        else if (input.createTextRange)
        {
            var range = input.createTextRange();
            range.collapse(true);
            range.moveEnd('character', selectionEnd);
            range.moveStart('character', selectionStart);
            range.select();
        }
    }

    function getKey(e)
    {
        // have to check undefined as String() if you want it to work in IE5 on Mac
        return ((String(e.which) == "undefined") ? e.keyCode : e.which);
    }

    function cbxMatch(edit, select, value, start, next)
    {
        var vl = value.toLowerCase();
        if (next)  // forwards 
        {
            for (var i = (start + 1), il = select.options.length; i < il; i++)
            {
                var o = select.options[i];
                var ov = o.text;
                ov = (ov ? ov : "");
                ovl = ov.toLowerCase();
                if (ovl.substring(0, vl.length) == vl)
                {
                    edit.value = ov;
                    setSelectionRange(edit, value.length, ov.length);
                    select.selectedIndex = o.index;
                    return i;
                }
            }
        }
        else  // backwards
        {
            for (var i = (start - 1); i >= 0; i--)
            {
                var o = select.options[i];
                var ov = o.text;
                ov = (ov ? ov : "");
                ovl = ov.toLowerCase();
                if (ovl.substring(0, vl.length) == vl)
                {
                    edit.value = ov;
                    setSelectionRange(edit, value.length, ov.length);
                    select.selectedIndex = o.index;
                    return i;
                }
            }
        }
        return start;
    }

    function cbxSelectChange()
    {
        var f = document.frm;
        f.cbxText.value = f.cbxSelect.options[f.cbxSelect.selectedIndex].text;
    }

    var allowfocus = false;
    var textkey = false;
    var lastmatch = -1;
    var lastval = "";

    function cbxUnmatch(edit)
    {
        if (lastmatch != -1)
        {
            setSelectionRange(edit, lastval.length, lastval.length);
            lastmatch = -1;
        }
        lastval = edit.value;
        lastval = (lastval ? lastval : "");
    }

    function cbxTextKeyPress(e)
    {
        var k = getKey(e);
        textkey = ((k >= 32) && (k <= 126));
    }

    function cbxTextKeyUp(e)
    {
        var k = getKey(e);
        var f = document.frm;
        if (textkey)
        {
            textkey = false;
            lastval = f.cbxText.value;
            lastval = (lastval ? lastval : "");
            lastmatch = cbxMatch(f.cbxText, f.cbxSelect, lastval, -1, true);
        }
        else
        {
            switch (k)
            {
                case 38:  // up arrow
                {
                    // prev match
                    lastmatch = cbxMatch(f.cbxText, f.cbxSelect,
lastval, lastmatch, false);
                    break;
                }
                case 40:  // down arrow
                {
                    // next match
                    lastmatch = cbxMatch(f.cbxText, f.cbxSelect,
lastval, lastmatch, true);
                    break;
                }
                case 8:   // backspace
                case 27:  // escape
                case 35:  // end
                case 36:  // home
                case 37:  // left arrow
                case 39:  // right arrow
                case 45:  // insert
                case 46:  // delete
                {
                    // unmatch if editing
                    cbxUnmatch(f.cbxText);
                    break;
                }
            }
        }
    }

    function shunt()
    {
        var f = document.frm;
        if (!allowfocus)
        {
            f.cbxText.focus();
        }
    }
</script>
</head>
<body>
<form name="frm">
<br>
<br>
Select from the list or type in the box:<br>
<select name="cbxSelect" style="position: absolute; width: 219px;
clip:rect(auto auto auto 200px);" onChange="cbxSelectChange()"
onFocus="shunt()" onMouseOver="allowfocus = true;"
onMouseOut="allowfocus = false;">
<option>Corvette</option>
<option>Viper</option>
<option>Mustang</option>
<option>BMW</option>
<option>Ferrari</option>
</select>
<input name="cbxText" style="position: absolute; width: 200px;"
onKeyPress="cbxTextKeyPress(event)" onKeyUp="cbxTextKeyUp(event)">
<br>
<br>
</form>
</body>
</html>

Request for Question Clarification by passive-ga on 17 May 2004 08:00 PDT
I'm not certain exactly what you are asking.
Do you want to programmatically open up the select box? I'm fairly
certain this can't be done, at least not in a cross browser fashion.

What is the purpose of this behaviour, perhaps something similar can
be accomplished in a different way?
If this behaviour itself it vitally important, you might be able to
fake it with custom select box created with CSS and javascript.

Clarification of Question by mr_zorg-ga on 17 May 2004 09:16 PDT
passive-ga,

Your first instict is correct -- I want to programatically open up the
select box.  I agree that it probably can't be done, that's what all
my research came up with too.  I'm hoping someone here can prove me
wrong.  :-)

The reason I want this behavior is so that the user can see potential
matches in the list as they start typing.

Emulating this behavior through CSS, DHTML, etc., is certainly an
option, but (so far anyway) this seems like a simpler solution and
neatly solves the problem of making the dropdown button have a native
look and feel.  If I were to emulate a select box, the button would,
no doubt, be a GIF...

Thanks!

Request for Question Clarification by passive-ga on 18 May 2004 12:42 PDT
I thought that might be what you were after.
As a thought, perhaps a multiple select box would do the trick?
If you wanted to get particularily fancy you could even resize the
multiple select box dynamically to adjust to the number of items that
matched the typed in string.
It's an idea that intrigues me, so perhaps I will put something
together, and you can let me know if it works for you.

Clarification of Question by mr_zorg-ga on 18 May 2004 14:47 PDT
In the mean time, I've been refining this example and it is much
better now  (abstracted as a JavaScript object).  Though it still
can't do the auto-dropdown thing.  I am willing to accept a DHTML
based solution if you can hack it into this example and it doesn't
break functionality on the browsers specified above.  My new example
includes limited support for Netscape 4.7 as well (this auto-dropdown
needn't work on Netscape 4.7, but should not break it).  Hope this
makes sense.

You can download the new example here: 
http://www.dropload.com/redeem.php?t=92f52867c08b9ee716e75ffc66d690b5

P.S.  Feel free to use this code in your own projects, I'd like to see
others benefit from this work.

Clarification of Question by mr_zorg-ga on 24 May 2004 11:43 PDT
Since it does not appear to be possible to do what I was looking for,
I've gone ahead and coded my own from scratch using DHTML...  So, I no
longer need this answer.  Closing it...
Answer  
There is no answer at this time.

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy