3.5.2.1.25. 下拉框

在线示例

API 文档

该控件支持从下拉列表中选择值。下拉列表提供基于用户的输入对数据进行过滤的功能,也支持分页显示数据。

gui lookupField

该组件的 XML 名称是: lookupField

  • 使用 LookupField 下拉框最简单的例子是从实体属性中选择枚举值。比如,Role 角色实体中有 type 属性,为枚举类型。用户可以通过 LookupField 下拉框控件编辑该属性:

    1. <data>
    2. <instance id="roleDc"
    3. class="com.haulmont.cuba.security.entity.Role"
    4. view="_local">
    5. <loader/>
    6. </instance>
    7. </data>
    8. <layout expand="editActions" spacing="true">
    9. <lookupField dataContainer="roleDc" property="type"/>
    10. </layout>

    在上面的例子中,使用 roleDc 数据容器选择 Role 实体数据。lookupField 下拉框组件中,数据容器的连接通过 dataContainer 属性定义,实体属性的名称定义在 property 属性中。此时,这个属性为枚举类型,控件的下拉列表中会显示所有枚举值的本地化名称

  • 类似的,LookupField 下拉框也可以用来选择实体实例。选项容器属性可以用来创建一系列选项:

    1. <data>
    2. <instance id="carDc" class="com.haulmont.sample.core.entity.Car" view="carEdit">
    3. <loader/>
    4. </instance>
    5. <collection id="colorsDc" class="com.haulmont.sample.core.entity.Color" view="_minimal">
    6. <loader id="colorsDl">
    7. <query>
    8. <![CDATA[select e from sample$Color e]]>
    9. </query>
    10. </loader>
    11. </collection>
    12. </data>
    13. <layout>
    14. <lookupField dataContainer="carDc" property="color" optionsContainer="colorsDc"/>
    15. </layout>

    这种时候,colorsDc 数据容器中的 Color 实体的实例名称会显示在下拉列表中,被选择的值会被设置到 carDc 数据容器中 Car 实体的 color 属性中。

    captionProperty定义显示到下拉框的实体属性值,而非实例名称,这样可以设置下拉列表的文字值。

  • 使用 setOptionCaptionProvider() 方法可以为 LookupField 组件显示的字符串选项名定义标题:

    1. lookupField.setOptionCaptionProvider((item) -> item.getLocalizedName());
  • 选项列表还可以通过 setOptionsList()setOptionsMap()setOptionsEnum() 设置,也可以在 XML 描述中通过 optionsContainer 或者 optionsDatasource 属性设置。

    • setOptionsList() - 通过代码指定选项列表。首先在 XML 描述中声明组件:

      1. <lookupField id="numberOfSeatsField" dataContainer="modelDc" property="numberOfSeats"/>

      然后将组件注入界面控制器,在 onInit() 方法中设置选项列表:

      1. @Inject
      2. protected LookupField<Integer> numberOfSeatsField;
      3. @Subscribe
      4. public void onInit(InitEvent event) {
      5. List<Integer> list = new ArrayList<>();
      6. list.add(2);
      7. list.add(4);
      8. list.add(5);
      9. list.add(7);
      10. numberOfSeatsField.setOptionsList(list);
      11. }

      组件的下拉列表中会显示 2, 4, 5 和 7。被选择的值会设置到 modelDc 数据容器中的 numberOfSeats 属性上。

  1. - `setOptionsMap()` 可以提供选项 map。比如为 XML 描述中声明的 `numberOfSeatsField` 组件指定选项 map(在 `onInit()` 方法中):
  2. ```
  3. @Inject
  4. protected LookupField<Integer> numberOfSeatsField;
  5. @Subscribe
  6. public void onInit(InitEvent event) {
  7. Map<String, Integer> map = new LinkedHashMap<>();
  8. map.put("two", 2);
  9. map.put("four", 4);
  10. map.put("five", 5);
  11. map.put("seven", 7);
  12. numberOfSeatsField.setOptionsMap(map);
  13. }
  14. ```
  15. 组件下拉框会显示 `**two**``**four**``**five**``**seven**` 文本。但是组件的值则是与文本对应的数字值。数字值会被设置到 `modelDc` 数据容器中的 `numberOfSeats` 属性上。
  16. - `setOptionsEnum()` 需要枚举类做为参数。下拉列表会显示枚举值的本地化名称,组件的值则为枚举值。
  • setPopupWidth() 可以设置下拉列表的宽度,宽度用字符串格式传递给该方法。使用相对单位(比如,"50%")可以设置下拉列表的宽度是针对于 LookupField 本身的相对值。默认情况下,该宽度设置为 null,下拉列表的宽度为了适应显示内容的宽度而可以大于组件的宽度。通过设置该值为 "100%",可以使得下拉列表的宽度等于 LookupField 的宽度。
  • 通过 setOptionStyleProvider() 可以为组件显示的不同的选项设置分别的 style name:

    1. lookupField.setOptionStyleProvider(entity -> {
    2. User user = (User) entity;
    3. switch (user.getGroup().getName()) {
    4. case "Company":
    5. return "company";
    6. case "Premium":
    7. return "premium";
    8. default:
    9. return "company";
    10. }
    11. });
  • 下拉列表中的组件可以在左边设置对应的图标。在界面控制器中使用 setOptionIconProvider() 方法设置:

    1. lookupField.setOptionIconProvider(entity -> {
    2. if (entity.getType() == LegalStatus.LEGAL)
    3. return "icons/icon-office.png";
    4. return "icons/icon-user.png";
    5. });

    gui lookupField 2

    如果使用 SVG 图标, 显式设置图标大小以避免图标覆盖。

    1. <svg version="1.1"
    2. id="Capa_1"
    3. xmlns="http://www.w3.org/2000/svg"
    4. xmlns:xlink="http://www.w3.org/1999/xlink"
    5. xml:space="preserve"
    6. style="enable-background:new 0 0 55 55;"
    7. viewBox="0 0 55 55"
    8. height="25px"
    9. width="25px">
  • setOptionImageProvider() 方法可以定义 LookupField 组件显示的选项图片。该方法设置一个接收资源类型参数的函数。

    1. @Inject
    2. private LookupField<Customer> lookupField;
    3. @Inject
    4. private Image imageResource;
    5. @Subscribe
    6. private void onInit(InitEvent event) {
    7. lookupField.setOptionImageProvider(e ->
    8. imageResource.createResource(ThemeResource.class).setPath("icons/radio.svg"));
    9. }
  • 如果 LookupField 下拉框组件非required,并且对应的实体属性也非必须,下拉选项会包含一个空行。如果选择了空行,组件值为 null. 使用 nullName 属性设置在“空行”上显示的文本。以下为一个示例:

    1. <lookupField dataContainer="carDc" property="colour" optionsContainer="colorsDs" nullName="(none)"/>

    这样,下拉框中的“空行”上会显示 (none) 文本。如果用户选择了该行,对应的实体属性值会设置为 null

    如果在代码中通过 setOptionsList() 设置了选项, 可以用 setNullOption() 方法设置空行文本,这样,如果用户选择了该行,组件值则为 null

    LookupField 过滤器:

    • filterMode 属性设置基于用户输入的过滤模式:

      • NO − 不过滤。

      • STARTS_WITH − 选项文本以用户输入开头。

      • CONTAINS − 选项文本包含用户输入(默认模式)。

  1. - `setFilterPredicate()` 方法用来设置过滤方法,该方法判断元素是否跟查找文字匹配。比如:
  2. ```
  3. BiFunction<String, String, Boolean> predicate = String::contains;
  4. lookupField.setFilterPredicate((itemCaption, searchString) ->
  5. predicate.apply(itemCaption.toLowerCase(), searchString));
  6. ```
  7. `FilterPredicate` `test` 方法可以用来客户化过滤逻辑,比如处理方言/特殊字符:
  8. ```
  9. lookupField.setFilterPredicate((itemCaption, searchString) ->
  10. StringUtils.replaceChars(itemCaption, "ÉÈËÏÎ", "EEEII")
  11. .toLowerCase()
  12. .contains(searchString));
  13. ```
  • LookupField 组件在没有合适选项的时候可以处理用户的输入,通过 setNewOptionHandler() 来处理,示例:

    1. @Inject
    2. private Metadata metadata;
    3. @Inject
    4. private LookupField<Color> colorField;
    5. @Inject
    6. private CollectionContainer<Color> colorsDc;
    7. @Subscribe
    8. protected void onInit(InitEvent event) {
    9. colorField.setNewOptionHandler(caption -> {
    10. Color color = metadata.create(Color.class);
    11. color.setName(caption);
    12. colorsDc.getMutableItems()
    13. .add(color);
    14. colorField.setValue(color);
    15. });
    16. }

    当用户输入不匹配任何选项的值并且按下回车键时,会触发调用新选项处理器。这时,上述代码会创建一个新的 Color 实例,name 属性值为用户输入,并且这个实例会加到下拉选项数据容器中,做为该控件当前被选中值。

    除了使用 setNewOptionHandler() 方法来处理用户输入,还可以在 XML 描述中通过 newOptionHandler 属性来指定控制器处理的方法。这个方法需要两个参数,一个是 LookupField 类型,指向组件实例,另一个是 String 类型,指向用户输入。newOptionAllowed 属性也可以用来开启是否允许输入新值。

  • nullOptionVisible XML 属性设置是否在下拉列表显示空值。可以配置 LookupField 下拉框非 required但是不提供空值选项。
  • textInputAllowed 属性可以禁止过滤器功能及键盘输入。对短列表来说很方便。默认值为 true
  • pageLength 属性重新设置下拉列表中一页选项的个数,默认值在cuba.gui.lookupFieldPageLength应用程序属性中定义。

  • 在基于 Halo 主题的 Web 客户端,可以自定义样式,通过 XML stylename 属性或在界面控制器中通过代码设置:

    1. <lookupField id="lookupField"
    2. stylename="borderless"/>

    通过代码设置时,从 HaloTheme 类中选择 LOOKUPFIELD_ 开头的常量样式:

    1. lookupField.setStyleName(HaloTheme.LOOKUPFIELD_BORDERLESS);

    LookupField 下拉框样式有:

    • align-center - 文本居中对齐。
  1. - `align-right` - 文本靠右对齐。
  2. - `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 下拉框元素

validator

LookupField 下拉框样式

align-right - align-center - borderless - huge - large - small - tiny

API

addValueChangeListener - commit - discard - isModified - setContextHelpIconClickHandler - setFilterPredicate - setOptionCaptionProvider - setOptionImageProvider - setOptionsEnum - setOptionsList - setOptionsMap - setOptionsStyleProvider - setPopupWidth