3.5.2.1.25. 下拉框
该控件支持从下拉列表中选择值。下拉列表提供基于用户的输入对数据进行过滤的功能,也支持分页显示数据。
该组件的 XML 名称是: lookupField
-
使用
LookupField
下拉框最简单的例子是从实体属性中选择枚举值。比如,Role
角色实体中有type
属性,为枚举类型。用户可以通过LookupField
下拉框控件编辑该属性:<data> <instance id="roleDc" class="com.haulmont.cuba.security.entity.Role" view="_local"> <loader/> </instance> </data> <layout expand="editActions" spacing="true"> <lookupField dataContainer="roleDc" property="type"/> </layout>
在上面的例子中,使用
roleDc
数据容器选择Role
实体数据。lookupField
下拉框组件中,数据容器的连接通过 dataContainer 属性定义,实体属性的名称定义在 property 属性中。此时,这个属性为枚举类型,控件的下拉列表中会显示所有枚举值的本地化名称。 -
类似的,
LookupField
下拉框也可以用来选择实体实例。选项容器属性可以用来创建一系列选项:<data> <instance id="carDc" class="com.haulmont.sample.core.entity.Car" view="carEdit"> <loader/> </instance> <collection id="colorsDc" class="com.haulmont.sample.core.entity.Color" view="_minimal"> <loader id="colorsDl"> <query> <![CDATA[select e from sample$Color e]]> </query> </loader> </collection> </data> <layout> <lookupField dataContainer="carDc" property="color" optionsContainer="colorsDc"/> </layout>
这种时候,
colorsDc
数据容器中的Color
实体的实例名称会显示在下拉列表中,被选择的值会被设置到carDc
数据容器中Car
实体的color
属性中。captionProperty定义显示到下拉框的实体属性值,而非实例名称,这样可以设置下拉列表的文字值。
-
选项列表还可以通过
setOptionsList()
,setOptionsMap()
和setOptionsEnum()
设置,也可以在 XML 描述中通过optionsContainer
或者optionsDatasource
属性设置。-
setOptionsList()
- 通过代码指定选项列表。首先在 XML 描述中声明组件:<lookupField id="numberOfSeatsField" dataContainer="modelDc" property="numberOfSeats"/>
然后将组件注入界面控制器,在
onInit()
方法中设置选项列表:@Inject protected LookupField<Integer> numberOfSeatsField; @Subscribe public void onInit(InitEvent event) { List<Integer> list = new ArrayList<>(); list.add(2); list.add(4); list.add(5); list.add(7); numberOfSeatsField.setOptionsList(list); }
组件的下拉列表中会显示 2, 4, 5 和 7。被选择的值会设置到
modelDc
数据容器中的numberOfSeats
属性上。
-
setOptionsMap()
可以提供选项 map。比如为 XML 描述中声明的numberOfSeatsField
组件指定选项 map(在onInit()
方法中):@Inject protected LookupField<Integer> numberOfSeatsField; @Subscribe public void onInit(InitEvent event) { Map<String, Integer> 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
文本。但是组件的值则是与文本对应的数字值。数字值会被设置到modelDc
数据容器中的numberOfSeats
属性上。
-
setOptionsEnum()
需要枚举类做为参数。下拉列表会显示枚举值的本地化名称,组件的值则为枚举值。
-
-
通过
setOptionStyleProvider()
可以为组件显示的不同的选项设置分别的 style name:lookupField.setOptionStyleProvider(entity -> { User user = (User) entity; switch (user.getGroup().getName()) { case "Company": return "company"; case "Premium": return "premium"; default: return "company"; } });
-
下拉列表中的组件可以在左边设置对应的图标。在界面控制器中使用
setOptionIconProvider()
方法设置:lookupField.setOptionIconProvider(entity -> { if (entity.getType() == LegalStatus.LEGAL) return "icons/icon-office.png"; return "icons/icon-user.png"; });
如果使用 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 dataContainer="carDc" property="colour" optionsContainer="colorsDs" 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
组件在没有合适选项的时候可以处理用户的输入,通过setNewOptionHandler()
来处理,示例:@Inject private Metadata metadata; @Inject private LookupField<Color> colorField; @Inject private CollectionContainer<Color> colorsDc; @Subscribe protected void onInit(InitEvent event) { colorField.setNewOptionHandler(caption -> { Color color = metadata.create(Color.class); color.setName(caption); colorsDc.getMutableItems() .add(color); colorField.setValue(color); }); }
当用户输入不匹配任何选项的值并且按下回车键时,会触发调用新选项处理器。这时,上述代码会创建一个新的
Color
实例,name
属性值为用户输入,并且这个实例会加到下拉选项数据容器中,做为该控件当前被选中值。除了使用
setNewOptionHandler()
方法来处理用户输入,还可以在 XML 描述中通过newOptionHandler
属性来指定控制器处理的方法。这个方法需要两个参数,一个是LookupField
类型,指向组件实例,另一个是String
类型,指向用户输入。newOptionAllowed
属性也可以用来开启是否允许输入新值。
-
nullOptionVisible
XML 属性设置是否在下拉列表显示空值。可以配置LookupField
下拉框非 required但是不提供空值选项。
-
textInputAllowed
属性可以禁止过滤器功能及键盘输入。对短列表来说很方便。默认值为true
。
-
pageLength
属性重新设置下拉列表中一页选项的个数,默认值在cuba.gui.lookupFieldPageLength应用程序属性中定义。 -
在基于 Halo 主题的 Web 客户端,可以自定义样式,通过 XML
stylename
属性或在界面控制器中通过代码设置:<lookupField id="lookupField" stylename="borderless"/>
通过代码设置时,从
HaloTheme
类中选择LOOKUPFIELD_
开头的常量样式:lookupField.setStyleName(HaloTheme.LOOKUPFIELD_BORDERLESS);
LookupField 下拉框样式有:
-
align-center
- 文本居中对齐。
-
align-right
- 文本靠右对齐。
-
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 下拉框元素
- LookupField 下拉框样式
-
align-right - align-center - borderless - huge - large - small - tiny
- API
-
addValueChangeListener - commit - discard - isModified - setContextHelpIconClickHandler - setFilterPredicate - setOptionsEnum - setOptionsList - setOptionsMap - setOptionsStyleProvider