Displaying active navigation based on contextual d

2020-06-01 01:01发布

问题:

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?

回答1:

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.



回答2:

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>


回答3:

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.



回答4:

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>


回答5:

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.



回答6:

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');