I’m using Vaadin Tabs and need each tab to have a separate URL, so the user can bookmark the page with the currently selected tab. Is this possible?
I’ve played around with HasUrlParameter and it’s possible to select a specific tab based on the parameter, but of course the URL isn’t changing when changing the tab. Can i change the URL manually? Or is there another approach?
You probably should place your Tabs in a class which implements the “RouterLayout”. After that, make sure that when clicking a Tab, a navigation occures to a class which is annotation like : “@Route(value = “YourRouteValue”, layout = “YourRouterLayout”.class)”
I am actually trying to do this right now, so I think I know exactly what Magnus means.
let’s assume we have following classes:
a MainView (RouterLayout) which contains a tabs with two tab items
two Views, one for each tab item. lets call them ViewA and ViewB
Now when opening ViewB (directly via URL, not via tab item click), the tabs from the MainView is displayed, but the tab-item for ViewA is selected because it’s the first tab item. So the second tab item needs to be selected programmatically in this case.
He is doing this by implementing BeforeEnterObserver in the MainView, reading the url and selecting the corresponding tab item.
In my opinion, it would be so much better if this whole logic can be started in the actual child view. But the child view ViewB has no way of knowing the MainView, does it? (please do correct me here if I’m wrong!)
I was trying out (MainView) this.getParent().get() within the ViewB but it doesn’t seem to work.
So to answer Magnus’ question from my point of view: If your approach works, then this is already not so bad. There could be a better way of doing this but I have yet to find it.
Its more about the other way round. When you type in specific URL (like you did at second 35 of your video), how does your tabs element know which tab item to select?
Yes, I do something similar. I have multiple tabs sharing the same class view, so I have a map of Tabs and the related data for the view.
In the beforeEnter event, I check the parameters in the url and add the tab to the Tabs component. If the tab already exists (i.e. its in the map) then its just setSelected.
Yes, exactly. That was my problem.
My approach is working, but feels a bit complicated. But as it is just some weird private code, i can live with it
Kaspar Scherrer:
I am actually trying to do this right now, so I think I know exactly what Magnus means.
let’s assume we have following classes:
a MainView (RouterLayout) which contains a tabs with two tab items
two Views, one for each tab item. lets call them ViewA and ViewB
Now when opening ViewB (directly via URL, not via tab item click), the tabs from the MainView is displayed, but the tab-item for ViewA is selected because it’s the first tab item. So the second tab item needs to be selected programmatically in this case.
He is doing this by implementing BeforeEnterObserver in the MainView, reading the url and selecting the corresponding tab item.
In my opinion, it would be so much better if this whole logic can be started in the actual child view. But the child view ViewB has no way of knowing the MainView, does it? (please do correct me here if I’m wrong!)
I was trying out (MainView) this.getParent().get() within the ViewB but it doesn’t seem to work.
So to answer Magnus’ question from my point of view: If your approach works, then this is already not so bad. There could be a better way of doing this but I have yet to find it.
I guess, if you’re using Spring, you could define a bean with Request scope that can hold your MainView instance for the current request. In the constructor of MainView, it could pass ‘this’ to this bean. Then in the constructors of ViewA and ViewB you inject this bean and can access the MainView. At least if that was constructed first, I’m not sure that’s necessarily the case. If not, it can be accessed in afterNavigation if the views implement AfterNavigationObserver.
Actually, since the MainLayout knows the classes of the views (in order to navigate on tab selection) it can implement AfterNavigationObserver and look at the first element of the active chain after navigation. It should be an instance of one of those classes corresponding to the selected tab. You can use a subclass of Tab which holds a reference to this class object, for easy lookup.