5.5.2.1.37. SuggestionField

Компонент SuggestionField предназначен для поиска экземпляров сущности по строке, вводимой пользователем. Он отличается от SuggestionPickerField тем, что может возвращать любые типы значений, например, сущности, строки или перечисления, а также не имеет кнопок для действий. Список опций загружается асинхронно в соответствии с логикой, задаваемой разработчиком на стороне сервера.

gui suggestionField 1

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

Компонент реализован для блока Web Client.

Атрибуты suggestionField:

  • asyncSearchDelayMs - устанавливает задержку между последним нажатием клавиши и асинхронным поиском.

  • minSearchStringLength - устанавливает минимальную длину строки для начала поиска.

  • popupWidth - устанавливает ширину всплывающей подсказки.

    Возможные значения:

    • auto - ширина поля подсказки равна максимальной ширине текста подсказки,

    • parent - ширина поля подсказки равна ширине основного компонента,

    • абсолютное (например, "170px") или относительное (например, "50%") значение.

  • suggestionsLimit - устанавливает ограничение количества выводимых подсказок.

Элементы suggestionField:

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

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

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

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

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

    <suggestionField id="suggestionField"
                     captionProperty="login">
        <query entityClass="com.haulmont.cuba.security.entity.User"
               escapeValueForLike="true"
               view="user.edit"
               searchStringFormat="%$searchString%">
            select e from sec$User e where e.login like :searchString
        </query>
    </suggestionField>

    Если элемент query не задан, то список опций должен быть предоставлен объектом типа SearchExecutor, созданным программно (см. ниже).

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

suggestionField.setSearchExecutor((searchString, searchParams) -> {
    return Arrays.asList(entity1, entity2, ...);
});

SearchExecutor может возвращать любые типы значений, например, сущности, строки или перечисления.

  • Сущности:

customersDs.refresh();
List<Customer> customers = new ArrayList<>(customersDs.getItems());
suggestionField.setSearchExecutor((searchString, searchParams) ->
        customers.stream()
                .filter(customer -> StringUtils.containsIgnoreCase(customer.getName(), searchString))
                .collect(Collectors.toList()));
  • Строки:

List<String> strings = Arrays.asList("Red", "Green", "Blue", "Cyan", "Magenta", "Yellow");
stringSuggestionField.setSearchExecutor((searchString, searchParams) ->
        strings.stream()
                .filter(str -> StringUtils.containsIgnoreCase(str, searchString))
                .collect(Collectors.toList()));
  • Перечисления:

List<SendingStatus> enums = Arrays.asList(SendingStatus.values());
enumSuggestionField.setSearchExecutor((searchString, searchParams) ->
        enums.stream()
                .map(sendingStatus -> messages.getMessage(sendingStatus))
                .filter(str -> StringUtils.containsIgnoreCase(str, searchString))
                .collect(Collectors.toList()));
  • Класс OptionWrapper используется тогда, когда необходимо отделить значение любого типа от его строкового представления:

List<OptionWrapper> wrappers = Arrays.asList(
        new OptionWrapper("One", 1),
        new OptionWrapper("Two", 2),
        new OptionWrapper("Three", 3);
suggestionField.setSearchExecutor((searchString, searchParams) ->
        wrappers.stream()
                .filter(optionWrapper -> StringUtils.containsIgnoreCase(optionWrapper.getCaption(), searchString))
                .collect(Collectors.toList()));
Warning

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

Параметр searchString может быть использован для фильтрации кандидатов по строке, введенной пользователем. Чтобы искать по значениям, содержащим специальные символы, используйте метод escapeForLike():

suggestionField.setSearchExecutor((searchString, searchParams) -> {
    searchString = QueryUtils.escapeForLike(searchString);
    return dataManager.loadList(LoadContext.create(Customer.class).setQuery(
            LoadContext.createQuery("select c from sample$Customer c where c.name like :name order by c.name escape '\\'")
                .setParameter("name", "%" + searchString + "%")));
});
  • OptionsStyleProvider позволяет задать отдельные стили для различных значений подсказок, отображаемых компонентом suggestionField:

    suggestionField.setOptionsStyleProvider((field, item) -> {
        User user = (User) item;
        switch (user.getGroup().getName()) {
            case "Company":
                return "company";
            case "Premium":
                return "premium";
            default:
                return "company";
        }
    });