comboBox
comboBox allows users to select a single value from a predefined list of items.
XML Element |
|
|---|---|
Java Class |
|
Basics
comboBox provides filtering of values as the user enters some text, and pagination of available values.
Use comboBox when:
-
Dynamic Filtering. You need the ability for users to filter the items in the dropdown as they type.
comboBoxprovides built-in filtering capabilities. -
Large Datasets. You are working with a large number of items in your dropdown.
comboBoxhandles pagination, allowing you to display only a limited number of options at a time, enhancing performance. -
Custom Rendering. You want to customize the appearance of the dropdown items, perhaps with additional information or styling.
comboBoxoffers more flexibility for customizing how items are rendered.
The simplest case of using comboBox is to select an enumeration value for an entity attribute. In the following example, the component edits the grade attribute of the Customer entity.
<data>
<instance id="customerDc"
class="io.jmix.uisamples.entity.Customer"
fetchPlan="_local"/>
</data>
<layout>
<comboBox dataContainer="customerDc" property="grade"/>
</layout>
The customerDc instance container holds the entity. The dataContainer and property attributes bind comboBox to its grade attribute.
Items from a List
You can specify the list of comboBox items using the setItems() method.
First, declare a component in the XML descriptor:
<instance id="orderDc"
class="io.jmix.uisamples.entity.Order"
fetchPlan="_local"/>
<comboBox id="amountComboBox"
label="Items List"
dataContainer="orderDc"
property="amount"/>
Then inject the component into the controller and specify a list of items in the onInit() method:
@ViewComponent
protected JmixComboBox<BigDecimal> amountComboBox;
amountComboBox.setItems(getAmountItemsList());
protected List<BigDecimal> getAmountItemsList() {
return List.of(
BigDecimal.valueOf(1000),
BigDecimal.valueOf(2000),
BigDecimal.valueOf(3000),
BigDecimal.valueOf(4000)
);
}
In the component’s drop-down list, the values 1000, 2000, 3000 and 4000 will be displayed. The selected value will be put into the amount attribute of an entity located in the orderDc data container.
Items with Custom Labels
ComponentUtils.setItemsMap() allows you to specify a string label for each item value explicitly.
@ViewComponent
protected JmixComboBox<Integer> ageComboBox;
ComponentUtils.setItemsMap(ageComboBox, getAgeItemsMap());
protected Map<Integer, String> getAgeItemsMap() {
LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
map.put(20, "Twenty");
map.put(30, "Thirty");
map.put(40, "Forty");
map.put(50, "Fifty");
return map;
}
Items from Enum
You can use either a declarative or programmatic approach to set the values of an enum as comboBox items.
The itemsEnum attribute defines the enumeration class for creating a list of items. The drop-down list will show localized names of enum values; the component’s value will be an enum value.
<comboBox id="gradeComboBox"
label="Items Enum"
dataContainer="customerDc"
itemsEnum="io.jmix.uisamples.entity.CustomerGrade"
property="grade"
placeholder="Select grade"/>
The example below uses the programmatic approach.
@ViewComponent
private JmixComboBox<OnboardingStatus> enumComboBox;
@Subscribe
public void onInit(InitEvent event) {
enumComboBox.setItems(OnboardingStatus.class);
}
Custom Filtering
By default, comboBox performs case-insensitive substring matching for its filtering. This means that it will show any items where the entered text appears anywhere within the item’s label, regardless of capitalization.
You can also customize filtering. To set a custom filter for comboBox, use the setItems() method.
@ViewComponent
protected JmixComboBox<String> noFilterComboBox;
@ViewComponent
protected JmixComboBox<String> startsWithFilterComboBox;
@ViewComponent
protected JmixComboBox<String> containsFilterComboBox;
@Subscribe
protected void onInit(InitEvent event) {
List<String> itemsList = List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
noFilterComboBox.setItems(itemsList);
startsWithFilterComboBox.setItems(getStartsWithFilter(), itemsList);
containsFilterComboBox.setItems(getContainsFilter(), itemsList);
}
protected ComboBox.ItemFilter<String> getStartsWithFilter() {
return (dayOfWeek, filterString) -> dayOfWeek.toLowerCase().startsWith(filterString.toLowerCase());
}
protected ComboBox.ItemFilter<String> getContainsFilter() {
return (dayOfWeek, filterString) -> dayOfWeek.toLowerCase().contains(filterString.toLowerCase());
}
Custom Value Entry
comboBox allows you to configure it to accept custom values not in the list of items.
When the allowCustomValue attribute is set to true, users can enter custom string values that don’t match any existing items. This triggers CustomValueSetEvent.
comboBox doesn’t do anything with the custom value string automatically. Use CustomValueSetEvent to determine how the custom value should be handled.
|
This example demonstrates the ability to add new values to the list of items, making them available for future selections:
<comboBox id="comboBox"
label="Magic Box"
allowCustomValue="true"
helperText="Entered value will be added to the items"/>
@ViewComponent
protected JmixComboBox<String> comboBox;
@Autowired
protected Notifications notifications;
protected List<String> items = Lists.newArrayList("One", "Two", "Tree");
@Subscribe
protected void onInit(InitEvent event) {
comboBox.setItems(items);
}
@Subscribe("comboBox")
protected void onComboBoxCustomValueSet(ComboBoxBase.CustomValueSetEvent<ComboBox<String>> event) {
String customValue = event.getDetail();
items.add(customValue);
comboBox.setItems(items);
comboBox.setValue(customValue);
notifications.show(customValue + " added");
}
Items Fetch Callback
comboBox can load items in batches in response to user input.
For example, when the user enters foo, the component loads from the database at most 50 items having foo in the name and shows them the dropdown. When the user scrolls down the list, the component fetches the next batch of 50 items with the same query and adds them to the list.
Declarative Items Query
To implement this behavior, define the itemsQuery nested element.
The itemsQuery element should contain the JPQL query text in the nested query element and a few additional attributes specifying what and how to load data:
-
escapeValueForLike- enables searching for the values that contain special symbols:%,\, etc. The default value isfalse. -
searchStringFormat- a string that contains a variable placeholder, which is subsequently replaced with an actual value.
Example of itemsQuery in comboBox:
<comboBox id="declarativeComboBox" label="Customer">
<itemsQuery searchStringFormat="(?i)%${inputString}%"
escapeValueForLike="true">
<query>
<![CDATA[select e.name from Customer e where e.name
like :searchString escape '\' order by e.name asc]]>
</query>
</itemsQuery>
</comboBox>
The pageSize attribute of the component defines the batch size when loading data from the database. It is 50 by default.
As you can see, itemsQuery in comboBox does not need class and fetchPlan attributes because the query is supposed to return the list of scalar values (notice e.name in the result set). To work with entities, use the entityComboBox component.
|
The |
Programmatic Items Fetching
Items fetching can also be defined programmatically using the itemsFetchCallback handler. For example:
@Autowired
protected DataManager dataManager;
protected Collection<Customer> customers;
@Subscribe
protected void onInit(InitEvent event) {
customers = dataManager.load(Customer.class).all().list();
}
@Supply(to = "programmaticComboBox", subject = "renderer")
protected Renderer<Customer> comboBoxTextRenderer() {
return new TextRenderer<>(Customer::getName);
}
@Install(to = "programmaticComboBox", subject = "itemsFetchCallback")
protected Stream<Customer> programmaticComboBoxItemsFetchCallback(Query<Customer, String> query) {
String enteredValue = query.getFilter()
.orElse("");
return customers.stream()
.filter(customer -> customer.getName() != null &&
customer.getName().toLowerCase().contains(enteredValue.toLowerCase()))
.skip(query.getOffset())
.limit(query.getLimit());
}
In this example, data is fetched using DataManager, but you can use this approach to load from a custom service as well.
Customizing Item Labels
itemLabelGenerator allows you to customize how items are displayed in the dropdown list. This gives you control over the text that users see, enabling you to present information in a more user-friendly or context-specific manner.
@Install(to = "colorComboBox", subject = "itemLabelGenerator")
private String colorComboBoxItemLabelGenerator(String item) {
return item.toUpperCase();
}
Rendering Items
The framework provides flexibility in customizing the rendering of items. You can use either the setRenderer() method or the @Supply annotation to achieve this.
<comboBox id="iconsComboBox"
label="Icons"
width="20em"/>
@ViewComponent
protected JmixComboBox<VaadinIcon> iconsComboBox;
@Autowired
protected UiComponents uiComponents;
@Subscribe
protected void onInit(InitEvent event) {
iconsComboBox.setItems(VaadinIcon.values());
}
@Supply(to = "iconsComboBox", subject = "renderer")
protected Renderer<VaadinIcon> iconsComboBoxRenderer() {
return new ComponentRenderer<Component, VaadinIcon>(vaadinIcon -> {
HorizontalLayout contentBox = uiComponents.create(HorizontalLayout.class);
contentBox.setPadding(false);
contentBox.add(vaadinIcon.create());
contentBox.add(vaadinIcon.name());
return contentBox;
});
}
Overlay
Overlay is a semi-transparent or opaque layer that is used to create a dropdown list of items.
The overlayClass attribute allows you to add custom CSS classes to the overlay element.
<comboBox id="ratingComboBox"
datatype="int"
overlayClass="my-custom-overlay"/>
Define a custom style in your css file:
vaadin-combo-box-overlay.my-custom-overlay::part(overlay){
background-color: #ecfcf9;
border-radius: 5px;
}
Validation
To check values entered into the comboBox component, you can use a validator in a nested validators element.
The following predefined validators are available for comboBox:
XML Element |
|
|---|---|
elements |
custom - decimalMax - decimalMin - digits - doubleMax - doubleMin - email - max - min - negativeOrZero - negative - notBlank - notEmpty - notNull - positiveOrZero - positive - regexp - size |
Theme Variants
Use the themeNames attribute to apply one or more theme variants.
| Variant | Description | Supported By |
|---|---|---|
|
Makes the component smaller. |
Aura, Lumo |
|
Aligns the field value to the left side. |
Aura, Lumo |
|
Centers the field value. |
Aura, Lumo |
|
Aligns the field value to the right side. |
Aura, Lumo |
|
Renders the helper text above the field, below the label. |
Aura, Lumo |
Attributes
The following attributes are specific to comboBox:
| Name | Description | Default |
|---|---|---|
If the |
|
|
If the |
|
|
Controls whether the field displays a clear button. |
|
|
The |
— |
|
Defines a space-delimited list of CSS class names to set on the overlay element. See Overlay. |
— |
|
Sets the maximum number of items sent per request, should be greater than zero. See Items Fetch Callback. |
|
The following shared attributes are supported by comboBox:
id - alignSelf - ariaLabel - ariaLabelledBy - autofocus - classNames - colspan - css - dataContainer - datatype - enabled - errorMessage - focusShortcut - height - helperText - label - maxHeight - maxWidth - minHeight - minWidth - pattern - placeholder - property - readOnly - required - requiredMessage - tabIndex - themeNames - title - visible - width
Handlers
The following handlers are specific to comboBox:
| Name | Description |
|---|---|
|
|
|
|
This handler only fetches data when it’s needed. See Programmatic Items Fetching. |
|
Sets the |
|
Validates the component value. |
The following shared handlers are supported by comboBox:
Elements
A comboBox can include itemsQuery, prefix, tooltip, and validator as its nested elements.