Best way to make Twitter Bootstrap tabs persistent

Solution 1:

This code selects the right tab depending on the #hash and adds the right #hash when a tab is clicked. (this uses jQuery)

In CoffeeScript:

$(document).ready ->
    if location.hash != ''
         $('a[href="'+location.hash+'"]').tab('show')

    $('a[data-toggle="tab"]').on 'shown', (e) ->
        location.hash = $(e.target).attr('href').substr(1)

Or in JavaScript:

$(document).ready(function() {
    if (location.hash !== '') $('a[href="' + location.hash + '"]').tab('show');
    return $('a[data-toggle="tab"]').on('shown', function(e) {
      return location.hash = $(e.target).attr('href').substr(1);
    });
});

Solution 2:

I wanted to improve the best answer here...

Credit goes to Sucrenoir, but if you want to avoid jumping on the page when you change tabs, use this improved code:

$(document).ready(function() {

    // Show active tab on reload
    if (location.hash !== '') $('a[href="' + location.hash + '"]').tab('show');

    // Remember the hash in the URL without jumping
    $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
       if(history.pushState) {
            history.pushState(null, null, '#'+$(e.target).attr('href').substr(1));
       } else {
            location.hash = '#'+$(e.target).attr('href').substr(1);
       }
    });
});

Solution 3:

Here is another way to solve the problem.

First add a line to the click event to show the hash in the address bar:

$('#myTab').on('click', 'a', function (e) {
  e.preventDefault();

  // Add this line
  window.location.hash = $(this).attr('href');

  $(this).tab('show');
})

Then make sure that the right tab is activated onload by adding this part to your document ready call.

if(window.location.hash){
   $('#myTab').find('a[href="'+window.location.hash+'"]').tab('show');
}

All together you can write this:

// Cache the ID
var navbox = $('#myTab');

// Activate tab on click
navbox.on('click', 'a', function (e) {
  var $this = $(this);

  // Prevent the ***default*** behavior
  e.preventDefault();

  // Set the hash to the address bar
  window.location.hash = $this.attr('href');

  // Activate the clicked tab
  $this.tab('show');
})

// If we have a hash in the address bar
if(window.location.hash){

  // Show right tab on load (read hash from address bar)
  navbox.find('a[href="'+window.location.hash+'"]').tab('show');
}

Solution 4:

I wanted to improve the best two answers here.. :)

Credit goes to Sucrenoir and d-wade.

Because the history API is used in code, you can't use onchangehash (https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onhashchange). This code add the functionality of back button (https://developer.mozilla.org/cs/docs/Web/API/WindowEventHandlers/onpopstate).

// Show active tab on reload
if (location.hash !== '')
    $('a[href="' + location.hash + '"]').tab('show');

// Remember the hash in the URL without jumping
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    if(history.pushState) {
        history.pushState(null, null, '#'+$(e.target).attr('href').substr(1));
    }
    else {
        location.hash = '#'+$(e.target).attr('href').substr(1);
    }
});

// Remember to back button
window.onpopstate = function(e) {
    $('a[href="' + location.hash + '"]').tab('show');
};