How do I keep the current tab active with twitter bootstrap after a page reload?

JavascriptJqueryTwitter Bootstrap

Javascript Problem Overview


I'm currently using tabs with Twitter Bootstrap and want to select the same tab after a user has posted data and the page reloads.

How is this done?

My current call to inti the tabs looks like this:

<script type="text/javascript">

$(document).ready(function() {

	$('#profileTabs a:first').tab('show');
});
</script>

My tabs:

<ul id="profileTabs" class="nav nav-tabs">
	<li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
	<li><a href="#about" data-toggle="tab">About Me</a></li>
	<li><a href="#match" data-toggle="tab">My Match</a></li>
</ul>

Javascript Solutions


Solution 1 - Javascript

You'll have to use localStorage or cookies to manage that. Here's a quick and dirty solution that can be vastly improved, but may give you a starting point:

$(function() { 
	// for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use 'shown' in the next line
	$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
		// save the latest tab; use cookies if you like 'em better:
		localStorage.setItem('lastTab', $(this).attr('href'));
	});

	// go to the latest tab, if it exists:
	var lastTab = localStorage.getItem('lastTab');
	if (lastTab) {
		$('[href="' + lastTab + '"]').tab('show');
	}
});

Solution 2 - Javascript

Got this to work using cookies and also removing the 'active' class from any other tabs and tab panes... and adding the 'active' class to the current tab and tab pane.

I'm sure there's a better way to do this, but this appears to work in this case.

Requires the jQuery cookie plugin.

$(function() { 
  $('a[data-toggle="tab"]').on('shown', function(e){
    //save the latest tab using a cookie:
    $.cookie('last_tab', $(e.target).attr('href'));
  });

  //activate latest tab, if it exists:
  var lastTab = $.cookie('last_tab');
  if (lastTab) {
      $('ul.nav-tabs').children().removeClass('active');
      $('a[href='+ lastTab +']').parents('li:first').addClass('active');
      $('div.tab-content').children().removeClass('active');
      $(lastTab).addClass('active');
  }
});

Solution 3 - Javascript

All other answers are correct. This answer will take into account the fact that one might have multiple ul.nav.nav-pills or ul.nav.nav-tabs on the same page. In this case, the previous answers will fail.

Still using localStorage but with a stringified JSON as the value. Here is the code:

$(function() {
  var json, tabsState;
  $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown', function(e) {
    var href, json, parentId, tabsState;
    
    tabsState = localStorage.getItem("tabs-state");
    json = JSON.parse(tabsState || "{}");
    parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id");
    href = $(e.target).attr('href');
    json[parentId] = href;

    return localStorage.setItem("tabs-state", JSON.stringify(json));
  });
  
  tabsState = localStorage.getItem("tabs-state");
  json = JSON.parse(tabsState || "{}");

  $.each(json, function(containerId, href) {
    return $("#" + containerId + " a[href=" + href + "]").tab('show');
  });
  
  $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
    var $this = $(this);
    if (!json[$this.attr("id")]) {
      return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show");
    }
  });
});

This bit can be used on the entire app over all pages and will work for both tabs and pills. Also, make sure the tabs or pills are not active by default, otherwise you will see a flicker effect at page load.

Important: Make sure the parent ul has an id. Thanks Alain

Solution 4 - Javascript

For the best option, use this technique:

$(function() { 
  //for bootstrap 3 use 'shown.bs.tab' instead of 'shown' in the next line
  $('a[data-toggle="tab"]').on('click', function (e) {
    //save the latest tab; use cookies if you like 'em better:
    localStorage.setItem('lastTab', $(e.target).attr('href'));
  });

  //go to the latest tab, if it exists:
  var lastTab = localStorage.getItem('lastTab');
  
  if (lastTab) {
    $('a[href="'+lastTab+'"]').click();
  }
});

Solution 5 - Javascript

