3.5.2.1.42. 建议字段

SuggestionField 组件用于根据用户输入的字符串搜索一些值。它与 SuggestionPickerField 的不同之处在于它可以使用任何类型的选项:例如,实体、字符串或枚举值,并且没有操作按钮。选项列表是根据应用程序开发人员定义的逻辑在后端加载。

gui suggestionField 1

该组件的 XML 名称: suggestionField

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 escape '\'
        </query>
    </suggestionField>

    如果未定义查询,则必须使用 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()));

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";
        }
    });

SuggestionField 的展示可以使用带 $cuba-suggestionfield-* 前缀的 SCSS 变量进行自定义。可以在创建一个 主题扩展 或者一个 自定义主题 之后在可视化编辑器里修改这些变量的值。