EntitySuggestionField

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

EntitySuggestionField – это поле ввода с дополнительной функциональностью: пользователь вводит несколько символов, и если найдено несколько совпадений, в выпадающем списке будут отображен каждый из них. EntitySuggestionField обновляет список опций при каждом вводе символа.

Список опций загружается асинхронно в соответствии с логикой, задаваемой разработчиком на стороне сервера.

EntitySuggestionField является по сути гибридом SuggestionField и EntityPicker.

XML-имя компонента: entitySuggestionField.

Основы

Используйте EntitySuggestionField, если:

  • Пользователям нужно выбрать один экземпляр сущности.

  • Список опций в списке предлагаемых значений слишком длинный для использования EntityComboBox.

  • Вы хотите обеспечить высокую производительность при поиске по базе данных без загрузки большого количества данных на уровень UI.

entity suggestion field

Для создания EntitySuggestionField, связанного с данными, используйте атрибуты dataContainer и property и элемент query:

<data>
    <instance id="addressDc" class="ui.ex1.entity.Address"> (1)
        <fetchPlan extends="_base"> (2)
            <property name="country" fetchPlan="_instance_name"/>
            <property name="city" fetchPlan="_base">
                <property name="country" fetchPlan="_base"/>
            </property>
        </fetchPlan>
    </instance>