I prefer storing the selected tab in the hashvalue of the window. This also enables sending links to colleagues, who than see "the same" page. The trick is to change the hash of the location when another tab is selected. If you already use # in your page, possibly the hash tag has to be split. In my app, I use ":" as hash value separator.

<ul class="nav nav-tabs" id="myTab">
    <li class="active"><a href="#home">Home</a></li>
    <li><a href="#profile">Profile</a></li>
    <li><a href="#messages">Messages</a></li>
    <li><a href="#settings">Settings</a></li>
</ul>

<div class="tab-content">
    <div class="tab-pane active" id="home">home</div>
    <div class="tab-pane" id="profile">profile</div>
    <div class="tab-pane" id="messages">messages</div>
    <div class="tab-pane" id="settings">settings</div>
</div>

<script>
    $('#myTab a').click(function (e) {
        e.preventDefault()
        $(this).tab('show')
    });

    // store the currently selected tab in the hash value
    $("ul.nav-tabs > li > a").on("shown.bs.tab", function (e) {
        var id = $(e.target).attr("href").substr(1);
        window.location.hash = id;
    });

    // on load of the page: switch to the currently selected tab
    var hash = window.location.hash;
    $('#myTab a[href="' + hash + '"]').tab('show');
</script>

Solution 6 - Javascript

To prevent the page flashing on the first tab and then the tab that was saved by the cookie (this occurs when you determine the class "active" by default in the first TAB)

Remove the class "active" of tabs and panes like:

<ul class="nav nav-tabs">
<div id="p1" class="tab-pane">

Put the script below to set first tab like default (Requires the jQuery cookie plugin)

    $(function() { 
        $('a[data-toggle="tab"]').on('shown', function(e){
            //save the latest tab using a cookie:
            $.cookie('last_tab', $(e.target).attr('href'));
        });
        //activate latest tab, if it exists:
        var lastTab = $.cookie('last_tab');
        if (lastTab) {
            $('a[href=' + lastTab + ']').tab('show');
        }
        else
        {
            // Set the first tab if cookie do not exist
            $('a[data-toggle="tab"]:first').tab('show');
        }
    });

Solution 7 - Javascript

I had tabs in multiple pages and localStorage keeps lastTab from previous pages as well, so for next page, since it had previous page's lastTab in storage, it didn't find any matching tab here, so nothing was being displayed. I modified it this way.

$(document).ready(function(){
	//console.log($('a[data-toggle="tab"]:first').tab('show'))
	$('a[data-toggle="tab"]').on('shown.bs.tab', function () {
		//save the latest tab; use cookies if you like 'em better:
		localStorage.setItem('lastTab', $(this).attr('href'));
	});

	//go to the latest tab, if it exists:
	var lastTab = localStorage.getItem('lastTab');
	if ($('a[href=' + lastTab + ']').length > 0) {
		$('a[href=' + lastTab + ']').tab('show');
	}
	else
	{
		// Set the first tab if cookie do not exist
		$('a[data-toggle="tab"]:first').tab('show');
	}
})

edit: I've noticed that I'll have to have different lastTab variable names for different pages, otherwise, they'll always overwrite each other. e.g. lastTab_klanten, lastTab_bestellingen etc. for two different pages klanten and bestellingen both having data displayed in tabs.

$(document).ready(function(){
	//console.log($('a[data-toggle="tab"]:first').tab('show'))
	$('a[data-toggle="tab"]').on('shown.bs.tab', function () {
		//save the latest tab; use cookies if you like 'em better:
		localStorage.setItem('lastTab_klanten', $(this).attr('href'));
	});

	//go to the latest tab, if it exists:
	var lastTab_klanten = localStorage.getItem('lastTab_klanten');
	if (lastTab_klanten) {
		$('a[href=' + lastTab_klanten + ']').tab('show');
	}
	else
	{
		// Set the first tab if cookie do not exist
		$('a[data-toggle="tab"]:first').tab('show');
	}
})

Solution 8 - Javascript

