Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Twitter Bootstrap Tabs active class toggle not working

Tags:

I am using Twitter bootstrap nav tabs and nav pills. This is my html code:

<div class="Header2" style="background-color:#1E3848">     <div id="headerTab">         <ul class="nav nav-tabs">             <li class="active ans-tab"> <a href="http://myweb.com/">Home</a></li>             <li class="topTab"><a href="http://myweb.com/score/">Score</a></li>             <li class="topTab"><a href="http://myweb.com/leaderboards/">Leaderboards</a></li>         </ul>     </div>     <div id="subHeaderTabPlayer">         <ul class="nav nav-pills">             <li class="active"> <a href="http://myweb.com/">Top</a></li>             <li><a href="http://myweb.com/rules/" data-toggle="pill">Rules</a></li>             <li><a href="http://myweb.com/player/" data-toggle="pill">Player</a></li>             <li><a href="http://myweb.com/categories/" data-toggle="pill">Categories</a></li>         </ul>     </div> </div> 

Now if I add attribute data-toggle="pill" and data-toggle="tab" the tab with active class change to one which I have clicked. However, href is no longer working. If I do not use these classes, href works but active class does not change and it always stays to the element that class was given at the load of page.

I even tried using jQuery to toggle class behavior and it does not work as well. My script code is:

<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script> <script type="text/javascript">     $(window).load(function(){         document.getElementById( 'subHeaderTabPlayer' ).style.display = 'none';         $('ul.nav-tabs li a').click(function (e) {             var activeTab= document.getElementByClass('active');             activeTab.removeAttribute("class");              $('ul.nav-tabs li.active').removeClass('active')             $(this).parent('li').addClass('active')         })         $('ul.nav-pills li a').click(function (e) {             $('ul.nav-pills li.active').removeClass('active');             $(this).parent('li').addClass('active');         })         $(".ans-tab").click(function() {             document.getElementById('subHeaderTabPlayer').style.visibility = 'visible';             document.getElementById('subHeaderTabPlayer' ).style.display = 'block';         });         $(".topTab").click(function() {             document.getElementById('subHeaderTabPlayer').style.visibility = 'collapse';             document.getElementById('subHeaderTabPlayer' ).style.display = 'none';         });     }); </script> 
like image 611
CodeMonkey Avatar asked Apr 18 '13 00:04

CodeMonkey


People also ask

How do I toggle tabs in bootstrap?

To make the tabs toggleable, add the data-toggle="tab" attribute to each link. Then add a . tab-pane class with a unique ID for every tab and wrap them inside a <div> element with class . tab-content .

How do you keep the current tab active on page reload?

Answer: Use the HTML5 localStorage Object In Bootstrap, if you refresh the page the tab is reset to default setting. However, you can use the HTML5 localStorage object to save some parameter for the current tab locally in the browser and get it back to make the last active tab selected on page reload.


2 Answers

Bootstrap nav tabs and pills work with a JS plugin. The plugin is loaded on the page and takes care of the highlighting and the remembering of the currently active tab or pill. It disables the href attributes if they link to other pages, simply because when you click on a link to another page, a new page is loaded. The JS is then reloaded for this new page, and it does not know about which tab or pill is currently active. They are designed to work with single page apps or links to anchors on the same page, and they work fine for that purpose.

The jQuery approach fails for the same reason, but might be easier to explain.

$('ul.nav-pills li a').click(function (e) {   $('ul.nav-pills li.active').removeClass('active')   $(this).parent('li').addClass('active') }) 

You click on a link, JS goes off and changes the class, only if it has enough time to do so before the next page is loaded, this next page is loaded because the href attribute on the link tells the browser to navigate to a new page. And the new page loads your JS again, it can't possibly remember the variables from the previous page, like which tab or pill is meant to be active.

If you are going to navigate to other pages, you might as well just set the active class on the right tab for the specific page that is being loaded.

If you really need to do this on the client side, you could do something like this, and load it on each page.

$(document).ready(function () {    // Set BaseURL   var baseURL = 'http://myweb.com/'    // Get current URL and replace baseURL   var href = window.location.href.replace(baseURL, '');    // Remove trailing slash   href = href.substr(-1) == '/' ? href.substr(0, href.length - 1) : href;    // Get last part of current URL   var page = href.substr(href.lastIndexOf('/') + 1);    // Add trailing slash if not empty (empty means we're currently at baseURL)   page = page != '' ? page + '/' : page;    // Select link based on href attribute and set it's closest 'li' to 'active'.    // .siblings('.active').removeClass() is only needed if you have a default 'active li'.   $('a[href="' + baseURL + page + '"]', '.nav li').closest('li').addClass('active').siblings('.active').removeClass();  }); 

It sets the active tab based on the last part of the URL, it's kind of specific to your scenario (and previously my scenario) though. You'd have to adapt it if there were file extensions or query parameters involved. Every page needs to at least have a link to itself on it. And it preferably has the exact same header with the same tabs and pills rendered on it as all the other pages.

Both of these last points again raise the thought in my mind "if you have to have this much control over what exactly is being rendered onto the page, you probably have access to the server side", and if that is the case, you might as well fix it there, as every link does a new request to the server anyway. And your solution wouldn't have to rely on some not so robust JavaScript to work.

So this is what I had going at one stage, you could improve it, or implement a solution where you post some data to the next page and read it with JavaScript there (which would probably be easier and more robust if you had file extensions or query strings to deal with).

Good luck with it! :)

like image 60
tom-19 Avatar answered Oct 08 '22 10:10

tom-19


Something to consider: If each li element uses a different controller, here's something you could try.

How to get Twitter-Bootstrap navigation to show active link?

Your code could look something like this:

<ul class="nav nav-pills">   <li class="<%= 'active' if params[:controller] == 'home' %>"> <a href="link" data-toggle="pill">Top</a></li>   <li class="<%= 'active' if params[:controller] == 'rules' %>"><a href="link" data-toggle="pill">Rules</a></li>   <li class="<%= 'active' if params[:controller] == 'player' %>"><a href="link" data-toggle="pill">Player</a></li>   <li class="<%= 'active' if params[:controller] == 'categories' %>"><a href="link" data-toggle="pill">Categories</a></li> </ul> 
like image 26
syeh Avatar answered Oct 08 '22 09:10

syeh