</data>
<layout>
    <vbox spacing="true">
        <entitySuggestionField id="countryField"
                               inputPrompt="msg://entitySuggestionField/select"
                               caption="msg://ui.ex1.entity/Address.country"
                               dataContainer="addressDc"
                               property="country">
            <query entityClass="ui.ex1.entity.Country"
                   searchStringFormat="%${searchString}%"
                   escapeValueForLike="true"
                   fetchPlan="_instance_name">
                <![CDATA[select c from uiex1_Country c where lower(c.name)
                like lower(:searchString) escape '\']]>
            </query>
        </entitySuggestionField>
    </vbox>
</layout>
1 InstanceContainer для сущности Address.
2 Встроенный фетч-план экземпляра сущности, расположенного в контейнере.

В приведенном выше примере экран определяет контейнер данных addressDc для сущности Address, имеющей атрибут country. В элементе entitySuggestionField атрибут dataContainer содержит ссылку на контейнер данных addressDc, а атрибут property ссылается на атрибут сущности country. Этот атрибут должен быть ссылкой на сущность. В данном примере это Country.

Определение опций

Список опций можно определить либо в XML-дескрипторе с помощью вложенного элемента query, либо программно в контроллере с помощью интерфейса SearchExecutor.

query

query – необязательный элемент, позволяющий задать запрос для выбора предлагаемых значений.

Элемент query имеет следующие атрибуты:

  • entityClass (обязательный) - полное квалифицированное имя класса сущности.

  • fetchPlan - дополнительный атрибут, задающий фетч-план, с которым будет загружена сущность.

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

  • searchStringFormat - строка Groovy, что позволяет использовать в запросе валидные Groovy-выражения.

SearchExecutor

Если query не определен, необходимо задать список опций программно с помощью SearchExecutor.

SearchExecutor – это функциональный интерфейс, содержащий один метод: List<E> search(String searchString, Map<String, Object> searchParams).

Используйте параметр searchString для фильтрации кандидатов по строке, введенной пользователем. Use the searchString parameter to filter candidates using the string entered by the user.

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

<entitySuggestionField id="entityField"
                       dataContainer="addressDc"
                       property="country"
                       caption="Country"/>

Затем задайте SearchExecutor для компонента:

@Autowired
private DataManager dataManager;

@Install(to = "entityField", subject = "searchExecutor")
private List entityFieldSearchExecutor(String searchString,
                                       Map<String, Object> searchParams) {
    return dataManager.load(Country.class)
            .query("e.name like ?1 order by e.name", "(?i)%" + searchString + "%")
            .list();
}

Заглушку реализации SearchExecutor можно генерировать с помощью Studio.

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

Метод escapeForLike() можно использовать для поиска значений, содержащих некоторые специальные символы:

@Autowired
private DataManager dataManager;

@Install(to = "entitySuggestionField", subject = "searchExecutor")
private List<Customer> entitySuggestionFieldSearchExecutor(String searchString,
                                                           Map<String, Object> searchParams) {
    searchString = QueryUtils.escapeForLike(searchString);
    return dataManager.load(Customer.class)
            .query("e.firstName like ?1 escape '\\' order by e.firstName", "(?i)%"
                    + searchString + "%")
            .list();
}

metaClass

Компонент EntitySuggestionField можно использовать без непосредственной привязки к данным, то есть без указания dataContainer и property. В этом случае для указания типа сущности, с которой должен работать EntitySuggestionField, используется атрибут metaClass.

<entitySuggestionField id="metaClassField"
                       metaClass="uiex1_Country"
                       caption="Country"/>

Логика поиска определяется с помощью SearchExecutor:

@Autowired
private DataManager dataManager;

@Install(to = "metaClassField", subject = "searchExecutor")
private List<Country> metaClassFieldSearchExecutor(String searchString,
                                                   Map<String, Object> searchParams) {
    return dataManager.load(Country.class)
            .query("e.name like ?1 order by e.name", "(?i)%" + searchString + "%")
            .list();
}

Действия

Для EntitySuggestionField можно определить настраиваемые и предопределенные действия, отображаемые в виде кнопок справа. Это можно сделать либо в XML-дескрипторе с помощью вложенного элемента actions, либо программно в контроллере с помощью метода addAction().

Предопределенные действия

Если создать EntitySuggestionField без действий, загрузчик XML определит для него только действия entity_lookup и entity_open. Существуют также действия entity_clear и entity_openComposition.

Чтобы добавить другое предопределенное действие, например, entity_clear, нужно определить элемент actions следующим образом:

<entitySuggestionField dataContainer="addressDc"
                       property="country"
                       caption="Country">
    <actions>
        <action id="lookup" type="entity_lookup"/>
        <action id="open" type="entity_open"/>
        <action id="clear" type="entity_clear"/>
    </actions>
</entitySuggestionField>

Элемент actions не дополняет, а переопределяет набор стандартных действий. Вам необходимо явно указывать идентификаторы всех требуемых действий.

Используйте addAction(), чтобы задать действия программно. Если компонент определен в XML-дескрипторе без вложенного элемента actions, достаточно добавить недостающие действия:

@Autowired
private EntitySuggestionField<Country> entitySuggestionField;

@Autowired
private Actions actions;

@Subscribe
public void onInit(InitEvent event) {
    entitySuggestionField.addAction(actions.create(EntityClearAction.class));
}

Настраиваемые действия

Настраиваемые действия для EntitySuggestionField схожи с настраиваемые действиями для EntityPicker.

События и слушатели

Чтобы сгенерировать заглушку слушателя в Jmix Studio, выберите компонент в XML-дескрипторе экрана или на панели иерархии Jmix UI и используйте вкладку Handlers на панели инспектора Jmix UI.

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

ArrowDownHandler

ArrowDownEvent отправляется, когда пользователь нажимает клавишу Arrow Down при скрытом всплывающем окне с подсказками.

Вы можете настроить свой обработчик событий и использовать метод EntitySuggestionField.showSuggestions(), который принимает список сущностей для отображения подсказок:

@Autowired
private CollectionContainer<Country> countriesDc;

@Autowired
private EntitySuggestionField<Country> countryField;

@Install(to = "countryField", subject = "arrowDownHandler")
private void countryFieldArrowDownHandler(SuggestionFieldComponent.ArrowDownEvent
                                                      arrowDownEvent) {
    countryField.showSuggestions(new ArrayList<>(countriesDc.getItems()));
}

ContextHelpIconClickHandler

EnterPressHandler

See the example of programmatic registration in the Handling User Input section for ComboBox.

EnterPressHandler can be provided declaratively using the @Install annotation in the screen controller. See this example in the Handling User Input section for EntityComboBox.

FieldIconProvider

FieldValueChangeEvent

Formatter

Добавляет экземпляр formatter в компонент.

В приведенном ниже примере показано использование formatter для поля с подсказками сущностей cityFieldFormat:

@Install(to = "cityFieldFormat", subject = "formatter")
protected String cityFieldFormatFormatter(City value) {
    return value != null
            ? value.getName() + " (" + (value.getCountry() != null
            ? value.getCountry().getName() : "not defined") + ")"
            : null;
}

Чтобы добавить formatter программно, используйте метод компонента setFormatter().

OptionCaptionProvider

SearchExecutor

Validator

См. Validator.

ValueChangeEvent

XML-атрибуты EntitySuggestionField

Просматривать и редактировать атрибуты, применимые к компоненту, можно с помощью панели инспектора Jmix UI в конструкторе экранов Studio.

XML-элементы EntitySuggestionField