Want fading effect? Updated version of @Oktav's code:

  1. For Bootstrap 3
  2. Sets up the classes on the li and tab's div to enable fading to work properly. Note that all of the content divs need class="tab-pane fade"

Code:

// See http://stackoverflow.com/a/16984739/64904
// Updated by Larry to setup for fading
$(function() {
  var json, tabsState;
  $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    var href, json, parentId, tabsState;
    tabsState = localStorage.getItem("tabs-state");
    json = JSON.parse(tabsState || "{}");
    parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id");
    href = $(e.target).attr('href');
    json[parentId] = href;
    return localStorage.setItem("tabs-state", JSON.stringify(json));
  });
  tabsState = localStorage.getItem("tabs-state");
  json = JSON.parse(tabsState || "{}");
  $.each(json, function(containerId, href) {
    var a_el = $("#" + containerId + " a[href=" + href + "]");
    $(a_el).parent().addClass("active");
    $(href).addClass("active in");
    return $(a_el).tab('show');
  });
  $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
    var $this = $(this);
    if (!json[$this.attr("id")]) {
      var a_el = $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first"),
          href = $(a_el).attr('href');
      $(a_el).parent().addClass("active");
      $(href).addClass("active in");
      return $(a_el).tab("show");
    }
  });
});

Solution 9 - Javascript

I made it works with similar solution as @dgabriel, in this case, the links <a> don't need id, it identify the current tab based on the position.

$(function() { 
  $('a[data-toggle="tab"]').on('shown', function (e) {
    var indexTab = $('a[data-toggle="tab"]').index($(this)); // this: current tab anchor
    localStorage.setItem('lastVisitedTabIndex', indexTab);
  });

  //go to the latest tab, if it exists:
  var lastIndexTab  = localStorage.getItem('lastVisitedTabIndex');
  if (lastIndexTab) {
      $('a[data-toggle="tab"]:eq(' + lastIndexTab + ')').tab('show');
  }
});

Solution 10 - Javascript

I suggest the following changes

  1. Use a plugin like amplify.store which provides a crossbrowser/ crossplatform localstorage API with builtin fallbacks.

  2. Target the tab that needs to be saved like $('#div a[data-toggle="tab"]') so as to extend this functionality to multiple tab containers that exist on the same page.

  3. Use a unique identifier (url ??) to save and restore last used tabs across multiple pages.


$(function() { 
  $('#div a[data-toggle="tab"]').on('shown', function (e) {
    amplify.store(window.location.hostname+'last_used_tab', $(this).attr('href'));
  });

  var lastTab = amplify.store(window.location.hostname+'last_used_tab');
  if (lastTab) {
    $("#div a[href="+ lastTab +"]").tab('show');
  }
});

Solution 11 - Javascript

Simple solution without local storage:

$(".nav-tabs a").on("click", function() {
    location.hash = $(this).attr("href");
});

Solution 12 - Javascript

Server side approach. Be sure all html elements have class="" in case not specified or you will need to handle nulls.

    private void ActiveTab(HtmlGenericControl activeContent, HtmlGenericControl activeTabStrip)
    {
        if (activeContent != null && activeTabStrip != null)
        {
            // Remove active from content
            Content1.Attributes["class"] = Content1.Attributes["class"].Replace("active", "");
            Content2.Attributes["class"] = Content2.Attributes["class"].Replace("active", "");
            Content3.Attributes["class"] = Content3.Attributes["class"].Replace("active", "");

            // Remove active from tab strip
            tabStrip1.Attributes["class"] = tabStrip1.Attributes["class"].Replace("active", "");
            tabStrip2.Attributes["class"] = tabStrip2.Attributes["class"].Replace("active", "");
            tabStrip3.Attributes["class"] = tabStrip3.Attributes["class"].Replace("active", "");

            // Set only active
            activeContent.Attributes["class"] = activeContent.Attributes["class"] + " active";
            activeTabStrip.Attributes["class"] = activeTabStrip.Attributes["class"] + " active";
        }
    }

