comboBox

comboBox позволяет пользователям выбирать одно значение из предопределённого списка элементов.

XML-элемент

comboBox

Java-класс

JmixComboBox

Основы

comboBox обеспечивает фильтрацию значений по мере ввода пользователем текста и разбиение на страницы доступных значений.

Используйте comboBox, когда вам нужны:

  • Динамическая фильтрация. Вам необходимо, чтобы пользователи могли фильтровать элементы в выпадающем списке по мере ввода текста. comboBox предоставляет встроенные возможности фильтрации.

  • Большие наборы данных. Вы работаете с большим количеством элементов в выпадающем списке. comboBox обрабатывает пагинацию, позволяя отображать только ограниченное количество вариантов за раз, что повышает производительность.

  • Настройка отображения. Вы хотите настроить внешний вид элементов в выпадающем списке, возможно, с дополнительной информацией или стилями. comboBox предлагает большую гибкость для настройки отображения элементов.

Простейший вариант использования comboBox — выбор значения перечисления для атрибута сущности. В следующем примере компонент редактирует атрибут grade сущности Customer.

<data>
    <instance id="customerDc"
              class="io.jmix.uisamples.entity.Customer"
              fetchPlan="_local"/>
</data>
<layout>
    <comboBox dataContainer="customerDc" property="grade"/>
</layout>

Контейнер экземпляра customerDc хранит сущность. Атрибуты dataContainer и property связывают comboBox с её атрибутом grade.

Пользовательские элементы

Список элементов

Вы можете задать список элементов comboBox с помощью метода setItems().

Сначала объявите компонент в XML-дескрипторе:

<instance id="orderDc"
          class="io.jmix.uisamples.entity.Order"
          fetchPlan="_local"/>
<comboBox id="amountComboBox"
          label="Items List"
          dataContainer="orderDc"
          property="amount"/>

Затем инжектируйте компонент в контроллер и задайте список элементов в методе onInit():

@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)
    );
}

В раскрывающемся списке компонента отобразятся значения 1000, 2000, 3000 и 4000. Выбранное значение будет помещено в атрибут amount сущности, расположенной в контейнере данных orderDc.

Список элементов с описаниями

Метод ComponentUtils.setItemsMap() позволяет явно задать строковые описания для каждого значения элемента.

@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;
}

Список значений перечисления

Вы можете использовать декларативный или программный подход для установки значений перечисления как элементов comboBox.

Атрибут itemsEnum определяет класс перечисления для создания списка элементов. В выпадающем списке будут отображаться локализованные имена значений перечисления; значение компонента будет являться значением перечисления.

<comboBox id="gradeComboBox"
          label="Items Enum"
          dataContainer="customerDc"
          itemsEnum="io.jmix.uisamples.entity.CustomerGrade"
          property="grade"
          placeholder="Select grade"/>

Пример ниже использует программный подход.

@ViewComponent
private JmixComboBox<OnboardingStatus> enumComboBox;

@Subscribe
public void onInit(InitEvent event) {
    enumComboBox.setItems(OnboardingStatus.class);
}

Пользовательская фильтрация

По умолчанию comboBox выполняет нечувствительное к регистру сопоставление подстрок для фильтрации. Это означает, что он будет показывать любые элементы, где введённый текст встречается где-либо в названии элемента, независимо от регистра.

Вы также можете настроить фильтрацию. Чтобы установить собственный фильтр для comboBox, используйте метод setItems().

@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());
}

Обработка пользовательского ввода

comboBox позволяет вам настроить его для принятия пользовательских значений, отсутствующих в списке элементов.

Когда атрибут allowCustomValue установлен в true, пользователи могут вводить произвольные строковые значения, не совпадающие с существующими элементами. Это приводит к событию CustomValueSetEvent.

comboBox автоматически не обрабатывает строку с пользовательским значением. Используйте событие CustomValueSetEvent, чтобы определить, как следует обработать введённое пользователем значение.

Этот пример демонстрирует возможность добавления новых значений в список элементов, делая их доступными для будущего выбора:

XML
<comboBox id="comboBox"
          label="Magic Box"
          allowCustomValue="true"
          helperText="Entered value will be added to the items"/>
Java
@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");
}

Получение элементов списка

comboBox может загружать элементы по частям в ответ на действия пользователя.

Например, когда пользователь вводит foo, компонент загружает из базы данных не более 50 элементов, содержащих foo в названии, и показывает их в выпадающем списке. Когда пользователь прокручивает список вниз, компонент извлекает следующую группу из 50 элементов с тем же запросом и добавляет их в список.

Декларативная конфигурация

Чтобы реализовать такое поведение, задайте вложенный элемент itemsQuery.

Для реализации этого поведения определите вложенный элемент itemsQuery.

Элемент itemsQuery должен содержать текст запроса JPQL во вложенном элементе query и несколько дополнительных атрибутов, определяющих, что и как загружать данные:

  • escapeValueForLike - включает поиск значений, содержащих специальные символы: %, \, и так далее. Значение по умолчанию - false.

  • searchStringFormat - строка Groovy. C её помощью вы можете использовать любые допустимые строковые выражения Groovy.

Пример itemsQuery в 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>

