comboBox 下拉列表
comboBox
支持用户从一组预定义的选项中选择单一值。
XML 元素 |
|
---|---|
Java 类 |
|
XML 属性 |
id - alignSelf - allowCustomValue - ariaLabel - ariaLabelledBy - autoOpen - autofocus - classNames - clearButtonVisible - colspan - css - dataContainer - datatype - enabled - errorMessage - focusShortcut - height - helperText - itemsEnum - label - maxHeight - maxWidth - minHeight - minWidth - overlayClass - pageSize - pattern - placeholder - property - readOnly - required - requiredMessage - tabIndex - themeNames - title - visible - width |
事件和处理器 |
AttachEvent - BlurEvent - ClientValidatedEvent - ComponentValueChangeEvent - CustomValueSetEvent - DetachEvent - FocusEvent - itemLabelGenerator - itemsFetchCallback - renderer - statusChangeHandler - validator |
XML 内部元素 |
itemsQuery - prefix - tooltip - validator |
基本用法
comboBox
在用户输入文本时提供对选项值的过滤,以及选项的分页展示。
满足下列情况可以使用 comboBox
:
-
动态过滤。用户需要根据输入的值对选项进行过滤。
comboBox
提供了内置的过滤功能。 -
选项数量大。当选项的数量特别大时,
comboBox
可以对选项进行分页,每次仅展示有限的部分选项,以提升渲染性能。 -
自定义渲染。希望自定义下拉选项的外观,比如可以带有其他信息或样式。
comboBox
为自定义选项的渲染方式提供了更大的灵活性。
使用 comboBox
的最简单情况是为实体属性选择枚举值。例如,User
实体具有 OnboardingStatus
枚举类型的 onboardingStatus
属性。
<data>
<instance class="com.company.onboarding.entity.User" id="userDc"> (1)
<fetchPlan extends="_base"/> (2)
<loader id="userDl"/>
</instance>
</data>
<layout>
<comboBox id="comboBox"
label="Onboarding status"
dataContainer="userDc"
property="onboardingStatus"/> (3)
</layout>
1 | User 实体的 InstanceContainer 容器。 |
2 | 容器内实体的内联 fetch plan。 |
3 | 将组件与数据容器和属性进行关联。dataContainer 属性使用 userDc 数据容器,property 引用 onboardingStatus 实体属性。 |
自定义选项
选项列表
comboBox
的选项列表还可以通过 setItems()
方法设置。
首先在 XML 描述中声明组件:
<data>
<instance class="com.company.onboarding.entity.Step" id="stepDc">
<fetchPlan extends="_base"/>
<loader id="stepDl"/>
</instance>
</data>
<layout>
<comboBox id="durationComboBox"
dataContainer="stepDc"
property="duration"/>
</layout>
然后将组件注入控制器,在 onInit()
方法中设置选项列表:
@ViewComponent
private JmixComboBox<Integer> durationComboBox;
@Subscribe
public void onInit(InitEvent event) {
durationComboBox.setItems(1,2,3,4,5);
}
组件的下拉列表中会显示 1
、2
、3
、4
和 5
。选择的值会设置到 stepDc
数据容器中的 duration
属性上。
选项映射
ComponentUtils.setItemsMap()
可以为每个选项值指定一个字符串标签。
@ViewComponent
private JmixComboBox<Integer> ratingComboBox;
@Subscribe
public void onInit(InitEvent event) {
Map<Integer, String> map = new LinkedHashMap<>();
map.put(2, "Poor");
map.put(3, "Average");
map.put(4, "Good");
map.put(5, "Excellent");
ComponentUtils.setItemsMap(ratingComboBox, map);
}
选项枚举
comboBox
枚举类型的选项可以通过声明式或编程式的方式设置。
itemsEnum
属性定义枚举类作为控件的选项列表。下拉列表中会显示枚举值的本地化名称;组件的值则为枚举的值。
<comboBox label="Onboarding status"
itemsEnum="com.company.onboarding.entity.OnboardingStatus"/>
下面的示例展示了编程式设置的方法。
@ViewComponent
private JmixComboBox<OnboardingStatus> enumComboBox;
@Subscribe
public void onInit(InitEvent event) {
enumComboBox.setItems(OnboardingStatus.class);
}
自定义过滤
默认情况下,comboBox
在对选项进行过滤时使用不区分大小写的子串匹配的方法。也就是说,选项会显示任意位置包含用户输入文本的选项,且不分大小写。
如需自定义过滤行为,可以使用 setItems()
方法的第一个参数:
@ViewComponent
private JmixComboBox<String> colorDropDown;
@Subscribe
public void onInit(InitEvent event) {
List<String> itemsList = List.of("White", "Red", "Blue", "Grey");
colorDropDown.setItems(getStartsWithFilter(), itemsList);
}
protected ComboBox.ItemFilter<String> getStartsWithFilter() {
return (color, filterString) ->
color.toLowerCase().startsWith(filterString.toLowerCase());
}
自定义选项值
comboBox
通过配置可以支持用户输入不在选项列表中的值。
如果 allowCustomValue
属性为 true
,用户可以输入不匹配任何选项的字符串值,此时会触发 CustomValueSetEvent。
comboBox 不会自动处理自定义字符串。请使用 CustomValueSetEvent 进行处理。
|
下面的示例中展示了如何为选项列表添加新的值,并在将来使用:
<comboBox id="colorComboBox"
label="Select the color"
allowCustomValue="true"/>
@ViewComponent
private JmixComboBox<String> colorComboBox;
@Subscribe
public void onInit(InitEvent event) {
colorComboBox.setItems("White", "Red", "Blue", "Grey");
}
@Subscribe("colorComboBox")
public void onColorComboBoxCustomValueSet(CustomValueSetEvent<ComboBox<String>> event) {
colorComboBox.setValue(event.getDetail());
}
选项获取回调
comboBox
可以根据用户输入批量加载选项。
例如,当用户输入 foo
时,组件会从数据库中加载最多 50 个名称中包含 foo
的选项,并在下拉列表显示。当用户向下滚动列表时,组件会获取具有相同查询语句的下一批 50 个选项,并将添加到选项列表中。
声明式配置
要实现这个功能,需要定义内部的 itemsQuery
元素。
itemsQuery
元素需要在内部的 query
元素中定义 JPQL 查询语句,以及通过几个属性配置如何加载数据:
-
escapeValueForLike
- 启用搜索包含特殊符号的值:%
、\
等。默认为false
。 -
searchStringFormat
- 一个包含变量占位符的字符串,该占位符在查询时将替换为实际值。
comboBox
中配置 itemsQuery
的示例:
<comboBox id="userComboBox"
label="User name"
pageSize="30"> (1)
<itemsQuery escapeValueForLike="true"
searchStringFormat="(?i)%${inputString}%"> (2)
<query>
<![CDATA[select e.username from User e where e.username
like :searchString escape '\' order by e.username asc]]>
</query>
</itemsQuery>
</comboBox>
1 | 组件的 pageSize 选项设置每个请求加载选项的最大数量,默认为 50。 |
2 | 可以看到,comboBox 内的 itemsQuery 不需要定义 class 和 fetchPlan 属性,因为查询语句需要返回标量值的一个列表(注意这里使用了 e.name )。如需处理实体,请使用 entityComboBox 组件。 |
编程式配置
选项的获取也可以通过 itemsFetchCallback
处理器编程式定义。示例:
@Autowired
protected DataManager dataManager;
protected Collection<User> users;
@Subscribe
public void onInit(InitEvent event) {
users = dataManager.load(User.class).all().list();
}
@Install(to = "programmaticComboBox", subject = "itemsFetchCallback")
private Stream<User> programmaticComboBoxItemsFetchCallback(Query<User, String> query) {
String enteredValue = query.getFilter()
.orElse("");
return users.stream()
.filter(user -> user.getDisplayName() != null &&
user.getDisplayName().toLowerCase().contains(enteredValue.toLowerCase()))
.skip(query.getOffset())
.limit(query.getLimit());
}
示例中,数据通过 DataManager 获取,但是也可以自定义一个 service 获取。
自定义选项标签
itemLabelGenerator
可以自定选项在列表中如何展示,即控制用户看到的文本,从而能够以更友好或特定于上下文的方式显示信息。
@Install(to = "colorComboBox", subject = "itemLabelGenerator")
private String colorComboBoxItemLabelGenerator(String item) {
return item.toUpperCase();
}
选项渲染
框架提供了自定义选项渲染的功能。可以使用 setRenderer()
方法或 @Supply
注解实现。
<comboBox id="daysComboBox"
itemsEnum="com.company.onboarding.entity.DayOfWeek"/>
@Supply(to = "daysComboBox", subject = "renderer")
private Renderer<DayOfWeek> daysComboBoxRenderer() {
return new ComponentRenderer<>(day -> {
HorizontalLayout layout = uiComponents.create(HorizontalLayout.class);
layout.setPadding(false);
String dayValue = metadataTools.format(day);
H4 label = new H4(dayValue);
JmixButton button = uiComponents.create(JmixButton.class);
button.addThemeVariants(ButtonVariant.LUMO_ICON, ButtonVariant.LUMO_TERTIARY_INLINE);
Icon icon = switch (day) {
case MONDAY -> VaadinIcon.BRIEFCASE.create();
case TUESDAY -> VaadinIcon.LINE_CHART.create();
case WEDNESDAY -> VaadinIcon.TROPHY.create();
case THURSDAY -> VaadinIcon.GROUP.create();
case FRIDAY -> VaadinIcon.CASH.create();
case SATURDAY -> VaadinIcon.GLASS.create();
case SUNDAY -> VaadinIcon.BED.create();
};
button.setIcon(icon);
layout.add(button, label);
return layout;
});
}
Overlay
Overlay 是一个半透明或不透明的图层,用于显示选项的下拉列表。
overlayClass
属性可以为 overlay 元素添加自定义的 CSS 类。
<comboBox id="ratingComboBox"
datatype="int"
overlayClass="my-custom-overlay"/>
在 css 文件中自定义样式:
vaadin-combo-box-overlay.my-custom-overlay::part(overlay){
background-color: #ecfcf9;
border-radius: 5px;
}
样式版本
使用 themeNames 属性可以调整文本对齐、帮助文本显示位置或组件的尺寸。
对齐方式
支持三种对齐方式:align-left
(默认)、align-right
、align-center
。
XML 代码
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
themeNames="align-left"
helperText="The align-left alignment"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
themeNames="align-center"
helperText="The align-center alignment"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
themeNames="align-right"
helperText="The align-right alignment"/>
帮助文本显示位置
设置 helper-above-field
会将帮助文字显示在控件上方而不是默认的下方:
XML 代码
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
label="Onboarding status"
helperText="Helper text with helper-above-field"
themeNames="helper-above-field"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
label="Onboarding status"
helperText="Helper text without helper-above-field"/>
尺寸
支持两种尺寸:默认大小或 small
。
XML 代码
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
helperText="Default size"/>
<comboBox itemsEnum="com.company.onboarding.entity.OnboardingStatus"
themeNames="small"
helperText="Small size"/>
验证
如需检查 comboBox
组件输入的值,可以通过内部元素 validators
使用 validator。
下面是 comboBox
可以使用的预定义验证器:
XML 元素 |
|
---|---|
预定义验证器 |
custom - decimalMax - decimalMin - digits - doubleMax - doubleMin - email - max - min - negativeOrZero - negative - notBlank - notEmpty - notNull - positiveOrZero - positive - regexp - size |
XML 属性
在 Jmix 中,所有组件都有一些作用一致的 通用属性。
下面是 comboBox
的特殊属性:
名称 |
描述 |
默认值 |
---|---|---|
如果 |
|
|
当 |
|
|
|
||
定义需要在 overlay 元素上设置的 CSS 类列表,以空格分隔。参阅 Overlay。 |
||
设置每个请求获取选项的最大数量,值必须大于 0。参阅 选项获取回调。 |
|
事件和处理器
在 Jmix 中,所有组件都有一些 通用事件和处理器,可以按相同的方法设置。
下面是 comboBox
的特殊事件和处理器:
在 Jmix Studio 生成处理器桩代码时,可以使用 Jmix UI 组件面板的 Handlers 标签页或者视图类顶部面板的 Generate Handler 添加,也可以通过 Code → Generate 菜单(Alt+Insert / Cmd+N)生成。 |
名称 |
描述 |
---|---|
|
|
|
|
仅在需要时加载选项数据。参阅 选项获取回调。 |
|
用于设置 |