3.5.2.1.25. LookupField
Компонент для выбора значения из выпадающего списка. Выпадающий список реализует фильтрацию значений по мере ввода пользователя и постраничный вывод доступных значений.
XML-имя компонента: lookupField
.
-
Простейший вариант использования
LookupField
- выбор значения перечисления (enum
) для атрибута сущности. Например, сущностьRole
имеет атрибутtype
типаRoleType
, который является перечислением. Тогда для редактирования этого атрибута можно использоватьLookupField
следующим образом:<data> <instance id="roleDc" class="com.haulmont.cuba.security.entity.Role" view="_local"> <loader/> </instance> </data> <layout expand="editActions" spacing="true"> <lookupField dataContainer="roleDc" property="type"/> </layout>
Как видно из примера, в экране описывается data container
roleDc
для сущностиRole
. В компонентеlookupField
в атрибуте dataContainer указывается ссылка на источник данных, а в атрибуте property − название атрибута сущности, значение которого должно быть отображено. В данном случае атрибут является перечислением, и в выпадающем списке будут отображены локализованные названия всех значений этого перечисления. -
Аналогично можно использовать
LookupField
для выбора экземпляра связанной сущности. Для формирования списка опций используется атрибут optionsContainer:<data> <instance id="carDc" class="com.haulmont.sample.core.entity.Car" view="carEdit"> <loader/> </instance> <collection id="colorsDc" class="com.haulmont.sample.core.entity.Color" view="_minimal"> <loader id="colorsDl"> <query> <![CDATA[select e from sample$Color e]]> </query> </loader> </collection> </data> <layout> <lookupField dataContainer="carDc" property="color" optionsContainer="colorsDc"/> </layout>
В данном случае компонент отобразит имена экземпляров сущности
Color
, находящихся в коллекции данныхcolorsDs
, а выбранное значение подставится в атрибутcolor
сущностиCar
, находящейся в контейнереcarDs
.С помощью атрибута captionProperty можно указать, какой атрибут сущности использовать вместо имени экземпляра для строковых названий опций.
-
Метод
setOptionCaptionProvider()
позволяет задать заголовки для строковых названий опций, отображаемых компонентомLookupField
:lookupField.setOptionCaptionProvider((item) -> item.getLocalizedName());
-
Список опций компонента может быть задан произвольно с помощью методов
setOptionsList()
,setOptionsMap()
иsetOptionsEnum()
, либо с помощью XML-атрибутаoptionsContainer
илиoptionsDatasource
.-
Метод
setOptionsList()
позволяет программно задать список опций компонента. Для этого объявляем компонент в XML-дескрипторе:<lookupField id="numberOfSeatsField" dataContainer="modelDc" property="numberOfSeats"/>
Затем инжектируем компонент в контроллер и в методе
onInit()
задаем ему список опций:@Inject protected LookupField<Integer> numberOfSeatsField; @Subscribe public void onInit(InitEvent event) { List<Integer> list = new ArrayList<>(); list.add(2); list.add(4); list.add(5); list.add(7); numberOfSeatsField.setOptionsList(list); }
В выпадающем списке компонента отобразятся числа 2, 4, 5, 7. Выбранное число подставится в атрибут
numberOfSeats
сущности, находящейся в контейнере данныхmodelDс
.
-
Метод
setOptionsMap()
позволяет задать строковые названия и значения опций по отдельности. Например, для описанного в XML-дескрипторе компонентаnumberOfSeatsField
в методеonInit()
контроллера задаем мэп опций:@Inject protected LookupField<Integer> numberOfSeatsField; @Subscribe public void onInit(InitEvent event) { Map<String, Integer> map = new LinkedHashMap<>(); map.put("two", 2); map.put("four", 4); map.put("five", 5); map.put("seven", 7); numberOfSeatsField.setOptionsMap(map); }
В выпадающем списке компонента отобразятся строки
two
,four
,five
,seven
. Однако значением компонента будет число, соответствующее выбранной строке. Оно и подставится в атрибутnumberOfSeats
сущности, находящейся в контейнере данныхmodelDс
.
-
setOptionsEnum()
принимает в качестве параметра класс перечисления. Выпадающий список будет содержать локализованные названия значений перечисления, значением компонента будет являться выбранное значение перечисления.
-
-
setOptionStyleProvider()
позволяет задать отдельные стили для различных значений в выпадающем списке:lookupField.setOptionStyleProvider(entity -> { User user = (User) entity; switch (user.getGroup().getName()) { case "Company": return "company"; case "Premium": return "premium"; default: return "company"; } });
-
Каждый элемент выпадающего списка может иметь значок слева. Чтобы установить значки, используйте метод
setOptionIconProvider()
:lookupField.setOptionIconProvider(entity -> { if (entity.getType() == LegalStatus.LEGAL) return "icons/icon-office.png"; return "icons/icon-user.png"; });
При использовании значков в формате SVG необходимо явно указывать их размеры, чтобы избежать наложения:
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="enable-background:new 0 0 55 55;" viewBox="0 0 55 55" height="25px" width="25px">
-
Если у компонента
LookupField
не установлен атрибут required, и если связанный атрибут сущности не объявлен как обязательный, то в списке опций компонента присутствует пустая строка, при выборе которой компонент возвращает значениеnull
. Атрибут nullName позволяет задать строку, отображаемую в этом случае вместо пустой. Пример использования:<lookupField dataContainer="carDc" property="colour" optionsContainer="colorsDs" nullName="(none)"/>
В данном случае вместо пустой строки отобразится строка
(none)
, при выборе которой в связанный атрибут сущности подставится значениеnull
.При программном задании списка опций методом
setOptionsList()
можно одну из опций передать в методsetNullOption()
. Тогда при ее выборе пользователем значением компонента будетnull
.- Фильтрация опций LookupField:
-
-
С помощью атрибута
filterMode
можно задать тип фильтрации опций при вводе пользователя:-
NO
− нет фильтрации. -
STARTS_WITH
− по началу фразы. -
CONTAINS
− по любому вхождению (используется по умолчанию).
-
-
Метод
setFilterPredicate()
позволяет настроить способ фильтрации. Предикат проверяет, совпадает ли введённая пользователем строка со заголовком элемента в списке, к примеру:BiFunction<String, String, Boolean> predicate = String::contains; lookupField.setFilterPredicate((itemCaption, searchString) -> predicate.apply(itemCaption.toLowerCase(), searchString));
Функциональный интерфейс
FilterPredicate
содержит методtest
, который позволяет реализовать более сложную логику фильтрации опций, например, игнорировать специальные символы или надстрочные знаки:lookupField.setFilterPredicate((itemCaption, searchString) -> StringUtils.replaceChars(itemCaption, "ÉÈËÏÎ", "EEEII") .toLowerCase() .contains(searchString));
-
-
Компонент
LookupField
способен обрабатывать ввод пользователя при отсутствии подходящей опции в списке. Для этого используется методsetNewOptionHandler()
. Например:@Inject private Metadata metadata; @Inject private LookupField<Color> colorField; @Inject private CollectionContainer<Color> colorsDc; @Subscribe protected void onInit(InitEvent event) { colorField.setNewOptionHandler(caption -> { Color color = metadata.create(Color.class); color.setName(caption); colorsDc.getMutableItems() .add(color); colorField.setValue(color); }); }
Обработчик новых опций вызывается, если пользователь ввел некоторое значение, не совпадающее ни с одной из опций, и нажал Enter. В данном случае в обработчике создается новый экземпляр сущности
Color
, его атрибутname
устанавливается в значение, введенное пользователем, этот экземпляр добавляется в источник данных опций и выбирается в компоненте.Вместо метода
setNewOptionHandler()
для обработки ввода пользователя можно использовать XML-атрибутnewOptionHandler
с указанным в нем методом контроллера. Данный метод должен иметь два параметра - первый типаLookupField
, второй типаString
. В них будут переданы соответственно экземпляр компонента и введенное пользователем значение. АтрибутnewOptionAllowed
используется, чтобы разрешить добавление новых опций.
-
XML-атрибут
nullOptionVisible
устанавливает видимость элемента со значением null в списке опций. Может работать только если атрибут required имеет значениеfalse
.
-
XML-атрибут
textInputAllowed
используется для отключения возможности фильтрации опций с клавиатуры. Это бывает удобно для коротких списков. Значение по умолчанию -true
.
-
XML-атрибут
pageLength
позволяет переопределить количество опций на одной странице выпадающего списка, заданное свойством приложения cuba.gui.lookupFieldPageLength. -
В веб-клиенте с темой, основанной на Halo, к компоненту
LookupField
можно применить предопределенные стили. Стили задаются в XML-дексрипторе или контроллере экрана с помощью атрибутаstylename
:<lookupField id="lookupField" stylename="borderless"/>
Чтобы применить стиль программно, выберите одну из констант класса
HaloTheme
с префиксом компонентаLOOKUPFIELD_
:lookupField.setStyleName(HaloTheme.LOOKUPFIELD_BORDERLESS);
Стили компонента LookupField:
-
align-center
- выравнивание текста по центру области.
-
align-right
- выравнивание текста по правому краю области.
-
borderless
- удаляет рамку и фон текстовой области.
-
- Атрибуты lookupField
-
align - caption - captionAsHtml - captionProperty - contextHelpText - contextHelpTextHtmlEnabled - css - dataContainer - datasource - description - descriptionAsHtml - editable - enable - box.expandRatio - filterMode - height - icon - id - inputPrompt - newOptionAllowed - newOptionHandler - nullName - nullOptionVisible - optionsDatasource - optionsEnum - pageLength - property - required - requiredMessage - stylename - tabIndex - textInputAllowed - visible - width
- Элементы lookupField
- Предопределенные стили lookupField
-
align-right - align-center - borderless - huge - large - small - tiny
- API
-
addValueChangeListener - commit - discard - isModified - setContextHelpIconClickHandler - setFilterPredicate - setOptionCaptionProvider - setOptionsEnum - setOptionsList - setOptionsMap - setOptionsStyleProvider