[Django]-Make clicked tab active in Bootstrap

51πŸ‘

βœ…

This solution didn’t work when the href attribute of your links will be different from href="#". Why ? Simply because each click on a link triggers a request to the server. In your JS code, you add the method preventDefault() in order to avoid this basic behavior, but I think that not really your objective for this purpose, isn’t it ?

To handle this kind of feature you can update your template code by adding something like this :

base.html

<div class="collapse navbar-collapse" id="tn-navbar-collapse">
    <ul class="nav navbar-nav">
        <li class="{% if nbar == 'home' %}active{% endif %}">
            <a href="/">HOME</a>
        </li>
        ...
    </ul>
</div>

views.py

def your_view(request):
    ...
    return render(request, 'yourtemplate.html', {'nbar': 'home'})

With this way, you don’t have to manage this feature with javascript.

πŸ‘€rphonika

56πŸ‘

If you dont want to send any additional context from views then you can handle it like this with resolver_match:

<li {% if request.resolver_match.url_name == 'home' %}class="active"{% endif %}>
    <a href="/">HOME</a>
</li>

where β€˜home’ is the name given to your url pattern for / (probably '^$') in your urls.py.
So obviously to use this you need to name all your url patterns, which is a good practice anyway.

πŸ‘€MohitC

8πŸ‘

Alternative including URL namespaces:

<li class="nav-item {% if request.resolver_match.view_name == 'scores:list' %}active{% endif %}">
    <a class="nav-link" href="{% url 'scores:list' %}">Scores</a>
</li>
πŸ‘€Daniel Garcia

1πŸ‘

I recently ran into this problem and tried every solution I could find. Eventually, I came to this. This example assumes the path to this content is yoursite.com/about
Give your link an id.

<li><a id="about" href="#">About</a></li>

var path = $(location).attr('pathname')
var pa = path.split("/")
$('#'+pa[1]).tab('show')

1πŸ‘

@rphonika has give a nice answer. But if you have many navigation menus then adding template logic in each list item makes the code untidy. Menu items can be assigned a unique id, the id passed in views and active class can be assigned using a one liner javascript code in html itself.

base.html

<ul class="nav navbar-nav navbar-left">
  <li><a class="navmenu-a" id="overview" href="{% url 'webapp:overview' %}">Overview</a></li>
  <li><a class="navmenu-a" id="plot" href="{% url 'webapp:plot' %}">Plot</a></li>
  <li><a class="navmenu-a" id="board" href="{% url 'webapp:board' %}">Board</a></li>
  <li><a class="navmenu-a" id="storyboard" href="{% url 'webapp:storyboard' %}">Storyboard</a></li>
  <li><a class="navmenu-a" id="freqs" href="{% url 'webapp:freqs' %}">Faq</a></li>
</ul>
.
.
.
<script type="text/javascript">
  {% if nmenu %} $("a#{{nmenu}}").addClass("navmenu-a-active") {% endif %}
</script>

views.py

def overview(request):
    ...
    return render(request, 'overview.html', {'nmenu': 'overview'})


def plot(request):
    ...
    return render(request, 'plot.html', {'nmenu': 'plot'})

And so on for other views

πŸ‘€antman

1πŸ‘

I would rather prefer to only edit the template using rather than editing both views and templates for this. People needing the same, rather than following the accepted answer, may consider the below way:

<ul class="navbar-nav">
  <li class="nav-item {% ifequal request.path '/' %} active {% endifequal %}">
      <a class="nav-link" href="/">Home</a>
  </li>
</ul

You can change β€˜index’ above with your own

πŸ‘€Jayesh

1πŸ‘

I think the easiest solution is JavaScript / CSS:
Anyway, here is the solution using Jquery. Notice n1,n2 classes in html

In base.html

   <nav>
    <ul class="nav flex-column">
       <li class="nav-item">
          <a class="nav-link n1" href="{% url 'polls:dashboard' %}">
          <span data-feather="home"></span>
          Dashboard 
          </a>
       </li>
       <li class="nav-item">
          <a class="nav-link n2" href="{% url 'polls:restaurants' %}">
          <span data-feather="file"></span>
          Restaurants
          </a>
       </li>
    </ul>
    </nav>
        <script>
        $('nav').find('{% block active_link%}{%endblock%}').addClass('active')
        </script>

Then in your dashboard template:

{% block active_link %}.n1{%endblock%}

In your restaurants template:

{% block active_link %}.n2{%endblock%}

πŸ‘€csandreas1

1πŸ‘

The most Django-canonical way of adding an active class to the nav item for the current page is with template inheritance. No JavaScript required. In your base template(ex: base.html) add a block for each nav link active class like this:

<ul class="nav navbar-nav">
        <li class="{% block nav_home_class %}{% endblock %}"><a href="#">Home</a></li>
        <li class="{% block nav_about_class %}{% endblock %}"><a href="#">About</a></li>
        <li class="{% block nav_contact_class %}{% endblock %}"><a href="#">Contact</a></li>
...

Then in each page’s template, set the matching nav_*_class block to active. For home.html:

{% extends "base.html" %}
{% block nav_home_class %}active{% endblock %}
...

The resulting html in the home page will look like:

<ul class="nav navbar-nav">
        <li class="active"><a href="#">Home</a></li>
        <li class=""><a href="#">About</a></li>
        <li class=""><a href="#">Contact</a></li>
...

0πŸ‘

After adding gamer’s JavaScript into your template code_here , you got to make sure you have the similar settings in your CSS file also, in order to make JavaScript work.

.navbar-nav > li.active > a {
  color: #d74b4b;
  background: transparent;
  border-bottom: none;
}
πŸ‘€Bigyellowbee

0πŸ‘

You can check if a string is in your URL path. This is helpful for hierarchical or nested URL paths

<li {% if 'home' in request.get_full_path %}class="active"{% endif %}>
    <a href="/">HOME</a>
</li>
πŸ‘€Alchemy

0πŸ‘

def my_view(request):
    active_tab = 'home'  # set the active tab here
    context = {'active_tab': active_tab}
    return render(request, 'my_template.html', context)

Then, in your template, you can use an if statement to check if the current page matches the active tab and apply a CSS class to the active tab.

<ul class="nav nav-tabs">
    <li {% if active_tab == 'home' %}class="active"{% endif %}>
        <a href="{% url 'home' %}">Home</a>
    </li>
    <li {% if active_tab == 'about' %}class="active"{% endif %}>
        <a href="{% url 'about' %}">About</a>
    </li>
    <li {% if active_tab == 'contact' %}class="active"{% endif %}>
        <a href="{% url 'contact' %}">Contact</a>
    </li>
</ul>

-2πŸ‘

If you want activate by context you can do like this variable == to context in .views

<li class="nav-item {% ifequal variable context %}active{% endifequal%}">
    <a class="nav-link" href="{% url 'scores:list' %}">Scores</a>
</li>

Leave a comment