SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : Lookup Lists II : Creating a Lookup List

Lookup lists are created by combining a standard textbox and listbox and associating them through their events. In the 4.0 browsers, the two events that are tracked are the onchange event on the listbox and the onkeyup event on the textbox. In the 3.0 browsers, the onfocus and onblur events are tracked. In the 3.0 browsers, whenever the textbox receives the focus a timer is started that is used to check the current value of the control. When the user leaves the textbox, the timer is turned back off. Using this timer we are able to simulate key events.

The following demonstrates the HTML necessary to create this example:

  <FORM>
    <TABLE><TR><TD>
      <INPUT TYPE="text" 
             NAME=textInput 
             SIZE=18 
             STYLE="width: 120pt" 
             ONFOCUS='if (!isDHTML) this._v=setTimeout("lookupItem(document.lForm.textInput, document.lForm.selectInput)",500)'"
             ONBLUR = 'if (!isDHTML) clearTimeout(this._v)'
             ONKEYUP="lookupItem(this,this.form.selectInput)">
    </TD><TD></TR><TR><TD>
      <SELECT SIZE=8 
             NAME=selectInput 
             STYLE="width: 120pt" 
             ONCHANGE="doSelectChange(this, this.form.textInput)">
        <OPTION VALUE="http://www.erols.com/jrule/dhtml">
          DHTML Demos
        </OPTION>
        <OPTION VALUE="http://www.dhtmlZone.com">
          DHTML Zone
        </OPTION>
        <OPTION VALUE="http://www.insideDHTML.com">
          Inside Dynamic HTML
        </OPTION>
        <OPTION VALUE="http://www.microsoft.com/sitebuilder">
          Microsoft Sitebuilders
        </OPTION>
        <OPTION VALUE="http://www.webCoder.com">
          Web Coder
        </OPTION>
        <OPTION VALUE="http://www.webMonkey.com">
          Web Monkey
        </OPTION>
        <OPTION VALUE="http://www.webReference.com">
          Web Reference
        </OPTION>
      </SELECT>
    </TD></TR></TABLE>
    <INPUT TYPE="Button" VALUE="Go" ONCLICK="goValue(this.form.selectInput)">
  </FORM>

In the SELECT listbox, the onchange event calls the doSelectChange function. This function takes two arguments. The first argument is the listbox itself, and the second argument is the textbox that needs to be updated. In the TEXTBOX element, the ONKEYUP event calls the lookupItem function and also takes two arguments. The first argument is the textbox itself, and the second argument is the listbox that is being searched. The ONFOCUS and ONBLUR events start the timer check in the 3.0 browsers. The 3.0 browsers are determined through object detection. Basically, if the browser does not support the layers or the all collection, it is assumed to be a 3.0 browser.

In both the listbox and textbox a CSS width is defined to force both the textbox and listbox to line up. The width property is defined by CSS1 to define the size of the element. Only Internet Explorer 4.0 supports this CSS1 property. In Netscape Navigator and the 3.0 browsers you need to approximate the width of the textbox using the SIZE attribute in relation to the size of the SELECT element. The TABLE around the elements is used for layout purposes. While Netscape does not honor the CSS width property, this property has an effect on the spacing of the form elements when specified outside of the table.

In this example, I used the VALUE field to specify a destination URL. When you click on the Go button, a new window is opened with the specified URL. You can customize and use the list text and its value based on your needs.

Code Review

The code in each of the functions is very simple and involves no browser detection. When the user selects an item from the listbox, the text of the listbox is copied to the textbox. This function works in all Javascript aware browsers:

  function doSelectChange(el,dest) {
    dest.value = el.options[el.selectedIndex].text
  }

The function that does the lookup is slightly more involved and is where we do quite a bit of browser detection. For the 3.0 browsers, we quickly reset the focus() to force the input boxes value property to be updated. The body of the function then matches the current input against the choices. The end of the function then resets the timer for 3.0 browsers ensuring this function is called again after a half-second. In 4.0 browsers, rather than use the timer, the onkeyup event is used to detect a change in value and to force a the code to do a new lookup.

    function doSelectChange(el,dest) {
      dest.value = el.options[el.selectedIndex].text
    }

    function lookupItem(el,dest) {
      if (!isDHTML) {
        el.blur(); el.focus()
      }
      var curValue = el.value.toLowerCase()
      var found = false
      var index = dest.selectedIndex
      var numOptions = dest.options.length
      var pos = 0
      while ((!found) && (pos < numOptions)) {
        found = (dest.options[pos].text.toLowerCase().indexOf(curValue)==0) 
        if (found) 
          index = pos
        pos++
      }
      if (found)
        dest.selectedIndex = index
      if (!isDHTML) 
        el._v = setTimeout("lookupItem(document.lForm.textInput, document.lForm.selectInput)",500)
    }

The Go button contains really simple code that navigates the user to the URL specified by the selected item's OPTION value:

    function goValue(el) {
      var where
      if (el.selectedIndex>-1) {
        where = el.options[el.selectedIndex].value
        window.open(where,"")
      }
    }

You can use similar techniques to build your own custom input controls out of standard HTML controls. Using our timer trick, you can even do real-time checking of the user's input in the 3.0 browsers. The last page provides easy access to all the code necessary to create the lookup list.