I have the following separated fragment in a Thymeleaf template.
<ul class="nav nav-tabs">
<li role="presentation"><a href="/">Freight Invoices</a></li>
<li role="presentation"><a href="/processed">Processed Invoices</a></li>
<li role="presentation"><a href="/postingrules">Posting Rules</a></li>
<li role="presentation" class="active"><a href="/settings">Settings</a></li>
</ul>
I want to add an "active" class to active navigation element — but it seems hard to accomplish in Thymyleaf. Any suggestions?
You could add a ModelAttribute with the value active in your controllers for each page, e.g. :
SettingsController.java
@RequestMapping("/settings")
public String viewSettings(Model model) {
// do stuff
model.addAttribute("classActiveSettings","active");
return "settings";
}
OR in a SettingsControllerAdvice.java
@ControllerAdvice(assignableTypes = SettingsController.class)
public class SettingsControllerAdvice {
@ModelAttribute("classActiveSettings")
public String cssActivePage() {
return "active";
}
}
Then, in the navigation fragment included in your settings.html :
<ul class="nav nav-tabs">
<!-- Other links -->
<li role="presentation" th:class="${classActiveSettings}">
<a th:href="@{/settings}">Settings</a>
</li>
</ul>
Finally, you can repeat this process for each controller and links in your navbar.
You can do this:
<ul class="nav navbar-nav">
<li th:classappend="${#httpServletRequest.getRequestURI() == '/dashboard' ? 'active':''}"><a th:href="@{/dashboard}"><span>Dashboard</span></a></li>
<li th:classappend="${#httpServletRequest.getRequestURI() == '/orders' ? 'active':''}"><a th:href="@{/orders}"><span>Orders</span></a></li>
<li th:classappend="${#httpServletRequest.getRequestURI() == '/income' ? 'active':''}"><a th:href="@{/income}"><span>Income</span></a></li>
<li role="separator" ></li>
</ul>
Although i think it is ugly solution and it is pity that thymeleaf does not have some macros for it, you can use:
<li th:classappend="${#httpServletRequest.getRequestURI().startsWith('/hotels') ? 'active':''}">
Hotel
</li>
It will work also for "deeper" links like /hotels/new so it is usable also for multilevel menus.
while this is an old question, I want to share this solution as it could be much more elegant!
http://nixmash.com/post/bootstrap-navbar-highlighting-in-thymeleaf
- Add a parameter (activeTab) to the navigation fragment.
<div th:fragment="common-navbar(activeTab)"></div>
- pass the value of it in the main pages that use the navbar fragment
<div th:replace="common/navbar :: common-navbar(about)"></div>
- check for it in 'li' element to set the 'active' class
<li th:class="${activeTab == 'about'}? 'active' : null"><a href="">About</a></li>
For those using Thymeleaf 3:
<a th:href="@{/home}" th:classappend="${#request.getRequestURI() == '/home' ? 'active' : ''}">Home</a>
If you have a context path on your application:
<a th:href="@{/home}" th:classappend="${#request.getRequestURI() == '/context-path/home' ? 'active' : ''}">Home</a>
Edit:
To be concise:
<a th:href="@{/home}" th:classappend="${#request.getServletPath() == '/home' ? 'active' : ''}">Home</a>
The benefit to using request.getServletPath()
is that it ignores the context path, if there is one.
May be this code would be helpful for someone. Attention! It's not Thymeleaf solution, just js code which you can add on your pages.
var currentPage = location.href.match(/(.*?)([^\/]+)$/).pop();
$(Array.prototype.filter.call($('.menu-head li a:nth-child(1)'), function(item)
{
return item.href.endsWith(currentPage)
})).parents('li').addClass('active');