Solution 13 - Javascript

If you want to show the first tab the first time you enter the page use this code:

    <script type="text/javascript">
        function invokeMeMaster() {
        var chkPostBack = '<%= Page.IsPostBack ? "true" : "false" %>';
            if (chkPostBack == 'false') {
                $(function () {
                    // for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use 'shown' in the next line
                    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                        // save the latest tab; use cookies if you like 'em better:
                        localStorage.setItem('lastTab', $(this).attr('href'));
                    });

                });
            }
            else {
                $(function () {

                    // for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use 'shown' in the next line
                    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                        // save the latest tab; use cookies if you like 'em better:
                        localStorage.setItem('lastTab', $(this).attr('href'));
                    });

                    // go to the latest tab, if it exists:
                    var lastTab = localStorage.getItem('lastTab');
                    if (lastTab) {
                        $('[href="' + lastTab + '"]').tab('show');
                    }

                });

            }
        }
        window.onload = function() { invokeMeMaster(); };

    </script>

Solution 14 - Javascript

Here is a snippet I made that works with Bootstrap 3 and jQuery and with different URLs containing different tabs. It does not support multiple tabs per page though but it should be an easy modification if you need that feature.

/**
 * Handles 'Bootstrap' package.
 *
 * @namespace bootstrap_
 */

/**
 * @var {String}
 */
var bootstrap_uri_to_tab_key = 'bootstrap_uri_to_tab';

/**
 * @return {String}
 */
function bootstrap_get_uri()
{
    return window.location.href;
}

/**
 * @return {Object}
 */
function bootstrap_load_tab_data()
{
    var uriToTab = localStorage.getItem(bootstrap_uri_to_tab_key);
    if (uriToTab) {
	try {
	    uriToTab = JSON.parse(uriToTab);
	    if (typeof uriToTab != 'object') {
		uriToTab = {};
	    }
	} catch (err) {
	    uriToTab = {};
	}
    } else {
	uriToTab = {};
    }
    return uriToTab;
}

/**
 * @param {Object} data
 */
function bootstrap_save_tab_data(data)
{
    localStorage.setItem(bootstrap_uri_to_tab_key, JSON.stringify(data));
}

/**
 * @param {String} href
 */
function bootstrap_save_tab(href)
{
    var uri = bootstrap_get_uri();
    var uriToTab = bootstrap_load_tab_data();
    uriToTab[uri] = href;
    bootstrap_save_tab_data(uriToTab);
}

/**
 *
 */
function bootstrap_restore_tab()
{
    var uri = bootstrap_get_uri();
    var uriToTab = bootstrap_load_tab_data();
    if (uriToTab.hasOwnProperty(uri) &&
	$('[href="' + uriToTab[uri] + '"]').length) {
    } else {
	uriToTab[uri] = $('a[data-toggle="tab"]:first').attr('href');
    }
    if (uriToTab[uri]) {
        $('[href="' + uriToTab[uri] + '"]').tab('show');
    }
}

$(document).ready(function() {

    if ($('.nav-tabs').length) {

	// for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use 'shown' in the next line
	$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
	    bootstrap_save_tab($(this).attr('href'));
	});
	bootstrap_restore_tab();

    }

});

Solution 15 - Javascript

$(document).ready(function () {

        if (JSON.parse(localStorage.getItem('currentClass')) == "active")
        {
            jQuery('#supporttbl').addClass('active')
            $('.sub-menu').css({ "display": "block" });
        }

        $("#supporttbl").click(function () { 
            var currentClass;
            if ($(this).attr('class')== "active") { 

                currentClass = $(this).attr('class');

                localStorage.setItem('currentClass', JSON.stringify(currentClass));
                console.log(JSON.parse(localStorage.getItem('currentClass')));

                jQuery('#supporttbl').addClass('active')
                $('.sub-menu').css({ "display": "block" });

            } else {
                
                currentClass = "Null"; 

                localStorage.setItem('currentClass', JSON.stringify(currentClass));
                console.log(JSON.parse(localStorage.getItem('currentClass')));

                jQuery('#supporttbl').removeClass('active')
                $('.sub-menu').css({ "display": "none" });
                
            }  
        });
        

});

