5.5.2.1.23. LookupField
Компонент для выбора значения из выпадающего списка. Выпадающий список реализует фильтрацию значений по мере ввода пользователя и постраничный вывод доступных значений.
XML-имя компонента: lookupField
.
Компонент LookupField реализован для блоков Web Client и Desktop Client.
-
Простейший вариант использования
LookupField
- выбор значения перечисления (enum
) для атрибута сущности. Например, сущностьRole
имеет атрибутtype
типаRoleType
, который является перечислением. Тогда для редактирования этого атрибута можно использоватьLookupField
следующим образом:<dsContext> <datasource id="roleDs" class="com.haulmont.cuba.security.entity.Role" view="_local"/> </dsContext> <layout> <lookupField datasource="roleDs" property="type"/>
Как видно из примера, в экране описывается источник данных
roleDs
для сущностиRole
. В компонентеlookupField
в атрибуте datasource указывается ссылка на источник данных, а в атрибуте property − название атрибута сущности, значение которого должно быть отображено. В данном случае атрибут является перечислением, и в выпадающем списке будут отображены локализованные названия всех значений этого перечисления. -
Аналогично можно использовать
LookupField
для выбора экземпляра связанной сущности. Для формирования списка опций используется атрибут optionsDatasource:<dsContext> <datasource id="carDs" class="com.company.sample.entity.Car" view="_local"/> <collectionDatasource id="coloursDs" class="com.company.sample.entity.Colour" view="_local"> <query>select c from sample$Colour c</query> </collectionDatasource> </dsContext> <layout> <lookupField datasource="carDs" property="colour" optionsDatasource="coloursDs"/>
В данном случае компонент отобразит отобразит имена экземпляров сущности
Colour
, находящихся в источнике данныхcolorsDs
, а выбранное значение подставится в атрибутcolour
сущностиCar
, находящейся в источнике данныхcarDs
.С помощью атрибута captionProperty можно указать, какой атрибут сущности использовать вместо имени экземпляра для строковых названий опций.
-
Список опций компонента может быть задан произвольно с помощью методов
setOptionsList()
,setOptionsMap()
иsetOptionsEnum()
, либо с помощью XML-атрибутаoptionsDatasource
.-
Метод
setOptionsList()
позволяет программно задать список опций компонента. Для этого объявляем компонент в XML-дескрипторе:<lookupField id="numberOfSeatsField" datasource="modelDs" property="numberOfSeats"/>
Затем инжектируем компонент в контроллер и в методе
init()
задаем ему список опций:@Inject protected LookupField numberOfSeatsField; @Override public void init(Map<String, Object> params) { 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
сущности, находящейся в источнике данныхmodelDs
.
-
Метод
setOptionsMap()
позволяет задать строковые названия и значения опций по отдельности. Например, для описанного в XML-дескрипторе компонентаnumberOfSeatsField
в методеinit()
контроллера задаем мэп опций:@Inject protected LookupField numberOfSeatsField; @Override public void init(Map<String, Object> params) { Map<String, Object> 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
сущности, находящейся в источнике данныхmodelDs
.
-
setOptionsEnum()
принимает в качестве параметра класс перечисления. Выпадающий список будет содержать локализованные названия значений перечисления, значением компонента будет являться выбранное значение перечисления.
-
-
OptionsStyleProvider
позволяет задать отдельные стили для различных значений в выпадающем списке с помощью методаsetOptionsStyleProvider()
:lookupField.setOptionsStyleProvider((field, item) -> { User user = (User) item; switch (user.getGroup().getName()) { case "Company": return "company"; case "Premium": return "premium"; default: return "company"; } });
-
Каждый элемент выпадающего списка может иметь значок слева. Создайте реализацию интерфейса
LookupField.OptionIconProvider
в контроллере экрана и установите ее для компонентаlookupField
:lookupField.setOptionIconProvider(new LookupField.OptionIconProvider<Customer>(){ @Override public String getItemIcon(Customer c){ if(c.getType()== LegalStatus.LEGAL) return"icons/icon-office.png"; return"icons/icon-user.png"; } });
TipПри использовании значков в формате 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 datasource="carDs" property="colour" optionsDatasource="coloursDs" 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
способен обрабатывать ввод пользователя при отсутствии подходящей опции в списке. Для этого используются методыsetNewOptionAllowed()
иsetNewOptionHandler()
. Например:@Inject private Metadata metadata; @Inject protected LookupField colourField; @Inject protected CollectionDatasource<Colour, UUID> coloursDs; @Override public void init(Map<String, Object> params) { colourField.setNewOptionAllowed(true); colourField.setNewOptionHandler(new LookupField.NewOptionHandler() { @Override public void addNewOption(String caption) { Colour colour = metadata.create(Colour.class); colour.setName(caption); coloursDs.addItem(colour); colourField.setValue(colour); } }); }
Обработчик
NewOptionHandler
вызывается, если пользователь ввел некоторое значение, не совпадающее ни с одной из опций, и нажал Enter. В данном случае в обработчике создается новый экземпляр сущностиColour
, его атрибутname
устанавливается в значение, введенное пользователем, этот экземпляр добавляется в источник данных опций и выбирается в компоненте.Вместо имплементации интерфейса
LookupField.NewOptionHandler
для обработки ввода пользователя можно использовать XML-атрибутnewOptionHandler
с указанным в нем методом контроллера. Данный метод должен иметь два параметра - первый типаLookupField
, второй типаString
. В них будут переданы соответственно экзампляр компонента и введенное пользователем значение. АтрибутnewOptionAllowed
используется вместо методаsetNewOptionAllowed()
для того, чтобы разрешить добавление новых опций.
-
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 the text inside the field to center.
-
align-right
- align the text inside the field to the right.
-
borderless
- removes the border and background from the text field.
-
- Атрибуты lookupField
-
align - caption - captionProperty - contextHelpText - contextHelpTextHtmlEnabled - datasource - description - editable - enable - 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 - setOptionsEnum - setOptionsList - setOptionsMap - setOptionsStyleProvider