multiSelectComboBox
multiSelectComboBox allows users to choose one or more items from a drop-down list. This component is similar to comboBox.
XML Element |
|
|---|---|
Java Class |
|
Basics
The drop-down list opens when the user clicks the field using a pointing device. Using the Up and Down keys or typing a character when the field is focused also opens the drop-down list.
<multiSelectComboBox id="multiSelectComboBox"/>
<multiSelectComboBox itemsEnum="io.jmix.uisamples.entity.Day" clearButtonVisible="true" width="17em"/>
@ViewComponent
protected JmixMultiSelectComboBox<String> multiSelectComboBox;
@Subscribe
protected void onInit(InitEvent event) {
multiSelectComboBox.setItems("CSS", "HTML", "Java", "JavaScript", "JSON", "Kotlin", "XML");
multiSelectComboBox.select("Java", "Kotlin");
}
Data-aware multiSelectComboBox
Data binding refers to linking a visual component to a data container. Changes in the visual component or corresponding data container can trigger updates to one another. See Using Data Components for more details.
multiSelectComboBox is designed for properties that store multiple values. When the component is bound to an entity attribute, the attribute type should be a collection, for example List or Set.
The most common use case is selecting related entities for a many-to-many association:
@JmixEntity
@Table(name = "HOBBY")
@Entity
public class Hobby {
/* attributes */
}
@JmixEntity
@Entity
@Table(name = "USER_")
public class User {
/* other attributes */
@JoinTable(name = "USER_HOBBY_LINK",
joinColumns = @JoinColumn(name = "USER_ID"),
inverseJoinColumns = @JoinColumn(name = "HOBBY_ID"))
@ManyToMany
private List<Hobby> userHobbies;
}
In this case, multiSelectComboBox allows the user to select several Hobby instances, and the relationship is stored in the join table.
To create a data-aware multiSelectComboBox, use the dataContainer and property attributes to bind the component to a collection property. Use the itemsContainer attribute to provide the list of available items. The following example produces a data-aware multiSelectComboBox.
<data>
<instance id="productDc"
class="io.jmix.uisamples.entity.Product"
fetchPlan="_local">
</instance>
<collection id="productTagsDc"
class="io.jmix.uisamples.entity.ProductTag"
fetchPlan="_local">
<loader id="productTagsDl">
<query>
<![CDATA[select e from ProductTag e]]>
</query>
</loader>
</collection>
</data>
<facets>
<dataLoadCoordinator auto="true"/>
</facets>
<layout>
<multiSelectComboBox id="multiSelectComboBox" width="15em" label="Product tags"
dataContainer="productDc" property="tags"
itemsContainer="productTagsDc"/>
<hbox>
<span text="Value in the container:"/>
<span id="spanValue"/>
</hbox>
</layout>
@ViewComponent
protected InstanceContainer<Product> productDc;
@ViewComponent
protected Span spanValue;
@Autowired
protected Metadata metadata;
@Subscribe
protected void onInit(InitEvent event) {
Product product = metadata.create(Product.class);
productDc.setItem(product);
}
@Subscribe("multiSelectComboBox")
protected void onMultiSelectComboBoxFieldValueChange(
TypedValueChangeEvent<JmixMultiSelectComboBox<Product>, Product> changeEvent) {
spanValue.setText(getSelectedTagsInstanceName());
}
protected String getSelectedTagsInstanceName() {
return productDc.getItem().getTags()
.stream()
.map(ProductTag::getInstanceName)
.collect(Collectors.joining(", "));
}
|
|
The component value contains the selected items. When the component is bound to a collection property, Jmix converts the selected items to the property collection type, for example List or Set.
MultiSelectComboBox with MetaClass
You can use multiSelectComboBox without directly referencing data, meaning you don’t need to specify dataContainer or property attributes. In this case, use the metaClass attribute to specify the entity type for multiSelectComboBox. To specify a collection of instances for selection use the itemsContainer attribute.
For example, the component can work with the Hobby entity, which has the metadata class name Hobby.
<multiSelectComboBox metaClass="Hobby"
itemsContainer="userHobbiesDc"/>
Custom Item Labels
Install an itemLabelGenerator to control how values are displayed in the overlay and selected-item chips.
<data>
<collection id="productTagsDc"
class="io.jmix.uisamples.entity.ProductTag"
fetchPlan="_local">
<loader id="productTagsDl">
<query>
<![CDATA[select e from ProductTag e]]>
</query>
</loader>
</collection>
</data>
<multiSelectComboBox id="multiSelectComboBox" label="Product tags" itemsContainer="productTagsDc"/>
@Install(to = "multiSelectComboBox", subject = "itemLabelGenerator")
protected String multiSelectComboBoxItemLabelGenerator(ProductTag productTag) {
return "#" + productTag.getName();
}
Custom Item Renderer
Supply a component renderer to display richer overlay items. This example shows each enum value with its Vaadin icon and name.
<multiSelectComboBox id="iconsMultiSelectComboBox" clearButtonVisible="true"
label="Icons"
width="20em"/>
@ViewComponent
protected JmixMultiSelectComboBox<VaadinIcon> iconsMultiSelectComboBox;
@Autowired
protected UiComponents uiComponents;
@Subscribe
protected void onInit(InitEvent event) {
iconsMultiSelectComboBox.setItems(VaadinIcon.values());
}
@Supply(to = "iconsMultiSelectComboBox", subject = "renderer")
protected Renderer<VaadinIcon> multiSelectComboBoxComponentRenderer() {
return new ComponentRenderer<>(vaadinIcon -> {
HorizontalLayout contentBox = uiComponents.create(HorizontalLayout.class);
contentBox.setPadding(false);
contentBox.add(vaadinIcon.create());
contentBox.add(vaadinIcon.name());
return contentBox;
});
}
Auto Expand
You can configure multiSelectComboBox to automatically expand its width to accommodate chips representing selected items. Expansion only works with undefined size in the desired direction (for example, setting max-width limits the component’s width). Possible values:
-
VERTICAL- field expands vertically and chips wrap. -
HORIZONTAL- field expands horizontally until max-width is reached, then collapses to overflow chip. -
BOTH- field expands horizontally until max-width is reached, then expands vertically and chips wrap. -
NONE- field does not expand and collapses to overflow chip.== Selected Items on Top
The selectedItemsOnTop attribute controls how selected items are displayed in the overlay.
Here’s how it works:
-
If
selectedItemsOnTopis set totrue, selected items are displayed at the top of the overlay, while unselected items remain at the bottom. This arrangement can be visually appealing and intuitive, particularly if users frequently select a subset of items and need quick access to the most recently selected ones. -
If
selectedItemsOnTopis set tofalse(the default value), selected items are displayed in the order they were selected, without being moved to the top of the overlay. This arrangement maintains the order of selection and can be preferred in scenarios where order is crucial or if visual consistency with other UI elements is important.
Items Fetch Callback
multiSelectComboBox 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. -
class(optional) - specifies a full qualified name of the entity class which instances will be fetched. -
fetchPlan- an optional attribute that specifies the fetch plan to be used for loading the queried entity.
The itemsQuery element has the following nested elements:
-
query- an element that contains a JPQL query. -
fetchPlan- an optional descriptor of inline fetch plan.
Example of itemsQuery in multiSelectComboBox:
<multiSelectComboBox id="declarativeMultiSelectComboBox" label="Customer"
metaClass="Customer">
<itemsQuery class="io.jmix.uisamples.entity.Customer"
searchStringFormat="(?i)%${inputString}%"
escapeValueForLike="true"
fetchPlan="_local">
<query>
<![CDATA[select e from Customer e where e.name
like :searchString escape '\' order by e.name asc]]>
</query>
</itemsQuery>
</multiSelectComboBox>
|
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();
}
@Install(to = "programmaticMultiSelectComboBox", subject = "itemsFetchCallback")
protected Stream<Customer> programmaticMultiSelectComboBoxItemsFetchCallback(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.
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 multiSelectComboBox:
| Name | Description | Default |
|---|---|---|
Controls whether users can enter values that are not in the available items. |
— |
|
Controls how the component behaves when there isn’t enough space to display all selected items as chips within the current field width. See Auto Expand. |
|
|
Controls whether the item overlay opens when the field receives focus. |
— |
|
Controls whether the field displays a clear button. |
|
|
Sets the items container. |
— |
|
Sets the items enum. |
— |
|
Defines an entity class for |
— |
|
Sets whether the drop-down list should be opened or not. |
|
|
Adds CSS class names to the component overlay. |
— |
|
Sets the page size. |
— |
|
Enables or disables grouping of the selected items at the top of the overlay. See Selected Items on Top. |
|
The following shared attributes are supported by multiSelectComboBox:
id - alignSelf - allowedCharPattern - ariaLabel - ariaLabelledBy - autofocus - classNames - colspan - css - dataContainer - enabled - errorMessage - focusShortcut - height - helperText - label - maxHeight - maxWidth - minHeight - minWidth - placeholder - property - readOnly - required - requiredMessage - tabIndex - themeNames - title - visible - width
Handlers
The following handlers are specific to multiSelectComboBox:
| Name | Description |
|---|---|
Fired when the user enters a custom value in the field. |
|
|
|
This handler only fetches data when it’s needed. See Items Fetch Callback. |
|
Sets the |
|
Validates the component value. |
The following shared handlers are supported by multiSelectComboBox:
Elements
A multiSelectComboBox can include fragmentRenderer, itemsQuery, tooltip, and validator as its nested elements.