Combobox
Combobox
Employment/Purpose
Components: combobox and comboitem.
A combobox is a special text box that embeds a drop-down list. With comboboxes, users are allowed to select from a drop-down list, in addition to entering the text manually.
Example
<combobox>
<comboitem label="Simple and Rich"/>
<comboitem label="Cool!"/>
<comboitem label="Ajax and RIA"/>
</combobox>
Default Selection
<zk>
<zscript><![CDATA[
ListModelList model = new ListModelList(Arrays.asList(new String[] { "David",
"Thomas", "Steven" }));
]]></zscript>
<combobox model="${model}" onAfterRender="self.setSelectedIndex(2)"/>
</zk>
Mouseless Entry Combobox
- Alt+DOWN to pop up the list.
- Alt+UP or ESC to close the list.
- UP and DOWN to change the selection of the items from the list.
Live Data
Selectable
By specifying the selection, you can invoke the addSelection() to select a default value, For example,
<combobox id="combobox" width="100px">
<attribute name="onCreate"><![CDATA[
List list2 = new ArrayList();
list2.add("David");
list2.add("Thomas");
list2.add("Steven");
ListModelList lm2 = new ListModelList(list2);
lm2.addToSelection(lm2.get(0));
combobox.setModel(lm2);
]]></attribute>
</combobox>
[Since 5.0.4]
Properties
Autocomplete
By default, it will autocomplete your input with the first item in the list that has the same starting string in a case-insensitive way.
Autocomplete in a Brute-force Way
The straightforward way to implement the autocomplete feature is to listen to the onChanging event. For example,
<combobox>
<attribute name="onChanging"><![CDATA[
self.getChildren().clear(); //remove all children
for (String value: getMatched(event.getValue())
self.appendChild(new Comboitem(value));
]]></attribute>
</combobox>
Line 4: We assume getMatched() is an application-specific method that returns a collection of matched values.
Autocomplete by ListSubModel
To separate the data from the view (Combobox) better, we can implement ListSubModel and set it to Combobox. There are 2 ways:
- Use SimpleListModel.
Unlike ListModelList and others, SimpleListModel implements ListSubModel by default. You can use SimpleListModel directly but it handles only an array of data.
- Convert ListModel object with ListModels.toListSubModel(ListModel)
The methods convert ListModel to ListSubModel that proxies the original ListModel.
For example,
<combobox apply="org.zkoss.reference.component.input.MyAutoCompleteComposer"/>
then in MyAutoComplete.java, you could have
public class MyAutoCompleteComposer extends SelectorComposer<Component> {
@Wire("combobox")
private Combobox combobox;
private List<Locale> items = Arrays.asList(Locale.getAvailableLocales());
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
combobox.setModel(ListModels.toListSubModel(new ListModelList(getAllItems())));
}
List getAllItems() {
return items;
}
}
By default, it shows the first 15 items that matches the value entered by the user. If you want to have a different value or a different comparator to find out matched items, you could invoke ListModels.toListSubModel(ListModel, Comparator, int) instead.
Note: Passing an instance of ListModelList directly to a combobox will show up all items in the list model, since it doesn't implement ListSubModel.
Readonly
Once set, the user is not allowed to type characters, but he still can select the items in the Combobox. (Default:false )
<combobox readonly="true"/>
Autodrop
By default, the drop-down list won't be opened until the user clicks the button, or presses Alt+DOWN. However, you could set the autodrop property to true, meaning as soon as the user types a character the drop-down list will be opened. This is helpful for novice users, but it might be annoying for experienced users.
If you prefer the combobox to drop down the list when the user types a character, you could specify the autodrop attribute as follows.
<combobox autodrop="true"/>
If you prefer to drop down the list when gaining the focus, you could provide a client-side listener as follows.
<combobox w:onfocus="this.open()" xmlns:w="client"/>
Description
You are able to add a description to each combo item to make it more descriptive or assign an image to every item.
<zk>
<combobox>
<comboitem label="Simple and Rich"
image="/img/Centigrade-Widget-Icons/GoldBar-32x32.gif"
description="The simplest way to make Web applications rich" />
<comboitem label="Cool!"
image="/img/Centigrade-Widget-Icons/CogwheelEye-32x32.gif"
description="The coolest technology" />
<comboitem label="Ajax and RIA"
image="/img/Centigrade-Widget-Icons/WindowGlobe-32x32.gif"
description="Rich Internet Application by Ajax" />
</combobox>
</zk>
Akin to other components that support images, you are able to use the setImageContent method to assign a dynamically generated image to the comboitem component. Please refer to the Image section for details.
The onOpen Event
The onOpen event is sent to the application when a user opens the drop-down list. To defer the creation of combo items, you can use the fulfill attribute as shown below.
<zk>
<combobox fulfill="onOpen">
<comboitem label="Simple and Rich"/>
<comboitem label="Cool!"/>
<comboitem label="Ajax and RIA"/>
</combobox>
</zk>
Alternatively, you can listen to the onOpen event and prepare the drop-down list or change it dynamically as demonstrated below.
<zk>
<zscript>
void prepare()
{
if (combo.getItemCount() == 0)
{
combo.appendItem("Simple and Rich");
combo.appendItem("Cool!");
combo.appendItem("Ajax and RIA");
}
}
</zscript>
<combobox id="combo" onOpen="prepare()" />
</zk>
The appendItem method is equivalent to creating a combo item and then setting the combobox as its parent.
The onChanging Event
Since a combobox is also a text box, you are also able to listen to an onChanging event. By listening to this event, you can manipulate the drop-down list as demonstrated by Google Suggests (http://www.google.com/webhp?complete=1&hl=en). This feature is sometimes called auto-complete.
As illustrated below, you can populate the drop-down list based on what user is entering.
<zk>
<zscript>
void suggest()
{
combo.getItems().clear();
if (event.value.startsWith("A")) {
combo.appendItem("Ace");
combo.appendItem("Ajax");
combo.appendItem("Apple");
} else if (event.value.startsWith("B")) {
combo.appendItem("Best");
combo.appendItem("Blog");
}
}
</zscript>
<combobox id="combo" autodrop="true" onChanging="suggest()"/>
</zk>
Notice that, when the onChanging event is received, the content of the combobox has not changed. Therefore, you cannot use the value property of the combobox. Instead, you should use the value property of the InputEvent.
Constraint
You could specify what value to accept for input controls by use of the constraint property. It could be a combination of no empty, and/or a regular expression.
To specify two or more constraints, use comma to separate them as follows.
<combobox constraint="no empty,/^A/">
<comboitem label="Simple and Rich" />
<comboitem label="Cool!" />
<comboitem label="Ajax and RIA" />
</combobox>
To specify a regular expression, you may have to use the character / to enclose the regular expression as follows.
<combobox constraint="/^A/"/>
Notes:
- The above statement is XML, so do not use \\ to specify a backslash. However typing \\ is necessary, if writing in Java.
new Combobox().setConstraint("/.+@.+\\.[a-z]+/");
- You are allowed to mix regular expressions with other constraints by separating them with a comma.
If you prefer to display different message to the default one, you can append the error message to the constraint with a colon.
<combobox constraint="/^A/: only allowed the item start with A"/>
Notes:
- The error message, if specified, must be the last element and start with colon.
- To support multiple languages, you could use the 「l」 function as depicted in the Internationalization chapter.
<combobox constraint="/^A/: ${c:l('err.startwith.required')}"/>
PopupWidth
[Since 8.0.3]
By specifying this property, the width of the popup will be set and ignore the default behavior.
If percentage is specified to this property, the width of the popup will be calculated with the width of the bandbox.
For example, if it's set to 130%, and the width of the bandbox is 300px, the popup of the bandbox will be 300px * 130% = 390px
If others is specified, it will be set to the width of the popup directly.
Inherited Functions
Please refer to Textbox for inherited functions.
Supported Events
Event: SelectEvent
Represents an event caused by user's the list selection is changed at the client. | |
Event: OpenEvent
Denotes that the user has opened or closed a component. Note: unlike onClose, this event is only a notification. The client sends this event after opening or closing the component. It is useful to implement load-on-demand by listening to the onOpen event, and creating components when the first time the component is opened. | |
Event: Event
Notifies one that the model's data has been rendered. |
- Inherited Supported Events: Textbox
Supported Molds
Available molds of a component are defined in lang.xml embedded in zul.jar.
[Since 5.0.0] |
Supported Children
* Comboitem
Use Cases
Version | Description | Example Location |
---|---|---|
Version History
Version | Date | Content |
---|---|---|
5.0.4 | August 2010 | ListModels was introduced to simply the implementation of autocomplete. |
5.0.4 | July 2010 | Combobox supported Selectable if it is also implemented with the specified ListModel. |
5.0.4 | July 2010 | Supported onAfterRender event |