i want to toggle highlighting for the routerLinkActive based on the routes,
i have a dashboard component and both the dashboard menu item and labels menu item refer to the same component, i want to add class to the li items based on the route
for dashboard the route will be
http://localhost:4300/dashboard
and for the labels , the route will be
http://localhost:4300/dashboard/5d1bb53877ed8702d8a01940
Code for the menu item
<ul class="sidebar-nav">
<li [ngClass]="{ active: rlal && rlal.isActive == false }">
<a [routerLink]="['/dashboard']" (click)="loadSnippet(null)">
<mat-icon>dashboard</mat-icon>
<span>Dashboard</span>
</a>
</li>
<h3 *ngIf="labelList && labelList.length!=0">Labels</h3>
<ul class="sidebar-nav">
<li *ngFor="let label of labelList" [ngClass]="rlal && rlal.isActive ? 'active' : ''"
routerLinkActive="rlal.isActive">
<a [routerLink]="['/dashboard', label._id]" routerLinkActive #rlal="routerLinkActive"
(click)="loadSnippet(label)">
<mat-icon>label</mat-icon>
<span>{{ label.label_name }} </span>
</a>
</li>
</ul>
Routes:
{
path: "dashboard",
component: DashboardComponent,
canActivate: [LoggedInGuard]
},
{
path: "dashboard/:labelId",
component: DashboardComponent,
canActivate: [LoggedInGuard]
}
The highlighting works fine for the individual label items, but for the dashboard , the li is not getting highlighted
If you want the dashboard link to be active only if there's no route parameter, you need to add routerLinkActive and [routerLinkActiveOptions]="{exact: true}" to you dashboard li node.
Also, you don't need to set the active class via ngClass, because routerLinkActive will do that for you.
<li routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
<a routerLink="/dashboard" (click)="loadSnippet(null)">
<mat-icon>dashboard</mat-icon>
<span>Dashboard</span>
</a>
</li>
...
<li routerLinkActive="active" *ngFor="let label of labelList">
<a [routerLink]="['/dashboard', label._id]" (click)="loadSnippet(label)">
<mat-icon>label</mat-icon>
<span>{{ label.label_name }}</span>
</a>
</li>
Related
I have link something like this:
<li class="list-item active"> <router-link :to="{name:'link-1'}"> Link 1</router-link>
<li class="list-item"> <router-link :to="{name:'link-2'}"> Link 2</router-link>
I want to add class active with list-item class based on the url suppose if the url is localhost:8000/link-1 then link-1 should be active.
If you are using Vue Router > 3.1.0 you can use <router-link> and a scoped slot for this:
<router-link
:to="{name:'link-1'}"
v-slot="{ href, route, navigate, isActive, isExactActive }"
>
<li
:class="[isActive && 'active', isExactActive && 'exact-active']"
>
<a :href="href" #click="navigate">Link 1</a>
</li>
</router-link>
<router-link
:to="{name:'link-2'}"
v-slot="{ href, route, navigate, isActive, isExactActive }"
>
<li
:class="[isActive && 'active', isExactActive && 'exact-active']"
>
<a :href="href" #click="navigate">Link 2</a>
</li>
</router-link>
If you don't need to have .active on the li elements, <router-link> has this build in. (See Dan's awnswer)
Vue router provides this functionality. When a link is active, it will have the router-link-exact-active class applied.
In your CSS:
.router-link-exact-active {
// styles here
}
There is also router-link-active which would match both "/" and "/link-1".
I have a multi level dropdown menu working for Aurelia with bootstrap however whilst its three levels deep and uses as a basis THIS gist expanding on it I am having trouble adding a divider via the route settings.
Now a divider uses the class "divider" in the list tag <li></li> Ok so I thought by adding the entry divider: true in the settings for the dropdown I could check for that and instead if displaying the link etc I could instead show a divider however I dont know how to implement this into the navmenu.html file. Here is the file:
<ul class="nav navbar-nav">
<li repeat.for="route of router.navigation" class="${route.isActive ? 'active' : ''}">
<a href.bind="route.href" if.bind="!route.settings.nav"><span class="glyphicon glyphicon-${ route.settings.icon }"></span> ${route.title}</a>
<a href.bind="route.href" if.bind="route.settings.nav" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-${ route.settings.icon }"></span> ${route.title} <span class="caret"></span> <!--First level menu heading - requires route.settings.nav to exist-->
</a>
<ul if.bind="route.settings.nav" class="dropdown-menu">
<li repeat.for="menu of route.settings.nav" class="dropdown-submenu">
<a href.bind="menu.href" if.bind="!menu.navSettings.subNav"><span class="glyphicon glyphicon-${ menu.navSettings.icon }"></span> ${menu.title}</a>
<a href.bind="menu.href" if.bind="menu.navSettings.subNav" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-${ menu.navSettings.icon }"></span> ${menu.title} <span class="caret-right"></span>
</a>
<ul if.bind="menu.navSettings.subNav" class="dropdown-menu">
<li repeat.for="subMenu of menu.navSettings.subNav" class="dropdown-submenu">
<a href.bind="subMenu.href" if.bind="!subMenu.subNavSettings.subSubNav"><span class="glyphicon glyphicon-${ subMenu.subNavSettings.icon }"></span> ${subMenu.title}</a>
<a href.bind="subMenu.href" if.bind="subMenu.subNavSettings.subSubNav" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-${ subMenu.subNavSettings.icon }"></span> ${subMenu.title} <span class="caret-right"></span>
</a>
<ul if.bind="subMenu.subNavSettings.subSubNav" class="dropdown-menu">
<li repeat.for="lowestSubMenu of subMenu.subNavSettings.subSubNav" class="dropdown-submenu">
<a href.bind="lowestSubMenu.href"> <span class="glyphicon glyphicon-${ lowestSubMenu.subSubNavSettings.icon }"></span> ${lowestSubMenu.title}</a>
</li>
</ul>
</li>
</ul>
</li> [ALL THE ANCHORS HERE OR A DIVIDER.. HOW DO I DO A TERNARY TO CHECK ON EACH REPEAT FOR A DIVIDER VALUE IN THE SETTINGS ARRAY.
</ul>
</li>
</ul>
Here is an exert from the route map that the navmenu reads from:
{
route: "clients",
name: "clients",
moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"),
title: "Clients",
nav: true,
settings: {
nav: [
{
href: "#clients/clientsList",
title: "Client List",
navSettings: {
icon: "list",
roles: ["Employee", "Admin"],
}
},
{
navSettings: {
roles: ["Employee", "Admin"],
divider: true, // HERE IS MY DIVIDER
}
},
{
href: "#clients/Create",
title: "Create Client",
navSettings: {
icon: "user",
roles: ["Employee", "Admin"],
}
}
],
icon: "user",
auth: true,
roles: ["Employee", "Admin"],
pos: "left"
}
},
The problem is that the <li></li> does a repeat and I need to check in that repeat - li to see if "navSettings has an entry divider: true and if so not show the link (menu item) but instead show a line divider.
How do I discard the anchors and instead show a list line with class "divider". Whats throwing me is the fact that the li has a repeat.for and I need to either show everything between the <li></li>tags or instead show a divider.
I need to check on the line:
<li repeat.for="menu of route.settings.nav" class="dropdown-submenu">
and change the class from "dropdown-submenu" to "divider" while at the same time not show any of the anchors <a></a> by doing similar check (if.bind I am guessing) for divider..
Hope you can help..
In the <li> use class="${menu.divider ? 'divider' : 'dropdown-submenu'}".
Use if.bind on menu.divider for the elements inside the <li>.
<li repeat.for="menu of route.settings.nav" class="${menu.divider ? 'divider' : 'dropdown-submenu'}">
<a if.bind="!menu.divider" href.bind="lowestSubMenu.href"> <span class="glyphicon glyphicon-${ lowestSubMenu.subSubNavSettings.icon }"></span> ${lowestSubMenu.title}</a>
<div if.bind="menu.divider" class="divider"></div>
</li>
How can I make ONE link in the FOR-Loop active?
<ul>
<li v-for="channel in $store.state.forum.channels" v-bind:key="channel.key">
<a v-bind:class="{ active: toggle }" v-on:click="selectChannel({ key: channel.key })">{{ channel.title }}</a>
</li>
</ul>
Or:
How can I access an iteration in the for loop from outside the loop?
I have the following state using angular-ui-router module and I am currently at the url http://localhost:3000/#/bar/87023/ where 87023 is the value of a.
.state('foo', {
url: '/bar/:a/:b',
views: {
'': {
templateUrl: 'partials/zoo.tpl.html',
controller: 'XCtrl'
},
'purr#foo': {
templateUrl: 'partials/zing.html',
controller: 'YCtrl'
}
}
})
On the zing.html page I have 4 tabs as following:
<ul class="nav nav-tabs">
<li>
<a href="#tab_1_1" data-toggle="tab">
Zoo Details </a>
</li>
<li>
<a href="#tab_1_2" data-toggle="tab">
Pricing </a>
</li>
<li class="dropdown">
<a href="#tab_1_3" data-toggle="tab">
Reviews </a>
</li>
<li>
<a href="#tab_1_4" data-toggle="tab">
Something interesting </a>
</li>
</ul>
<div class="tab-content">
<div id="tab_1_1">
//tab_1_1 content
</div>
<div id="tab_1_2">
//tab_1_2 content
</div>
<div id="tab_1_3" >
//tab_1_3 content
</div>
<div id="tab_1_4" >
//tab_1_4 content
</div>
</div>
When I click on tab_1_1 or any of the tabs, I am taken to the http://localhost:3000/#/ page. Could somebody help me understand why am I having this issue and how to resolve this? I want to be on the same page (http://localhost:3000/#/bar/87023/) and be able to see the content of the tabs.
You are redirecting to index because href attribute changes the hash of browser, which is listened by angularJS's ngRoute.
Use data-target attribute instead of href
Here's a example on jsFiddle
Template:
<template name="header">
<div class="blog-masthead">
<div class="container">
<nav class="blog-nav">
<a class="blog-nav-item {{active}}" href="{{pathFor 'homePage'}}">Home</a>
{{#if currentUser}}
<a class="blog-nav-item {{active}}" href="#">{{Meteor.userId}}</a>
{{else}}
<a class="blog-nav-item {{active}}" href="{{pathFor 'loginPage'}}">Login</a>
<a class="blog-nav-item {{active}}" href="{{pathFor 'signUpPage'}}">Sign Up</a>
{{/if}}
<a class="blog-nav-item {{active}}" href="#">About</a>
</nav>
</div>
</div>
</template>
header.js
Template.header.events({
'click a': function(e) {
e.preventDefault();
this.active?"active":"";
}
});
I just want to make set click link's class as active. Clicked link class should look like class="blog-nav-item active".
The example below relies on iron-router and presents a reactive approach for adding the active class
First should modify the template to be:
<a class="blog-nav-item {{active 'homePage'}}" href="{{pathFor 'homePage'}}">Home</a>
And then the appropriate helper for it should be:
Template.name.helpers({
active: function(routeName) {
var curRoute = Router.current().route;
return curRoute.name === routeName ? 'active' : '';
}
});
Edit v1.0+
As of iron-router 1.0, A route's name is now accessible at
route.getName() (previously it was route.name).
In particular, you'll need to write return
curRoute.getName() === routeName ? 'active' : '';
Thank you #jrbedard for the notification
I guess this would be the "Meteor way" you wanted:
<template name="menu">
<ul>
<li class="{{#if isCurrentPage 'pageA'}}active{{/if}}">
Page A
</li>
<li class="{{#if isCurrentPage 'pageB'}}active{{/if}}">
Page B
</li>
<li class="{{#if isCurrentPage 'pageC'}}active{{/if}}">
Page C
</li>
</ul>
</template>
Router.onBeforeAction(function(){
Session.set('currentRouteName', Router.current().route.name)
})
Template.menu.helpers({
isCurrentPage: function(pageName){
return Session.equals('currentRouteName', pageName)
}
})
Router.current().route.name do evaluate to the current page name in the latest version of iron router, but I don't know if that's part of the public API one should use.
EDIT
Router.current() is apparently reactive, so all JavaScript code you need is the following:
Template.menu.helpers({
isCurrentPage: function(pageName){
return Router.current().route.name == pageName
}
})
You can solve it with JavaScript only:
Template.header.events({
'click .blog-nav-item': function(event, template){
// Remove the class 'active' from potentially current active link.
var activeLink = template.find('.blog-nav-item')
if(activeLink){
activeLink.classList.remove('active')
}
// Add the class 'active' to the clicked link.
event.currentTarget.classList.add('active')
}
})