Атрибут компонента pageSize задаёт размер порции при загрузке данных из базы. Значение по умолчанию — 50.

Для itemsQuery в comboBox не нужны атрибуты class и fetchPlan, поскольку запрос возвращает список скалярных значений — обратите внимание на e.name в результирующем наборе. Для работы с сущностями используйте компонент entityComboBox.

itemsQuery не поддерживает использование префиксов container_ или component_ для автоматической привязки параметров к контейнерам или визуальным компонентам; такая декларативная привязка поддерживается только фасетом dataLoadCoordinator.

Программная конфигурация

Извлечение элементов также может быть определено программно с помощью обработчика itemsFetchCallback. Например:

@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());
}

В этом примере данные извлекаются с помощью DataManager, но вы можете использовать этот подход для загрузки из собственного сервиса.

Настройка отображения элементов

itemLabelGenerator позволяет вам настроить отображение элементов в выпадающем списке. Это дает вам контроль над текстом, который видят пользователи, позволяя представлять информацию более удобным для пользователя или контекстно-специфичным образом.

@Install(to = "colorComboBox", subject = "itemLabelGenerator")
private String colorComboBoxItemLabelGenerator(String item) {
    return item.toUpperCase();
}

Рендеринг элементов

Фреймворк предоставляет гибкость в настройке отображения элементов. Вы можете использовать либо метод setRenderer(), либо аннотацию @Supply, чтобы добиться этого.

XML
<comboBox id="iconsComboBox"
          label="Icons"
          width="20em"/>
Java
@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;
    });
}

Оверлей

Оверлей - это полупрозрачный или непрозрачный слой, который используется для создания выпадающего списка элементов.

Атрибут overlayClass позволяет вам добавлять пользовательские CSS-классы к элементу оверлея.

<comboBox id="ratingComboBox"
          datatype="int"
          overlayClass="my-custom-overlay"/>

Определите свой собственный стиль в вашем CSS-файле:

vaadin-combo-box-overlay.my-custom-overlay::part(overlay){
    background-color: #ecfcf9;
    border-radius: 5px;
}

Валидация

Чтобы проверять значения, введённые в comboBox, добавьте валидатор во вложенный элемент validators.

Для comboBox доступны следующие стандартные валидаторы:

XML-элемент

validators

elements

custom - decimalMax - decimalMin - digits - doubleMax - doubleMin - email - max - min - negativeOrZero - negative - notBlank - notEmpty - notNull - positiveOrZero - positive - regexp - size

Варианты темы

Используйте атрибут themeNames, чтобы применить один или несколько вариантов темы.

Вариант Описание Поддерживается в

small

Уменьшает размер компонента.

Aura, Lumo

align-left

Выравнивает значение поля по левому краю.

Aura, Lumo

align-center

Выравнивает значение поля по центру.

Aura, Lumo

align-right

Выравнивает значение поля по правому краю.

Aura, Lumo

helper-above-field

Размещает вспомогательный текст над полем, под меткой.

Aura, Lumo

Атрибуты

comboBox имеет следующие уникальные атрибуты:

Имя Описание По умолчанию

allowCustomValue

Если атрибут allowCustomValue равен true, пользователь может ввести строковые значения, которые не соответствуют ни одной существующей метке элемента, что приведет к срабатыванию CustomValueSetEvent. См. Ввод пользовательского значения.

false

autoOpen

Если атрибут autoOpen равен true, раскрывающийся список comboBox открывается автоматически, когда поле фокусируется с помощью мыши или касания, или когда пользователь вводит текст в поле. Установите значение false, чтобы отключить это поведение.

true

clearButtonVisible

Определяет, отображается ли в поле кнопка очистки.

false

itemsEnum

Атрибут itemsEnum определяет класс перечисления для создания списка элементов. См. Перечисление предметов.

overlayClass

Определяет список имен классов CSS, разделенных пробелами, для установки в элементе наложения. См. Overlay.

pageSize

Устанавливает максимальное количество элементов, отправляемых за один запрос, должно быть больше нуля. См. Обратный вызов получения предметов.

50

comboBox имеет следующие общие атрибуты:

Обработчики

comboBox имеет следующие уникальные обработчики:

Имя Описание

CustomValueSetEvent

com.vaadin.flow.component.combobox.ComboBoxBase.CustomValueSetEvent запускается, когда пользователь вводит непустое значение, которое не соответствует ни одному из существующих элементов. Чтобы включить ввод пользовательских значений, установите для атрибута allowCustomValue значение true.

itemLabelGenerator

com.vaadin.flow.component.ItemLabelGenerator можно использовать для настройки строки, отображаемой пользователю для элемента. См. Настройка меток предметов.

itemsFetchCallback

Этот обработчик извлекает данные только тогда, когда это необходимо. См. Получение программных элементов.

renderer

Устанавливает Renderer ответственным за отображение отдельных элементов в списке возможных вариантов comboBox. Это не влияет на то, как отображается выбранный элемент — это можно настроить с помощью ItemLabelGenerator. См. Рендеринг предметов.

validator

Проверяет значение компонента.

comboBox имеет следующие общие обработчики:

Элементы

Компонент comboBox может содержать следующие вложенные элементы: itemsQuery, prefix, tooltip, и validator.

Смотрите также