I have a left navigation area composed of several SideNav components. When one is expanded I want to automatically close all other expanded SideNav menus.
I can’t find a way to do this. there is no click/expand listener on the SideNav component.
You can listen with Element#addPropertyChangeListener to changes of a property. In this case expanded.
This worked for me with client sided click and a server sided SideNavItem#setExpanded.
I created the addItem method to not have duplicated code.
private SideNav sideNav = new SideNav("Side Nav");
/* flow skeleton starter */
public MainView() {
addClassName("centered-content");
// create items
SideNavItem messagesLink = new SideNavItem("Messages", MainView.class, VaadinIcon.ENVELOPE.create());
messagesLink.addItem(new SideNavItem("Inbox", MainView.class, VaadinIcon.INBOX.create()));
messagesLink.addItem(new SideNavItem("Sent", MainView.class, VaadinIcon.PAPERPLANE.create()));
messagesLink.addItem(new SideNavItem("Trash", MainView.class, VaadinIcon.TRASH.create()));
SideNavItem adminSection = new SideNavItem("Admin");
adminSection.setPrefixComponent(VaadinIcon.COG.create());
adminSection.addItem(new SideNavItem("Users", MainView.class, VaadinIcon.GROUP.create()));
adminSection.addItem(new SideNavItem("Permissions", MainView.class, VaadinIcon.KEY.create()));
SideNavItem testSection = new SideNavItem("Test");
testSection.setPrefixComponent(VaadinIcon.COG.create());
testSection.addItem(new SideNavItem("Test", MainView.class, VaadinIcon.GROUP.create()));
testSection.addItem(new SideNavItem("Test", MainView.class, VaadinIcon.KEY.create()));
addItem(messagesLink, adminSection, testSection);
add(sideNav);
add(new Button("Expand last item", e -> testSection.setExpanded(true)));
}
/**
* add to nav bar and add listener
*/
private void addItem(SideNavItem... items) {
for (SideNavItem item : items) {
// listen to expanded changed on client
item.getElement().addPropertyChangeListener("expanded", this::collapseItems);
sideNav.addItem(item);
}
}
/**
* handle change
*/
private void collapseItems(PropertyChangeEvent event) {
final Element currentlyChangedItem = event.getSource();
Object newPropValue = event.getValue();
// collapse only if opened
if (Boolean.TRUE.equals(newPropValue)) {
sideNav.getChildren().filter(item -> {
// do not collapse item that triggered event
return !item.getElement().equals(currentlyChangedItem) && item instanceof SideNavItem;
}).forEach(item -> ((SideNavItem) item).setExpanded(false));
;
}
}