Autocomplete with Combobox
Tom M. Yeh, Potix Corporation
December 13, 2006
Version
Applicable to ZK 2.0 and later.
The Issue
The autocomplete feature is getting popular these days. Here I illustrate how to
use the onChanging event to implement it with a combobox.
A Solution
One of the simplest way to implement the autocomplete feature is to listen
the onChanging event, and then alter the child components,
comboitem, dynamically
based on the content that the user is entering.
In the following codes, I assumed we have a dictionary consisting of all possible suggestions that are used to speed up user's entry. In a real application, you might load the suggestions from a database or a Web service.
The Source Codes
public class AutoComplete extends Combobox { public AutoComplete() { refresh(""); //init the child comboitems } public AutoComplete(String value) { super(value); //it invokes setValue(), which inits the child comboitems } public void setValue(String value) { super.setValue(value); refresh(value); //refresh the child comboitems } /** Listens what an user is entering. */ public void onChanging(InputEvent evt) { refresh(evt.getValue()); } /** Refresh comboitem based on the specified value. */ private void refresh(String val) { int j = Arrays.binarySearch(_dict, val); if (j < 0) j = -j-1; Iterator it = getItems().iterator(); for (int cnt = 10; --cnt >= 0 && j < _dict.length && _dict[j].startsWith(val); ++j) { if (it != null && it.hasNext()) { ((Comboitem)it.next()).setLabel(_dict[j]); } else { it = null; new Comboitem(_dict[j]).setParent(this); } } while (it != null && it.hasNext()) { it.next(); it.remove(); } } private static String[] _dict = { //alphabetic order "abacus", "accuracy", "acuity", "adage", "afar", "after", "apple", "bible", "bird", "bingle", "blog", "cabane", "cape", "cease", "cedar", "dacron", "definable", "defacto", "deluxe", "each", "eager", "effect", "efficacy", "far", "far from", "girl", "gigantean", "giant", "home", "honest", "huge", "information", "inner", "jump", "jungle", "jungle fever", "kaka", "kale", "kame", "lamella", "lane", "lemma", "master", "maxima", "music", "nerve", "new", "number", "omega", "opera", "pea", "peace", "peaceful", "rock", "sound", "spread", "student", "super", "tea", "teacher", "unit", "universe", "vector", "victory", "wake", "wee", "weak", "xeme", "yea", "yellow", "zebra", "zk", }; }The
isChangingBySelectBackMethodZK 2.2 introduced a new method called
isChangingBySelectBackto theorg.zkoss.zk.ui.event.InputEventclass. It denotes whether the onChanging event is caused by user's selecting one of the combo items. When implementing autocomplete, it is better not to filter out unmatched suggestions when user presses UP and DOWN keys to select from the list of suggestions. In other words, it is more user friendly if theonChangingmethod is as follows.public void onChanging(InputEvent evt) { if (!evt.isChangingBySelectBack()) refresh(evt.getValue()); }
Summary
As illustrated, it is easy to provide autocomplete with the onChanging event.
Though you have to write some codes, the algorithm to generate the proper list
of suggestions can be as sophisticated as you want.

