0

I'm using vaadin 14 for my application. My MainView class extends Applayout class. This allows me to use addToNavBar(true, some Components) function which adds navigation bar to your application.

Now, In my main view, inside the navigation bar, I have register and login buttons populated. If click on these buttons, using addonclick listener I delegate to other views like Login and Registration. During these view changes, the navbar on top still stays there. However, if the user logged in or registered, I want to remove these login and register buttons in navigation bar and replace them with profile picture icon located inside the navbar. However, from child views(register,login) I couldn't find a way to access to navbar with vaadin 14. Accordingly, how can I access and change the content of the navbar from child views?

public class MainView extends AppLayout {
private static final long serialVersionUID = 1L;
private final Tabs menu;
private HorizontalLayout headerLayout;

public MainView() {
    setPrimarySection(Section.NAVBAR);
    headerLayout = createHeaderContent();
    addToNavbar(true, headerLayout);
    setDrawerOpened(false);
    menu = createMenu();
    addToDrawer(createDrawerContent(menu));
}

private HorizontalLayout createHeaderContent() {
    headerLayout = new HorizontalLayout();
    headerLayout.setId("header");
    headerLayout.getThemeList().set("dark", true);
    headerLayout.setWidthFull();
    headerLayout.setSpacing(false);
    headerLayout.setAlignItems(FlexComponent.Alignment.CENTER);
    headerLayout.add(new DrawerToggle());
    headerLayout.add(createWebsiteName());
    headerLayout.add(createMiddleSpacingInHeader());
    headerLayout.add(createLoginAndRegisterButtons());

    return headerLayout;
}

private Component createLoginAndRegisterButtons() {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setPadding(true);
        layout.setSpacing(true);
        layout.setAlignItems(Alignment.STRETCH);

        Button register = createRegisterButton();
        Button login = createLoginButton();
        Image loggedInUserPicture = createLoggedInUserImage();

        layout.add(register, login, loggedInUserPicture);

        return layout;
    }
Ahmet Eroğlu
  • 594
  • 1
  • 7
  • 23

1 Answers1

1

There is currently no good API for this. One reason is that framework needs to be agnostic to how you build your menu. I have solved this by creating small interface of this kind

public interface HasTabsAccessor {
    
    public default Tabs getTabs(Component component) {
        Optional<Component> parent = component.getParent();
        Tabs menu = null;
        while (parent.isPresent()) { 
            Component p = parent.get();
            if (p instanceof MainLayout) {
                MainLayout main = (MainLayout) p;
                menu = main.getMenu();
            }           
            parent = p.getParent();
        }
        return menu;
    }
}

Which I can then add to views where I need to access the menu.

    @Route(value = FormLayoutView.ROUTE, layout = MainLayout.class)
    @PageTitle(FormLayoutView.TITLE)
    public class FormLayoutView extends VerticalLayout implements BeforeLeaveObserver, HasTabsAccessor {
...

And then just using getTabs() in the view.

Tatu Lund
  • 9,949
  • 1
  • 12
  • 26
  • Hey Tatu, thank you very much for your extremely helpful solution, I want to try it out, but in your interface you use main = main.getMenu() , in vaadin 14, I think that here you try to access to tabs on the left navigator bar. But I'm trying to read to upper navigation bar. And this instance i cant access to because of the fact that I add it just by calling addToNavBar method from mainview class which extends applayout – Ahmet Eroğlu Aug 31 '20 at 13:33
  • Yes, you need to adapt the solution to your application. As I pointed out framework gives big freedom how to build your bottom layout, i.e. the menu can be on the left on the top. It can be based on tabs or layouts or what ever. So take this solution as generic idea how to traverse to MainLayout and access some API there, which you naturally have to add to your MainLayout. – Tatu Lund Aug 31 '20 at 13:48
  • I understood, already figured it out by now ! :) Thanks alot ! :) – Ahmet Eroğlu Aug 31 '20 at 14:04