Vaadin 14 如何在MenuBar组件中添加可填写的表单功能
该需求可正常实现,菜单自动关闭是Vaadin MenuBar的默认交互逻辑,只需调整配置即可解决。
问题原因
Vaadin MenuBar子菜单默认响应内部所有点击、焦点事件,触发自动关闭逻辑,避免菜单长期悬浮遮挡页面内容,你场景中TextField获得焦点时正好触发了该逻辑。
具体操作步骤
- 步骤1:关闭表单项的默认点击关闭属性
你将FormLayout添加到子菜单时会生成对应的MenuItem实例,将该实例的setCloseOnClick属性设为false即可避免点击表单区域触发菜单关闭:// 替换原有 contacts.getSubMenu().addItem(nameLayout); MenuItem contactFormItem = contacts.getSubMenu().addItem(nameLayout); contactFormItem.setCloseOnClick(false); - 步骤2:兼容低版本/焦点触发关闭场景
如果你使用Vaadin 23以下版本没有setCloseOnClick方法,或配置后仍存在焦点触发关闭的问题,给表单内可交互元素添加事件冒泡阻止逻辑即可:// 阻止输入框的点击、焦点事件冒泡到菜单 phoneField.getElement().addEventListener("click", e -> e.stopPropagation()); phoneField.getElement().addEventListener("focus", e -> e.stopPropagation()); // 阻止提交按钮的点击事件冒泡 sendButton.getElement().addEventListener("click", e -> e.stopPropagation()); - 步骤3:可选:提交后手动控制菜单状态
若需要用户点击提交后自动关闭菜单,可在业务逻辑执行完成后手动调用关闭方法:sendButton.addClickListener(e -> { String phoneNum = phoneField.getValue(); // 此处执行申请回呼的业务逻辑 // ... // 提交完成后手动关闭菜单 contacts.getSubMenu().close(); // 可选:清空输入框 phoneField.clear(); });
修改后完整代码示例
public class HeaderView extends MenuBar implements RouterLayout { private final MenuItem tools; private final MenuItem contacts; public HeaderView() { // logo final Image img = new Image("img/logo.png", "image"); img.setHeight("44px"); this.addItem(img); // TOOLS tools = this.addItem("Tools"); tools.addComponentAsFirst(new Icon(VaadinIcon.TOOLS)); // CONTACTS contacts = this.addItem("Contacts"); contacts.addComponentAsFirst(new Icon(VaadinIcon.PHONE)); // layout for the form contact final FormLayout nameLayout = new FormLayout(); final TextField phoneField = new TextField(); phoneField.setLabel("Phone"); phoneField.setPlaceholder("Phone"); final Button sendButton = new Button("send"); // 阻止事件冒泡逻辑 phoneField.getElement().addEventListener("click", e -> e.stopPropagation()); phoneField.getElement().addEventListener("focus", e -> e.stopPropagation()); sendButton.getElement().addEventListener("click", e -> e.stopPropagation()); // 提交逻辑 sendButton.addClickListener(e -> { String phoneNum = phoneField.getValue(); // 处理申请回呼业务逻辑 contacts.getSubMenu().close(); phoneField.clear(); }); // add textfield and button to the layout nameLayout.add(phoneField, sendButton); // add the form to the menubar MenuItem contactFormItem = contacts.getSubMenu().addItem(nameLayout); contactFormItem.setCloseOnClick(false); } }
内容的提问来源于stack exchange,提问作者jeje
相关产品推荐
相关产品推荐

