select 单选

select 支持用户从列表中选择单一值。

XML 元素

select

Java 类

JmixSelect

基本用法

select 与 comboBox 类似。

下列情况请使用 select:

  • 当不需要用户输入对选项进行过滤时。

  • 选项列表需要是紧凑的。如果选项对于 radioButtonGroup 过多的话,可以用该组件。

select 最基本的用法就是从枚举中选择值:

<select itemsEnum="io.jmix.uisamples.entity.CustomerGrade"
        emptySelectionAllowed="true" emptySelectionCaption="Empty"/>

数据感知的 select

使用 dataContainer 和 property 属性将 select 与一个实体属性绑定。数据容器提供实体实例,property 表示需要使用该组件编辑的属性。

默认情况下,Jmix Studio 在创建带有枚举类型属性的实体详情视图时会生成 select。例如,User 实体的 onboardingStatus 属性是 OnboardingStatus 枚举类型。

XML
<data>
    <instance id="customerDc"
              class="io.jmix.uisamples.entity.Customer"
              fetchPlan="_local"/>
</data>
<layout>
    <select id="select" label="Grade" dataContainer="customerDc" property="grade"/>
    <hbox>
        <span text="Value in the container:"/>
        <span id="spanValue"/>
    </hbox>
</layout>
Java
@ViewComponent
protected InstanceContainer<Customer> customerDc;
@ViewComponent
protected Span spanValue;

@Autowired
protected Metadata metadata;

@Subscribe
protected void onInit(InitEvent event) {
    Customer customer = metadata.create(Customer.class);
    customer.setGrade(CustomerGrade.PREMIUM);
    customerDc.setItem(customer);
}

@Subscribe("select")
protected void onSelectValueChange(
        ComponentValueChangeEvent<JmixSelect<CustomerGrade>, CustomerGrade> changeEvent) {
    spanValue.setText(customerDc.getItem().getGrade().name());
}

下面的示例演示如何用 select 组件选择用户所属的部门:

<data>
    <instance class="com.company.onboarding.entity.User"
              id="userDc"> (1)
        <fetchPlan extends="_base"> (2)
            <property name="department" fetchPlan="_base"/>
        </fetchPlan>
        <loader id="userDl"/>
    </instance>
    <collection class="com.company.onboarding.entity.Department"
                id="departmentsDc"> (3)
        <fetchPlan extends="_base"/>
        <loader id="departmentsDl">
            <query>
                <![CDATA[select e from Department e]]>
            </query>
        </loader>
    </collection>
</data>
<facets>
    <dataLoadCoordinator auto="true"/> (4)
</facets>
<layout>
    <select dataContainer="userDc"
            property="department"
            itemsContainer="departmentsDc"/> (5)
</layout>
1 数据容器包含当前编辑的 User 实例。
2 定义获取作为选项的 Department 实例的 fetch plan。
3 包含 Department 实例集合的数据容器。
4 数据加载器自动加载为组件提供选项。
5 将组件与数据容器和属性进行关联。通过 itemsContainer 属性指定选项列表。

选项的构建

可以通过下列方法为 select 设置选项列表:

选项列表

<select id="selectItems" datatype="int"/>

setItems() 方法可以编程式地设置选项列表。

@ViewComponent
private JmixSelect<Integer> selectItems;

@Subscribe
public void onInit(final InitEvent event) {
    selectItems.setItems(1, 2, 3, 4, 5);
}

选项映射

<select id="selectMaps" datatype="int"/>

ComponentUtils.setItemsMap() 可以显式地为选项条目设置字符串标签。

@ViewComponent
private JmixSelect<Integer> selectMaps;

@Subscribe
public void onInit(final 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(selectMaps, map);
}

选项枚举

如果使用枚举,则可以通过声明式或编程式的方法将枚举值设置为选项。

下面的示例是声明式用法。

<select itemsEnum="io.jmix.uisamples.entity.CustomerGrade"
        emptySelectionAllowed="true" emptySelectionCaption="Empty"/>

下面的示例是编程式用法。

@ViewComponent
private JmixSelect<DayOfWeek> selectEnum;

@Subscribe
public void onInit(final InitEvent event) {
    selectEnum.setItems(DayOfWeek.class);
}

禁用选项

选项可以禁用,此时用户无法选择这些选项,但是这些选项也可能在不同的条件下允许选择。

使用 itemEnabledProvider 可以根据特定条件动态配置每个选项的启用状态。禁用的选项显示为灰色,用户无法选择。所有选项默认启用。

@Install(to = "select", subject = "itemEnabledProvider")
private boolean selectItemEnabledProvider(final Department department) {
    return department == null || department.getHrManager() != null;
}

空选项

select 组件提供展示一个空选项的功能,在默认值为空或“没有选择任何选项”的场景可以用到。

emptySelectionAllowed 设置是否允许用户选择空值。当设置为 true 时,选项列表中会显示一个空白选项。

空选项可以通过 emptySelectionCaption 属性进行自定义。

<select itemsEnum="io.jmix.uisamples.entity.CustomerGrade"
        emptySelectionAllowed="true" emptySelectionCaption="Empty"/>

当 emptySelectionAllowed = true 时,使用 emptySelectionCaption 属性设置空白选项的标题。用于在选项列表中显示。

