Link to home
Start Free TrialLog in
Avatar of espn78
espn78

asked on

Filtering a listbox

I have this code which filters a listbox
form a textbox.

<HTML>
<HEAD>
    <TITLE>JavaScript Toolbox - Auto-Complete</TITLE>
<script>
function autoComplete (field, select, property, forcematch) {
    var found = false;
    for (var i = 0; i < select.options.length; i++) {
    if (select.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0) {
         found=true; break;
         }
    }
    if (found) { select.selectedIndex = i; }
    else { select.selectedIndex = -1; }
    if (field.createTextRange) {
         if (forcematch && !found) {
              field.value=field.value.substring(0,field.value.length-1);
              return;
              }
         var cursorKeys ="8;46;37;38;39;40;33;34;35;36;45;";
         if (cursorKeys.indexOf(event.keyCode+";") == -1) {
              var r1 = field.createTextRange();
              var oldValue = r1.text;
              var newValue = found ? select.options[i][property] : oldValue;
              if (newValue != field.value) {
                   field.value = newValue;
                   var rNew = field.createTextRange();
                   rNew.moveStart('character', oldValue.length) ;
                   rNew.select();
                   }
              }
         }
    }

</script>
</HEAD>
<BODY BGCOLOR=#FFFFFF LINK="#00615F" VLINK="#00615F" ALINK="#00615F">
<FORM>

<B>Auto-Complete</B><BR>
Start typing a name in the input box that matches a name in the drop-down...<BR>
<INPUT TYPE="text" NAME="input1" VALUE="" ONKEYUP="autoComplete(this,this.form.options,'value',true)">
<SELECT NAME="options"
onChange="this.form.input1.value=this.options[this.selectedIndex].value">
    <OPTION VALUE="adam">adam
    <OPTION VALUE="george">george
    <OPTION VALUE="matt">matt
    <OPTION VALUE="bill">bill
    <OPTION VALUE="greg">greg
    <OPTION VALUE="bob">bob
    <OPTION VALUE="david">david
    <OPTION VALUE="ryan">ryan
</SELECT>

</FORM>

</BODY>
</HTML>



can anyone help me with this ?
how easy it is to filter the results at the listbox in order to hide all the other values (exaple: when i press "g") and display only the values starts with G.

thnx
Avatar of Zvonko
Zvonko
Flag of North Macedonia image

How about this:


<HTML>
<HEAD>
   <TITLE>JavaScript Toolbox - Auto-Complete</TITLE>
<script>
function autoComplete (field, select, property, forcematch) {
   var found = false;
   for (i = select.options.length - 1; i > -1; i--) {
     if (select.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0)
        found=true;
      else
        select.options[i]=null;
   }
   if (found) { select.selectedIndex = 0; }
   else { select.selectedIndex = -1;
     select.options.length=selOpts.length;
     for(i=0;i<selOpts.length;i++)
       select.options[i]=new Option(selOpts[i][0], selOpts[i][1]);
   }
   if (field.createTextRange) {
        if (forcematch && !found) {
             field.value=field.value.substring(0,field.value.length-1);
             return;
             }
        var cursorKeys ="8;46;37;38;39;40;33;34;35;36;45;";
        if (cursorKeys.indexOf(event.keyCode+";") == -1) {
             var r1 = field.createTextRange();
             var oldValue = r1.text;
             var newValue = found ? select.options[0][property] : oldValue;
             if (newValue != field.value) {
                  field.value = newValue;
                  var rNew = field.createTextRange();
                  rNew.moveStart('character', oldValue.length) ;
                  rNew.select();
                  }
             }
        }
   }
var selOpts = new Array();
function initSel(theSel){
 for(i=0;i<theSel.options.length;i++)
  selOpts[i]=[theSel.options[i].value,theSel.options[i].text];
}
</script>
</HEAD>
<BODY BGCOLOR=#FFFFFF LINK="#00615F" VLINK="#00615F" ALINK="#00615F" onLoad="initSel(document.forms[0].options)">
<FORM>

<B>Auto-Complete</B><BR>
Start typing a name in the input box that matches a name in the drop-down...<BR>
<INPUT TYPE="text" NAME="input1" VALUE="" ONKEYUP="autoComplete(this,this.form.options,'value',true)">
<SELECT NAME="options"
onChange="this.form.input1.value=this.options[this.selectedIndex].value">
   <OPTION VALUE="adam">adam
   <OPTION VALUE="george">george
   <OPTION VALUE="matt">matt
   <OPTION VALUE="bill">bill
   <OPTION VALUE="greg">greg
   <OPTION VALUE="bob">bob
   <OPTION VALUE="david">david
   <OPTION VALUE="ryan">ryan
