Search code examples
javavaadin-flowvaadin24

Vaadin : preventing MenuBar from closing when MenuBarRootItem is clicked


I am using vaadin 24. I have a MenuBar and I would like to modify the default behavior of MenuBar so that it doesn't close when I click on the items (to be able to click them several times). Do someone know how to achieve this please ?

Here's my code :

MenuBar menu = new MenuBar();
menu.addItem(VaadinIcon.PLUS.create(), event -> increase());
menu.addItem(VaadinIcon.MINUS.create(), event -> decrease());

Solution

  • It's a known omission. Here's a workaround from the ticket:

    /*
     * Do not close the overlay ({@link SubMenu} containing this menu item when clicked.
     */
    public class RetainOpenedMenuItemDecorator {
        public static final String CHECKED_ATTR = "menu-item-checked";
        private final MenuItem menuItem;
    
        public RetainOpenedMenuItemDecorator(MenuItem menuItem) {
            this.menuItem = menuItem;
            menuItem.getElement().addEventListener("click", e -> {
                if (!menuItem.isCheckable()) {
                    return;
                }
                // needed because UI change is also prevented
                if (menuItem.isChecked()) {
                    menuItem.getElement().executeJs("this.setAttribute('"+ CHECKED_ATTR + "', '')");
                } else {
                    menuItem.getElement().executeJs("this.removeAttribute('"+ CHECKED_ATTR + "')");
                }
            }).addEventData("event.preventDefault()");
        }
    
        public MenuItem getMenuItem() {
            return menuItem;
        }
    
        public static void keepOpenOnClick(MenuItem menuItem) {
            new RetainOpenedMenuItemDecorator(menuItem);
        }
    
        public static void keepOpenOnClick(SubMenu subMenu) {
            subMenu.getItems().forEach(RetainOpenedMenuItemDecorator::keepOpenOnClick);
        }
    }