Bootstrap 4 navmenu issue with active

Hi there, I asked this question just before which I believe went some of the way to sorting my issues. Use a valueconverter to change the css class for the active menu option.

It works however it only works when the whole page is rendered. If I change the route the menu does nothing. It does not re-render. OK I can work with that. What about changing the class with eventaggregator? I added the event aggregator to the navmenu.ts as follows:

	attached() {

	this.eventAggregator.subscribe("router:navigation:complete", response => {
		console.log("Router fired and completed: ", this.router.currentInstruction.fragment);
	});
}

this gets me the route fragment.

Its at this point I am unsure what to do or… if there is actually a better way to do this. I now want to add a class of “active” to the appropriate menu item…

How can I find the actual ref item in the view in order to match the router fragment and thus add css of active…?

Or is there an easier way… seems others used jquery but I dont want to do that and the valueconverter only works once…

1 Like

I have solved this finally. Its most likely not the best way but it does work. Essentially I trigger off the router using the eventaggregator by subscribing to the the router complete event.

	attached() {
	this.eventAggregator.subscribe("router:navigation:complete", response => {
		this.topUrl = "#/" + this.router.currentInstruction.fragment.split('/')[1]
	});
}

I have also split this to the first folder or, essentially the first menu level. I added “#/” to the front of it it and now it equals the route.href value if its from the same dropdown tree. I then just check if the two values are equal and if they are I add the “active” class.

				<li repeat.for="route of router.navigation">
				<a href.bind="route.href" if.bind="!route.settings.nav" class=" ${route.href == topUrl ? 'active' : ''}">
					${route.title}
				</a>
				<a href.bind="route.href" if.bind="route.settings.nav" class="dropdown-toggle ${route.href == topUrl ? 'active' : ''}" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					${route.title}
				</a>

So if I select a menu item from three levels down it still reverts back to the top level and if they are equal sets the active class. I would have used the valueconverter however I discovered that once the page rendered the menu did not change so I had to revert to the aggregator to add the active class…

Sure there are better ways but this is what I came up with…

1 Like

Wouldn’t the approach like what has been described here be useful?

1 Like

BTW navigations in the router have a property called isActive, that could be of some help. It will be something like this line. When you have parent/child routes and a child route isActive property is true then the parent route has also isActive set to true

1 Like