当选择空选项时,组件显示的值为 itemLabelGenerator 提供的 null 选项值,或者由 placeholder 属性设置的占位符,如果占位符也没有设置,则显示空白。

@Install(to = "sizeSelect", subject = "itemLabelGenerator")
private String sizeSelectItemLabelGenerator(final String t) {
    return t != null ? t : sizeSelect.getEmptySelectionCaption();
}

自定义选项标签

通过 itemLabelGenerator 可以自定义 radioButtonGroup 组件中选项的显示标签,即控制用户看到的文本,从而能够以更友好或特定于上下文的方式显示信息。

@Install(to = "customItemsSelect", subject = "itemLabelGenerator")
private String customItemsSelectItemLabelGenerator(final Department t) {
    return t.getHrManager() != null
            ? t.getName() + "[Manager: " + t.getHrManager().getFirstName() +
            " " + t.getHrManager().getLastName() + "]"
            : t.getName();
}

itemLabelGenerator 控制下拉列表中每个选项显示的标签,以及 select 组件输入框中已选择项的标签。

textRenderer 仅控制下拉列表中每个选项显示的标签。

@Install(to = "departmentSelect", subject = "textRenderer")
private String departmentSelectTextRenderer(final Department t) {
    return t.getName() + ", number #" + t.getNum();
}
textRenderer 不会影响 select 组件输入框中已选择项的标签。

如果仅需自定义下拉列表中的标签,可以通过该功能提高选项的辨析度、添加其他信息或根据所选对象的属性调整标签。

选项渲染

框架提供了自定义选项渲染的功能。渲染器会对每个选项生效并创建选项的外观组件。

可以使用 setRenderer() 方法或 @Supply 注解实现。

@Autowired
private UiComponents uiComponents;

@Supply(to = "selectWithRenderer", subject = "renderer") (1)
private ComponentRenderer<Button, Department> selectWithRendererRenderer() {
    return new ComponentRenderer<>(item -> { (2)
        Button button = uiComponents.create(Button.class); (3)
        button.setText(item.getName());
        button.setIcon(VaadinIcon.DESKTOP.create());
        return button; (4)
    });
}
1 @Supply 将渲染器与 selectWithRenderer 绑定。
2 lambda 使用当前的 Department 作为参数。
3 在这个回调中创建并配置组件。
4 lambda 返回需要显示的组件。

或者,可以使用内部的 fragmentRenderer 元素来渲染条目。有关详细信息,请参阅 Fragment 渲染器 部分。

Overlay

Overlay 是一个半透明或不透明的图层,用于显示选项的下拉列表。

使用 classNames 属性为组件添加自定义 CSS 类。可以使用这些类来为组件选择器中的 Overlay parts 设置样式。

<select itemsEnum="com.company.onboarding.entity.DayOfWeek"
        classNames="my-custom-overlay"/>

在 css 文件中自定义样式:

vaadin-select.my-custom-overlay::part(overlay){
    background-color: #ecfcf9;
    border-radius: 5px;
}

样式版本

使用 themeNames 属性配置一个或多个样式。

样式 描述 支持的主题

align-left

字段值左对齐。

Aura, Lumo

align-center

字段值居中对齐。

Aura, Lumo

align-right

字段值右对齐。

Aura, Lumo

align-start

根据当前文本方向,将字段值向起始侧对齐。

Aura

align-end

根据当前文本方向,将字段值向末尾侧对齐。

Aura

helper-above-field

帮助文字显示在字段上方,标题下方。

Aura, Lumo

small

组件更小。

Aura, Lumo

XML 属性

下面是 select 的特殊属性:

名称 描述 默认值

emptySelectionAllowed

设置用户是否可以不选择。参阅 空白选项。

false

emptySelectionCaption

当 emptySelectionAllowed = true 时,设置空白选项的标签。参阅 空白选项。

空字符串 ""

itemsContainer

定义包含选项列表的数据容器。组件显示实体的实例名称。参阅 数据绑定。

—

itemsEnum

定义用于创建选项列表的枚举类。参阅 选项枚举。

—

noVerticalOverlap

当为 false 时,覆盖层显示在输入框上方。当为 true 时,覆盖层不会覆盖输入框。参阅 Vaadin 文档。

false

overlayWidth

指定覆盖层的宽度。如果省略(默认值),覆盖层会自动调整其宽度以匹配最宽的选项,或者至少与输入框的宽度相同。参阅 Vaadin 文档。

—

下面是 select 支持的其他通用属性:

事件和处理器

下面是 select 的特殊事件和处理器:

名称 描述

InvalidChangeEvent

com.vaadin.flow.component.select.Select.InvalidChangeEvent 当组件的 invalid 状态变化时发送。

OpenedChangeEvent

com.vaadin.flow.component.select.Select.OpenedChangeEvent 当组件的选项弹窗 opened 状态变化时发送。

itemEnabledProvider

itemEnabledProvider 作用于每个选项,用于判断该选项是否启用(true)或禁用(false)。参阅 禁用选项。

itemLabelGenerator

自定义每个选项的显示标签。参阅 自定义选项标签。

renderer

设置选项的渲染器。参阅 选项渲染。

textRenderer

设置选项的文本渲染器。参阅 自定义选项标签.

validator

验证组件值。

下面是 select 支持的其他通用事件:

XML 内部元素

一个 select 可以包含 fragmentRenderer、prefix 和 tooltip 作为其内部元素。

参考