In jQuery UI v1.8rc3, the autocomplete widget accepts a source option which can be either a string, an array, or a callback function. If it's a string, autocomplete does a GET on that URL to get options/suggestions. If an array, autocomplete does a search, as you pointed out, for the presence of the typed chars in any position in the terms of the array. The final variant is what you want - the callback function.

From the autocomplete documentation:

The third variation, the callback, provides the most flexibility, and can be used to connect any data source to Autocomplete. The callback gets two arguments:

• A request object, with a single property called "term", which refers to the value currently in the text input. For example, when the user entered "new yo" in a city field that is set to do autocomplete, the request.term will hold "new yo".
• A response function, a callback which expects a single argument to contain the data to suggest to the user. This data should be filtered based on the provided term, and must be an array in the format allowed for simple local data: String-Array or Object-Array with label/value/both properties.

Example code:

var wordlist= [ "about", "above", "across", "after", "against",
                "along", "among", "around", "at", "before", 
                "behind", "below", "beneath", "beside", "between", 
                "beyond", "but", "by", "despite", "down", "during", 
                "except", "for", "from", "in", "inside", "into", 
                "like", "near", "of", "off", "on", "onto", "out", 
                "outside", "over", "past", "since", "through", 
                "throughout", "till", "to", "toward", "under", 
                "underneath", "until", "up", "upon", "with", 
                "within", "without"] ; 

$("#input1").autocomplete({
    // The source option can be an array of terms.  In this case, if
    // the typed characters appear in any position in a term, then the
    // term is included in the autocomplete list.
    // The source option can also be a function that performs the search,
    // and calls a response function with the matched entries.
    source: function(req, responseFn) {
        var re = $.ui.autocomplete.escapeRegex(req.term);
        var matcher = new RegExp( "^" + re, "i" );
        var a = $.grep( wordlist, function(item,index){
            return matcher.test(item);
        });
        responseFn( a );
    }
});

A few key points:

  • the call to $.ui.autocomplete.escapeRegex(req.term); That escapes the search term so that any regex-meaningful terms in the text typed by the user are treated as plain text. For example, the dot (.) is meaningful to regex. I learned of this escapeRegex function by reading the autocomplete source code.
  • the line with new Regexp(). It specifies a regexp beginning with ^ (Circumflex), which implies, it will match only when the typed characters appear at the beginning of the term in the array, which is what you wanted. It also uses the "i" option which implies a case-insensitive match.
  • the $.grep() utility just calls the provided function on each term in the provided array. The function in this case simply uses the regexp to see if the term in the array is a match for what was typed.
  • finally, the responseFn() is invoked with the result of the search.

working demo: http://jsbin.com/ezifi

what it looks like:

alt text

Just a note: I find the documentation on autocomplete to be pretty immature at this point. I didn't find examples that did this, and I couldn't find working doc on which .css files were necessary or which .css classes would be used. I learned all this from inspecting the code.

See also, how can I custom-format the Autocomplete plug-in results?


thx cheeso for intrducing jsbin.com,

i extended your code to support first- and lastname matches, too.

  $("#input1").autocomplete({
      source: function(req, responseFn) {
          addMessage("search on: '" + req.term + "'<br/>");

          var matches = new Array();
          var needle = req.term.toLowerCase();

          var len = wordlist.length;
          for(i = 0; i < len; ++i)
          {
              var haystack = wordlist[i].toLowerCase();
              if(haystack.indexOf(needle) == 0 ||
                 haystack.indexOf(" " + needle) != -1)
              {
                  matches.push(wordlist[i]);
              }
          }

          addMessage("Result: " + matches.length + " items<br/>");
          responseFn( matches );
      }
  });

demo: http://jsbin.com/ufimu3/

type 'an' or 're'


I use the autocomplete from devbridge. http://www.devbridge.com/projects/autocomplete/jquery/

It matches on the beginning characters, only.

alt text

As far as matching based on first name or last name, you'd just have to supply a lookup list with the first and last name.

Example usage:

  var wordlist = [
      'January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November',
      'December' ]; 

      var acOptions = {
          minChars:2,
          delimiter: /(,|;)\s*/, // regex or character
          maxHeight:400,
          width:300,
          zIndex: 9999,
          deferRequestBy: 10, // miliseconds

          // callback function:
          onSelect: function(value, data){
              //$('#input1').autocomplete(acOptions);
              if (typeof data == "undefined") {
                  alert('You selected: ' + value );
              }else {
                  alert('You selected: ' + value + ', ' + data);
              }
          },

          // local autosuggest options:
          lookup: wordlist
      };

The lookup option that you pass to initialize the autocomplete control can be a list, or an object. The above showed a simple list. If you want some data attached to the suggestions that get returned, then make the lookup option an object, like this:

var lookuplist = {
    suggestions:   [ "Jan", "Feb", "Mar", "Apr", "May" ],
    data :         [ 31, 28, 31, 30, 31, ]
};

If you want to search the beginning of each word in the string, a more elegant solution to henchman's is to take cheeso's but just use the regexp word boundary special character:

var matcher = new RegExp( "\\b" + re, "i" );

Example: http://jsbin.com/utojoh/2 (try searching for 'bl')