comboBox

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

XML-элемент

comboBox

Java-класс

JmixComboBox

Атрибуты

id - alignSelf - allowCustomValue - ariaLabel - ariaLabelledBy - autoOpen - autofocus - classNames - clearButtonVisible - colspan - css - dataContainer - datatype - enabled - errorMessage - focusShortcut - height - helperText - itemsEnum - label - maxHeight - maxWidth - minHeight - minWidth - overlayClass - pageSize - pattern - placeholder - property - readOnly - required - requiredMessage - tabIndex - themeNames - title - visible - width

Обработчики

AttachEvent - BlurEvent - ClientValidatedEvent - ComponentValueChangeEvent - CustomValueSetEvent - DetachEvent - FocusEvent - itemLabelGenerator - itemsFetchCallback - renderer - statusChangeHandler - validator

Элементы

itemsQuery - prefix - tooltip - validator

Основы

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

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

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

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

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

Простейший случай использования comboBox - это выбор значения перечисления для атрибута сущности. Например, сущность User имеет атрибут onboardingStatus типа OnboardingStatus, который является перечислением.

combo box basic
<data>
    <instance class="com.company.onboarding.entity.User" id="userDc"> (1)
        <fetchPlan extends="_base"/> (2)
        <loader id="userDl"/>
    </instance>
</data>
<layout>
    <comboBox id="comboBox"
              label="Onboarding status"
              dataContainer="userDc"
              property="onboardingStatus"/> (3)
</layout>
1 InstanceContainer для сущности User.
2 Встроенный план выборки экземпляра сущности, находящегося в контейнере.
3 Привязка компонента к контейнеру данных и свойству. Атрибут dataContainer содержит ссылку на контейнер данных userDc, а атрибут property ссылается на атрибут сущности onboardingStatus.

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

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

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

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

<data>
    <instance class="com.company.onboarding.entity.Step" id="stepDc">
        <fetchPlan extends="_base"/>
        <loader id="stepDl"/>
    </instance>
</data>
<layout>
    <comboBox id="durationComboBox"
              dataContainer="stepDc"
              property="duration"/>
</layout>

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

@ViewComponent
private JmixComboBox<Integer> durationComboBox;

@Subscribe
public void onInit(InitEvent event) {
    durationComboBox.setItems(1,2,3,4,5);
}

В выпадающем списке компонента будут отображаться значения 1, 2, 3, 4 и 5. Выбранное значение будет помещено в атрибут duration сущности, находящейся в контейнере данных stepDc.

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

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

@ViewComponent
private JmixComboBox<Integer> ratingComboBox;

@Subscribe
public void onInit(InitEvent event) {
    Map<Integer, String> map = new LinkedHashMap<>();
    map.put(2, "Poor");
    map.put(3, "Average");
    map.put(4, "Good");
    map.put(5, "Excellent");
    ComponentUtils.setItemsMap(ratingComboBox, map);
}

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

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

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

<comboBox label="Onboarding status"
          itemsEnum="com.company.onboarding.entity.OnboardingStatus"/>

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

@ViewComponent
private JmixComboBox<OnboardingStatus> enumComboBox;

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

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

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

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

@ViewComponent
private JmixComboBox<String> colorDropDown;

@Subscribe
public void onInit(InitEvent event) {
    List<String> itemsList = List.of("White", "Red", "Blue", "Grey");
    colorDropDown.setItems(getStartsWithFilter(), itemsList);

}
protected ComboBox.ItemFilter<String> getStartsWithFilter() {
    return (color, filterString) ->
            color.toLowerCase().startsWith(filterString.toLowerCase());
}

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

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

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

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

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

<comboBox id="colorComboBox"
          label="Select the color"
          allowCustomValue="true"/>
@ViewComponent
private JmixComboBox<String> colorComboBox;

@Subscribe
public void onInit(InitEvent event) {
    colorComboBox.setItems("White", "Red", "Blue", "Grey");
}

@Subscribe("colorComboBox")
public void onColorComboBoxCustomValueSet(CustomValueSetEvent<ComboBox<String>> event) {
    colorComboBox.setValue(event.getDetail());
}

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

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

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

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

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

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

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

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

Пример itemsQuery в comboBox:

<comboBox id="userComboBox"
          label="User name"
          pageSize="30"> (1)
    <itemsQuery escapeValueForLike="true"
                searchStringFormat="(?i)%${inputString}%"> (2)
        <query>
            <![CDATA[select e.username from User e where e.username
            like :searchString escape '\' order by e.username asc]]>
        </query>
    </itemsQuery>
</comboBox>
1 Атрибут pageSize определяет размер пакета при загрузке данных из базы данных. По умолчанию он равен 50.
2 Как вы можете видеть, itemsQuery в comboBox не требует атрибутов class и fetchPlan, поскольку предполагается, что запрос возвращает список скалярных значений (обратите внимание на e.name в результирующем наборе). Для работы с сущностями используйте компонент entityComboBox.

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

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

@Autowired
protected DataManager dataManager;

protected Collection<User> users;

@Subscribe
public void onInit(InitEvent event) {
    users = dataManager.load(User.class).all().list();
}

@Install(to = "programmaticComboBox", subject = "itemsFetchCallback")
private Stream<User> programmaticComboBoxItemsFetchCallback(Query<User, String> query) {
    String enteredValue = query.getFilter()
            .orElse("");

    return users.stream()
            .filter(user -> user.getDisplayName() != null &&
                    user.getDisplayName().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, чтобы добиться этого.

<comboBox id="daysComboBox"
          itemsEnum="com.company.onboarding.entity.DayOfWeek"/>
@Supply(to = "daysComboBox", subject = "renderer")
private Renderer<DayOfWeek> daysComboBoxRenderer() {
    return new ComponentRenderer<>(day -> {
        HorizontalLayout layout = uiComponents.create(HorizontalLayout.class);
        layout.setPadding(false);

        String dayValue = metadataTools.format(day);
        H4 label = new H4(dayValue);

        JmixButton button = uiComponents.create(JmixButton.class);
        button.addThemeVariants(ButtonVariant.LUMO_ICON, ButtonVariant.LUMO_TERTIARY_INLINE);
        Icon icon = switch (day) {
            case MONDAY -> VaadinIcon.BRIEFCASE.create();
            case TUESDAY -> VaadinIcon.LINE_CHART.create();
            case WEDNESDAY -> VaadinIcon.TROPHY.create();
            case THURSDAY -> VaadinIcon.GROUP.create();
            case FRIDAY -> VaadinIcon.CASH.create();
            case SATURDAY -> VaadinIcon.GLASS.create();
            case SUNDAY -> VaadinIcon.BED.create();
        };
        button.setIcon(icon);
        layout.add(button, label);
        return layout;
    });
}

Оверлей

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

Атрибут 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;
}

Варианты оформления

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

Выравнивание

Выберите один из трёх вариантов выравнивания: align-left (по умолчанию), align-right (по правому краю), align-center (по центру).

combo box alignment
XML code
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
          themeNames="align-left"
          helperText="The align-left alignment"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
          themeNames="align-center"
          helperText="The align-center alignment"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
          themeNames="align-right"
          helperText="The align-right alignment"/>

Позиция подсказки

Установив helper-above-field, вы переместите подсказку с её стандартного положения под полем на позицию над ним.

combo box helper above field
XML code
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
          label="Onboarding status"
          helperText="Helper text with helper-above-field"
          themeNames="helper-above-field"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
          label="Onboarding status"
          helperText="Helper text without helper-above-field"/>

Размер

Доступны два варианта размера: размер по умолчанию и small.

combo box size
XML code
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
          helperText="Default size"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
          themeNames="small"
          helperText="Small size"/>

Валидация

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

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

XML-элемент

validators

Предопределенные валидаторы

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

Атрибуты

В Jmix есть множество общих атрибутов, которые выполняют одну и ту же функцию для всех компонентов.

Ниже приведены атрибуты, специфичные для comboBox:

Название

Описание

Значение по умолчанию

allowCustomValue

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

false

autoOpen

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

true

itemsEnum

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

overlayClass

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

pageSize

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

50

Обработчики

В Jmix существует множество общих обработчиков, которые конфигурируются одинаково для всех компонентов.

Ниже приведены обработчики, специфичные для comboBox.

Чтобы сгенерировать заглушку обработчика в Jmix Studio, используйте вкладку Handlers панели инспектора Jmix UI, или команду Generate Handler, доступную на верхней панели контроллера экрана и через меню CodeGenerate (Alt+Insert / Cmd+N).

Название

Описание

CustomValueSetEvent

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

itemLabelGenerator

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

itemsFetchCallback

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

renderer

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

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

Смотрите документацию Vaadin для получения дополнительной информации.