vaadin - 有没有办法让组合框像 Vaadin Flow 中的 Select 一样呈现选定的值?
问题描述
例如,在Select
组件中,所选值的呈现方式如下所示。但是,当涉及到ComboBox
它时,它不会呈现,仅在下拉菜单中显示,如下所示。我需要使用,ComboBox
因为我需要搜索功能,即在输入值时选择项目,因为可能有很多值。Select
理想情况下,合并and会很棒,ComboBox
但除非我想知道是否有办法呈现所选值。
解决方案
您不能使用任意渲染器,因为文本输入是文本输入。正如问题下方的评论中所指出的,您真正想要的是输入值前面的图标,虽然 ComboBox 中没有很好的 API 用于此目的,但您可以使用vaadin-text-field
输入。我已经使用此处的食谱食谱改编了一个示例。请注意,有一个增强请求可以更轻松地处理 ComboBox 中的前缀/后缀组件:https ://github.com/vaadin/flow-components/issues/1594
public class AboutView extends Div {
public AboutView() {
ComboBox<Person> comboBox = new ComboBox<>();
comboBox.setItems(getPersons());
// Renderer for the drop down
comboBox.setRenderer(new ComponentRenderer<Div, Person>(person -> {
Div container = new Div();
container.add(person.getIcon().create(), new Span(person.getName()));
return container;
}));
// on value change: either clear the prefix slot or create a new Icon there
comboBox.addValueChangeListener(e -> {
Person p = e.getValue();
if (p == null) {
PrefixUtil.clearSlot(comboBox, "prefix");
return;
}
PrefixUtil.setPrefixComponent(comboBox, p.getIcon().create());
});
comboBox.setItemLabelGenerator(Person::getName);
add(comboBox);
}
public List<Person> getPersons() {
List<Person> persons = new ArrayList<>();
Person person1 = new Person("Foo", VaadinIcon.ARROW_BACKWARD);
Person person2 = new Person("Bar", VaadinIcon.BAR_CHART);
Person person3 = new Person("Baz", VaadinIcon.PUZZLE_PIECE);
persons.add(person1);
persons.add(person2);
persons.add(person3);
return persons;
}
public static class Person {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
public VaadinIcon getIcon() {
return icon;
}
public void setIcon(VaadinIcon icon) {
this.icon = icon;
}
private VaadinIcon icon;
public Person(String name, VaadinIcon icon) {
this.name = name;
this.icon = icon;
}
}
public static class PrefixUtil {
private static Stream<Element> getElementsInSlot(HasElement target,
String slot) {
return target.getElement().getChildren()
.filter(child -> slot.equals(child.getAttribute("slot")));
}
public static void setPrefixComponent(Component target, Component component) {
clearSlot(target, "prefix");
if (component != null) {
component.getElement().setAttribute("slot", "prefix");
target.getElement().appendChild(component.getElement());
}
}
private static void clearSlot(Component target, String slot) {
getElementsInSlot(target, slot).collect(Collectors.toList())
.forEach(target.getElement()::removeChild);
}
private static Component getChildInSlot(HasElement target, String slot) {
Optional<Element> element = getElementsInSlot(target, slot).findFirst();
if (element.isPresent()) {
return element.get().getComponent().get();
}
return null;
}
public static Component getPrefixComponent(Component target) {
return getChildInSlot(target, "prefix");
}
}
}
推荐阅读
- javascript - 如何在不同设备的动画文本之间切换?html/css
- sql-server-2008-r2 - SQL Server 2008 R2中如何排除每个月的第三个星期三
- html - 在 renderUI 中生成的 selectizeInput 和 numericInputs 的对齐方式
- flutter - 我对 bloc 模式和更改通知程序有疑问
- python - “或”没有按预期工作,而是按位或“|” 效果很好
- azure-front-door - 如何使用 Azure 前门规则引擎匹配条件仅将请求匹配到站点的根目录?
- javascript - 如何为我的项目实现这个加载器?
- sql-server - Azure Purview 看到 On-Prem SQL Server 数据库和表,但无法扫描并显示消息:提供了无效的客户端密码
- ruby-on-rails - 部署 heroku 应用程序时在任何源中都找不到 nokogiri-1.11.1
- javascript - 角数学贾克斯