Reputation: 40032
I have a layout Jade view that has a menu via unordered list, and I want to set the <li>
to be <li class="active">...</li>
when the current page is rendered in the browser.
I assume I will have to access the current request to determine when to set the attribute on the <li>
I can't find any examples of how to do this so hoping someone can help
Thanks
Upvotes: 19
Views: 21807
Reputation: 1756
you can use global variables in app.js like :
// Global vars
app.use( function ( req, res, next ) {
// rest of your code ...
res.locals.current_url = req.path;
// rest of your code ...
next();
} );
// then in your .jade file:
ul.navbar-nav.mr-auto
li(class="nav-item #{ current_url === '/page1' ? 'active' : ''}")
a.nav-link(href='/page1') Page1
like this you are able to use "current_url" globally all around your view files
Upvotes: 2
Reputation: 99
Pass the req.originalUrl in your routes file. example: in your /routes/about.js
router.get('/', function(req, res) {
res.render('about', {
url: req.originalUrl
});
});
Then, write if else condition on your jade template
if(url==='/about-us')
li(class='active')
a(href='about-us') About Us
else
li
a(href='about-us') About Us
Upvotes: 2
Reputation: 20378
Here's a much neater way of doing it, server-side:
In your routes.js
(or wherever) define an array of objects representing your nav like such:
var navLinks = [
{ label: 'Home', key: 'home', path: '' },
{ label: 'About', key: 'about', path: '/about' },
{ label: 'Contact', key: 'contact', path: '/contact' }
]
Pass the navLinks
variable to your view, as well as the key of the item you'd like hilighted:
res.render('home', { title: 'Welcome!', section: 'home', navLinks: navLinks });
You can also add the navLinks
variable to app.locals
and save yourself always having to provide it explicitly to views.
Then in your jade template loop through the array of links and set the active class on the one whose key matches the provided section:
ul(class='nav nav-list')
- navLinks.forEach(function(link){
- var isActive = (link.key == section ? 'active' : '')
li(class=isActive)
a(href=link.path)= link.label
- })
Upvotes: 8
Reputation: 75656
Try this before your call res.render() in your route:
res.locals.path = req.path;
res.render('/page');
or
res.render('/page', { path: req.path });
Then you would have to do a bunch of if/else statements in your view (as the above solution suggests).
- if(currentUrl === '/')
li(class='active')
a(href='/') Current Driver Standings
- else
li
a(href='/') Current Driver Standings
I however, prefer to do this on client side instead, to keep my template files free from as much logic as possible:
In page template file (this is ejs, not sure how to echo in jade):
<body data-path="<%= path %>">
Then with jQuery you can grab the path from body and attach an active class:
$(function(){
var path = $('body').attr('data-path');
$('nav li a[href='+path+']').parents('li').addClass('active');
});
Update: You can also just use var path = window.location.pathname
instead of saving it to an attribute on body
//no need to save path to <body> tag first:
$(function(){
var path = window.location.pathname;
$('nav li a[href='+path+']').parents('li').addClass('active');
});
Upvotes: 38
Reputation: 40032
I came up with this which works however I'm not sure if its best practice. Please let me know either way:
response.render("current/currentSchedule", {
title: "Current Race Schedule",
currentUrl: req.path,
});
ul(class='nav nav-list')
li(class='nav-header') Current Season
- if(currentUrl === '/')
li(class='active')
a(href='/') Current Driver Standings
- else
li
a(href='/') Current Driver Standings
- if(currentUrl === '/constructor-standings')
li(class='active')
a(href='/constructor-standings') Current Constructor Standings
- else
li
a(href='/constructor-standings') Current Constructor Standings
- if(currentUrl === '/current-schedule')
li(class='active')
a(href='/current-schedule') Current Race Schedule
- else
li
a(href='/current-schedule') Current Race Schedule
Upvotes: 0