comboBox
comboBox позволяет пользователям выбирать одно значение из предопределённого списка элементов.
XML-элемент |
|
|---|---|
Java-класс |
|
Основы
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, чтобы определить, как следует обработать введённое пользователем значение.
|
Этот пример демонстрирует возможность добавления новых значений в список элементов, делая их доступными для будущего выбора:
<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");
}
Получение элементов списка
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.
|
|
Программная конфигурация
Извлечение элементов также может быть определено программно с помощью обработчика 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, чтобы добиться этого.
<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;
});
}
Оверлей
Оверлей - это полупрозрачный или непрозрачный слой, который используется для создания выпадающего списка элементов.
Атрибут 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-элемент |
|
|---|---|
elements |
custom - decimalMax - decimalMin - digits - doubleMax - doubleMin - email - max - min - negativeOrZero - negative - notBlank - notEmpty - notNull - positiveOrZero - positive - regexp - size |
Варианты темы
Используйте атрибут themeNames, чтобы применить один или несколько вариантов темы.
| Вариант | Описание | Поддерживается в |
|---|---|---|
|
Уменьшает размер компонента. |
Aura, Lumo |
|
Выравнивает значение поля по левому краю. |
Aura, Lumo |
|
Выравнивает значение поля по центру. |
Aura, Lumo |
|
Выравнивает значение поля по правому краю. |
Aura, Lumo |
|
Размещает вспомогательный текст над полем, под меткой. |
Aura, Lumo |
Атрибуты
comboBox имеет следующие уникальные атрибуты:
| Имя | Описание | По умолчанию |
|---|---|---|
Если атрибут |
|
|
Если атрибут |
|
|
Определяет, отображается ли в поле кнопка очистки. |
|
|
Атрибут |
— |
|
Определяет список имен классов CSS, разделенных пробелами, для установки в элементе наложения. См. Overlay. |
— |
|
Устанавливает максимальное количество элементов, отправляемых за один запрос, должно быть больше нуля. См. Обратный вызов получения предметов. |
|
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
Обработчики
comboBox имеет следующие уникальные обработчики:
| Имя | Описание |
|---|---|
|
|
|
|
Этот обработчик извлекает данные только тогда, когда это необходимо. См. Получение программных элементов. |
|
Устанавливает |
|
Проверяет значение компонента. |
comboBox имеет следующие общие обработчики:
Элементы
Компонент comboBox может содержать следующие вложенные элементы: itemsQuery, prefix, tooltip, и validator.