Solution 16 - Javascript

if you have more than one tab in the page, you can use the following code

<script type="text/javascript">
$(document).ready(function(){
    $('#profileTabs').on('show.bs.tab', function(e) {
        localStorage.setItem('profileactiveTab', $(e.target).attr('href'));
    });
    var profileactiveTab = localStorage.getItem('profileactiveTab');
    if(profileactiveTab){
        $('#profileTabs a[href="' + profileactiveTab + '"]').tab('show');        
    }
    $('#charts-tab').on('show.bs.tab', function(e) {
        localStorage.setItem('chartsactiveTab', $(e.target).attr('href'));
    });
    var chartsactiveTab = localStorage.getItem('chartsactiveTab');
    if(chartsactiveTab){
        $('#charts-tab a[href="' + chartsactiveTab + '"]').tab('show');        
    }     
});
</script>

Solution 17 - Javascript

This will refresh the tabs but only after everything in the controller is loaded.

// >= angular 1.6 angular.element(function () {
angular.element(document).ready(function () {
    //Here your view content is fully loaded !!
    $('li[href="' + location.hash + '"] a').tab('show');
});

Solution 18 - Javascript

I'm using this with MVC:

  • There is a SelectedTab integer field in the model to send the value to the POST method

JavaScript Section:

<script type="text/javascript">
    $(document).ready(function () {
       var index = $("input#SelectedTab").val();
       $("#tabstrip > ul li:eq(" + index + ")").addClass("k-state-active");
        
       $("#tabstrip").kendoTabStrip();
    });
    function setTab(index) {
      $("input#SelectedTab").val(index)
    }
</script>

HTML Section:

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.SelectedTab)
<div id="tabstrip">
    <ul>
        <li onclick="setTab(0)">Content 0</li>
        <li onclick="setTab(1)">Content 1</li>
        <li onclick="setTab(2)">Content 2</li>
        <li onclick="setTab(3)">Content 3</li>
        <li onclick="setTab(4)">Content 4</li>
    </ul>
    <div>
        
    </div>
    <div>
        
    </div>
    <div>
        
    </div>
    <div>
        
    </div>
    <div>
        
    </div>
</div>
<div class="content">
    <button type="submit" name="save" class="btn bg-blue">Save</button>
</div>
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaulView Question on Stackoverflow
Solution 1 - JavascriptdgabrielView Answer on Stackoverflow
Solution 2 - JavascriptricsrockView Answer on Stackoverflow
Solution 3 - JavascriptOktavView Answer on Stackoverflow
Solution 4 - JavascriptVaimeoView Answer on Stackoverflow
Solution 5 - JavascriptkopporView Answer on Stackoverflow
Solution 6 - JavascriptJeferson TenorioView Answer on Stackoverflow
Solution 7 - JavascriptGoharSahiView Answer on Stackoverflow
Solution 8 - JavascriptLarry KView Answer on Stackoverflow
Solution 9 - JavascriptJaiderView Answer on Stackoverflow
Solution 10 - JavascriptSandeepView Answer on Stackoverflow
Solution 11 - JavascriptFrancesco BorziView Answer on Stackoverflow
Solution 12 - JavascriptMichael GoldshmidtView Answer on Stackoverflow
Solution 13 - JavascriptrubenView Answer on Stackoverflow
Solution 14 - JavascriptcjohanssonView Answer on Stackoverflow
Solution 15 - Javascriptdinesh patidarView Answer on Stackoverflow
Solution 16 - JavascriptMohamed SamiView Answer on Stackoverflow
Solution 17 - JavascriptPHPGuruView Answer on Stackoverflow
Solution 18 - JavascriptCarlos ToledoView Answer on Stackoverflow