</SELECT>

</FORM>

</BODY>
</HTML>


nice idea :-)

I guess the textRange stuff does not work in either NS6 nor MSIE. However, I changed your code a bit (see text below).

<HTML>
<HEAD>
<TITLE>JavaScript Toolbox - Auto-Complete</TITLE>
<script>
function autoComplete (field, oSel, property, forcematch) {
   var found = -1;
   for (var i = 0; i < oSel.options.length; i++) {
     if (oSel.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0) {
        oSel.options[i].style.display="";
        if (found == -1) found=i;
     } else {
        oSel.options[i].style.display="none";
     }
   }
   if (found>=0) { oSel.options[found].selected=true; }
// little debugger, see DIV below
if (found>=0) document.getElementById("dbg").innerHTML='i:'+i+", found:"+found+", prop:"+property
}
</script>
</HEAD>
<BODY BGCOLOR=#FFFFFF LINK="#00615F" VLINK="#00615F" ALINK="#00615F">
<FORM>
<B>Auto-Complete</B><BR>
Start typing a name in the input box that matches a name in the drop-down...<BR>
<INPUT TYPE="text" NAME="input1" VALUE="" ONKEYUP="autoComplete(this,this.form.selOptions,'value',true)">
<SELECT NAME="selOptions"
onChange="this.form.input1.value=this.options[this.selectedIndex].value">
   <OPTION VALUE="adam">adam
   <OPTION VALUE="george">george
   <OPTION VALUE="matt">matt
   <OPTION VALUE="bill">bill
   <OPTION VALUE="greg">greg
   <OPTION VALUE="bob">bob
   <OPTION VALUE="david">david
   <OPTION VALUE="ryan">ryan
   <OPTION VALUE="geoffrey">geoffrey
</SELECT>
</FORM>
<div id="dbg"></div>
</BODY>
</HTML>

1. renamed a couple of your variables and HTML elements, using "options" may conflict with the existing .options property of a select list, also "select" is a bad name for a select list as there's a select() method and so on.
Avoid such "common" names, they're often the reason for some code not to work as expected, expect the programmers of a browser to came up with that idea before :-) that's why we have window.document and not thebrowserbox.thestuffinside

I also added "geoffrey" to the name list to habe twe starting with "geo" (don't know if the name's spelled correctly)

What happens:
found will contain the item no. of the option that matched first and only the first will be taken. It'll be the selected on in the list afterward. NO BREAK here.
the for() loop hides all options that don't match and keeps the otheres visible, this way visually reducing the available entries to those starting with the letters entered so far.

I removed the createRange part as I don't think this will work as intended - at least it didn't seem to do anything here. instead the first matching option will be selected.

Drawback: MSIE5.5 and Opera7 did not "hide" the options, whereas Mozilla did. Maybe MSIE6 will do it as well if goven a DOCTYPE XHTML, I don't have IE6 here.

CirTap
hmm. should have reloaded the question before posting :-)
now I finally see what the range's supposed to do.
It does not "restore" the List when I type back, eg. change "geo" to "ge", there's only george left in the list. The full list only reappears when I emtpy the textbox.
Avatar of espn78
espn78

ASKER

i see it's difficult that way

ok, let's make it easier.
forget the auto-complete..

how hard it is to be built with a submit button ?
for exaple I type 1 or 2 chars in the textbox and then submit the value in order to filter the listbox with the right results.

Avatar of espn78

ASKER

i see it's difficult that way

ok, let's make it easier.
forget the auto-complete..

how hard it is to be built with a submit button ?
for exaple I type 1 or 2 chars in the textbox and then submit the value in order to filter the listbox with the right results.

Avatar of espn78

ASKER

i see it's difficult that way

ok, let's make it easier.
forget the auto-complete..

how hard it is to be built with a submit button ?
for exaple I type 1 or 2 chars in the textbox and then submit the value in order to filter the listbox with the right results.

Avatar of espn78

ASKER

..but if the value don't not exist the list box will return the latest previous one..
Avatar of espn78

ASKER

..but if the value don't not exist the list box will return the latest previous one..
Avatar of espn78

ASKER

..but if the value don't not exist the list box will return the latest previous one..
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

PAQ with points refunded

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jAy
EE Cleanup Volunteer
ASKER CERTIFIED SOLUTION
Avatar of Computer101
Computer101
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial