entityComboBox

entityComboBox lets users select an entity instance from a drop-down list and run actions for it.

XML Element

entityComboBox

Java Class

EntityComboBox

Basics

The entityComboBox component is commonly used when the field value must represent a reference to an entity. It enables users to select a particular entity instance with the ability to perform relevant actions.

Clicking the field or arrow button opens a drop-down list containing all existing instances of the entity.

Note that unless you have configured lazy loading, the component will load a list of all available instances into both the browser’s memory and the server’s memory. This can consume substantial system resources and may impact performance, especially for large number of items. Furthermore, users may find it challenging to search for a specific instance within a lengthy drop-down list.

If the expected number of items is large, such as thousands or more, or if making a selection requires providing additional context about each item, it is recommended to use entityPicker.

The following example uses entityComboBox to select the department to which a user belongs:

<data>
    <instance id="orderDc"
              class="io.jmix.uisamples.entity.Order">
        <fetchPlan extends="_local">
            <property name="customer" fetchPlan="_local"/>
        </fetchPlan>
    </instance>
    <collection id="customersDc"
                class="io.jmix.uisamples.entity.Customer"
                fetchPlan="_local">
        <loader id="customersDl">
            <query>
                <![CDATA[select e from Customer e]]>
            </query>
        </loader>
    </collection>
</data>
<facets>
    <dataLoadCoordinator auto="true"/>
</facets>
<layout>
    <entityComboBox dataContainer="orderDc"
                    itemsContainer="customersDc"
                    property="customer"
                    width="15em"
                    label="With actions">
        <actions>
            <action id="lookup" type="entity_lookup"/>
            <action id="clear" type="entity_clear"/>
        </actions>
    </entityComboBox>
    <entityComboBox dataContainer="orderDc"
                    itemsContainer="customersDc"
                    property="customer"
                    width="15em"
                    label="Without actions"/>
</layout>

For more interactive examples of the entityComboBox and its variations, see:

Data-aware entityComboBox

Use the dataContainer and property attributes to bind entityComboBox to an entity attribute. The data container provides the entity instance, property identifies the reference attribute to update, and itemsContainer supplies the entities available for selection.

Selecting an Entity

If you simply need a way to select an instance of a specific entity, specify that entity using the metaClass attribute. To specify a collection of instances for selection use the itemsContainer attribute.

<entityComboBox metaClass="Department"
                itemsContainer="departmentsDc">
    // ...
</entityComboBox>

Selecting an instance is often intended to update an attribute within another instance. In the example above, selecting a Department instance updates the User instance by associating it with the chosen department.

In such cases you will need to bind the component to the data container holding the instance and specify the attribute to be updated using the dataContainer and property attributes respectively. To specify a collection of instances for selection use the itemsContainer attribute.

<entityComboBox dataContainer="userDc"
                property="department"
                itemsContainer="departmentsDc">
    // ...
</entityComboBox>

Actions

Initially entityComboBox does not have any actions. You need to add them explicitly, for example:

<data>
    <instance id="orderDc"
              class="io.jmix.uisamples.entity.Order">
        <fetchPlan extends="_local">
            <property name="customer" fetchPlan="_local"/>
        </fetchPlan>
    </instance>
    <collection id="customersDc"
                class="io.jmix.uisamples.entity.Customer"
                fetchPlan="_local">
        <loader id="customersDl">
            <query>
                <![CDATA[select e from Customer e]]>
            </query>
        </loader>
    </collection>
</data>
<facets>
    <dataLoadCoordinator auto="true"/>
</facets>
<layout>
    <entityComboBox dataContainer="orderDc"
                    itemsContainer="customersDc"
                    property="customer"
                    width="15em"
                    label="With actions">
        <actions>
            <action id="lookup" type="entity_lookup"/>
            <action id="clear" type="entity_clear"/>
        </actions>
    </entityComboBox>
    <entityComboBox dataContainer="orderDc"
                    itemsContainer="customersDc"
                    property="customer"
                    width="15em"
                    label="Without actions"/>
</layout>

To add action in Jmix Studio, select the component in the view descriptor XML or in the Jmix UI structure panel and click on the Add→Action button in the Jmix UI inspector panel.

See detailed information on defining custom and predefined actions in the Actions section for entityPicker.

Lazy Loading

The component supports loading items in batches in response to user input, rather than loading all items at once. This helps to ensure a smooth user experience, even when dealing with a large number of items.

Declarative Items Query

To implement lazy loading in the view descriptor, instead of specifying the itemsContainer attribute configure the itemsQuery nested element. For example, to load at most 30 items and show them in the list, do the following:

<layout>
    <tabSheet id="tabSheet" width="100%">
        <tab id="declarativeTab" label="Declaratively">
            <entityComboBox id="declarativeEntityComboBox" label="Customer"
                            metaClass="Customer">
                <actions>
                    <action id="entityLookup" type="entity_lookup"/>
                    <action id="entityClear" type="entity_clear"/>
                </actions>
                <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>
            </entityComboBox>
        </tab>
        <tab id="programmaticTab" label="Programmatic">
            <entityComboBox id="programmaticEntityComboBox" label="Customer"
                            metaClass="Customer">
                <actions>
                    <action id="entityLookup" type="entity_lookup"/>
                    <action id="entityClear" type="entity_clear"/>
                </actions>
            </entityComboBox>
        </tab>
    </tabSheet>
</layout>

The pageSize attribute defines the batch size when loading data from the database. It is 50 by default.

Attributes in the itemsQuery provide control over the fetching process. They are as follows: * class – specifies a full qualified name of the entity class which instances will be fetched. * searchStringFormat – a string that contains a variable placeholder, which is subsequently replaced with an actual value. * escapeValueForLike – specifies whether to search for values containing special symbols. By default, this value is false. * fetchPlan – and optional descriptor of inline fetch plan. A JPQL query specifies the items to load.

The itemsQuery does not support using the container_ or component_ prefixes to automatically bind parameters to containers or visual components; this declarative binding is only supported by dataLoadCoordinator facet.

Programmatic Items Fetching

Items fetching can also be defined programmatically using the itemsFetchCallback handler. For example:

XML
<layout>
    <tabSheet id="tabSheet" width="100%">
        <tab id="declarativeTab" label="Declaratively">
            <entityComboBox id="declarativeEntityComboBox" label="Customer"
                            metaClass="Customer">
                <actions>
                    <action id="entityLookup" type="entity_lookup"/>
                    <action id="entityClear" type="entity_clear"/>
                </actions>
                <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>
            </entityComboBox>
        </tab>
        <tab id="programmaticTab" label="Programmatic">
            <entityComboBox id="programmaticEntityComboBox" label="Customer"
                            metaClass="Customer">
                <actions>
                    <action id="entityLookup" type="entity_lookup"/>
                    <action id="entityClear" type="entity_clear"/>
                </actions>
            </entityComboBox>
        </tab>
    </tabSheet>
</layout>
Java
@Autowired
protected DataManager dataManager;

protected Collection<Customer> customers;

@Subscribe
protected void onInit(InitEvent event) {
    customers = dataManager.load(Customer.class).all().list();
}

@Install(to = "programmaticEntityComboBox", subject = "itemsFetchCallback")
protected Stream<Customer> programmaticEntityComboBoxItemsFetchCallback(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.

Custom Renderer

By default, instances displayed in a drop-down list are typically rendered as plain text. A custom renderer allows you to define a rendering logic for each item in the drop-down, enabling you to include various components, icons, or even layouts.

For example, define the following renderer to add an icon before a department name:

@Supply(to = "customRendererField", subject = "renderer")
private Renderer<Department> departmentRenderer() {
    return new ComponentRenderer<>(department -> {
        Icon icon = VaadinIcon.USERS.create();
        HorizontalLayout contentBox = uiComponents.create(HorizontalLayout.class);
        contentBox.setPadding(false);
        contentBox.add(icon);
        contentBox.add(department.getName());
        return contentBox;
    });
}

Alternatively, you can render items using a nested fragmentRenderer element. Refer to the Fragment Renderer section for more information.

Theme Variants

Use the themeNames attribute to apply one or more theme variants.

Variant Description Supported By

align-left

Aligns the field value to the left side.

Aura, Lumo

align-center

Centers the field value.

Aura, Lumo

align-right

Aligns the field value to the right side.

Aura, Lumo

align-start

Aligns the field value to the start side, taking the current text direction into account.

Aura

align-end

Aligns the field value to the end side, taking the current text direction into account.

Aura

helper-above-field

Renders the helper text above the field, below the label.

Aura, Lumo

small

Makes the component smaller.

Aura, Lumo

Attributes

The following attributes are specific to entityComboBox:

Name Description Default

allowCustomValue

If the allowCustomValue attribute is true, the user can input string values that do not match any existing item labels, which will fire CustomValueSetEvent.

autoOpen

Controls whether the item overlay opens when the field receives focus.

itemsContainer

Sets the name of a data container which contains a list of items.

metaClass

Sets the meta class.

opened

Sets whether the drop-down list should be opened or not.

pageSize

Sets the page size.

The following shared attributes are supported by entityComboBox:

Handlers

The following handlers are specific to entityComboBox:

Name Description

CustomValueSetEvent

com.vaadin.flow.component.combobox.ComboBoxBase.CustomValueSetEvent is fired when the user enters a non-empty value that does not match any of the existing items.

itemLabelGenerator

Provides the text shown for each item.

validator

Validates the component value.

renderer

Provides the component used to render each item. See Custom Renderer.

The following shared handlers are supported by entityComboBox:

Elements

An entityComboBox can include actions, fragmentRenderer, itemsQuery, prefix, tooltip, and validator as its nested elements.