Como mantenho a guia atual ativa com o bootstrap do Twitter após o recarregamento da página?

86

Atualmente, estou usando guias com o Twitter Bootstrap e desejo selecionar a mesma guia depois que um usuário postar dados e a página recarregar.

Como isso é feito?

Minha chamada atual para inti the tabs se parece com isto:

<script type="text/javascript">

$(document).ready(function() {

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

Minhas guias:

<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>
Paulo
fonte
1
Esta parece ser uma pergunta duplicada para stackoverflow.com/questions/18999501/…
koppor
relacionado a stackoverflow.com/questions/7862233/…
Tim Abell

Respostas:

137

Você terá que usar localStorage ou cookies para gerenciar isso. Aqui está uma solução rápida e suja que pode ser amplamente melhorada, mas pode fornecer um ponto de partida:

$(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');
    }
});
dgabriel
fonte
nice one bud, sua solução pode ser adicionada no joomla 30 core, joomlacode.org/gf/project/joomla/tracker/…
Benn
12
é melhor usar em $(this).attr('href')vez de $(e.target).attr('id')fornecer o hash sem o url completo. Você também deve aplicar o .tab()na tag a com data-toggle="tab"em vez de $('#'+lastTab). Veja também: stackoverflow.com/questions/16808205/…
Bass Jobsen
3
Parece que o método mudou ligeiramente no Bootstrap 3. shownnão parece mais funcionar, tive que mudá-lo para shown.bs.tab. Nota: Eu entendo javascript e outros tão bem quanto entendo de economia ... então, alguém que sabe o que está acontecendo sinta-se à vontade para me corrigir.
Chaz
10
Modificado para funcionar com vários controles de guia (e Bootstrap 3): gist.github.com/brendanmckenzie/8f8008d3d51c07b2700f
Brendan
1
Vai para a primeira guia e volta para a guia atual após a atualização
Raviteja
23

Fiz isso funcionar usando cookies e também removendo a classe 'ativa' de quaisquer outras guias e painéis de guia ... e adicionando a classe 'ativa' à guia e painel de guias atuais.

Tenho certeza de que há uma maneira melhor de fazer isso, mas parece funcionar neste caso.

Requer o plugin de cookie jQuery.

$(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');
  }
});
ricsrock
fonte
Não consegui fazer com que a solução localStorage funcionasse, embora parecesse lógico. Esta solução pronta para uso e o plugin $ .cookie são MUITO úteis de se ter.
Michael J. Calkins
aplique .tab () em uma tag com data-toggle = "tab" em vez de remover e adicionar classes, consulte também: stackoverflow.com/questions/16808205/…
Bass Jobsen
Para meu layout, porque eu estava usando 'fade in active' para os divs, precisei alterar as duas últimas linhas para adicionar ou remover 'in active'.
Obromios
18

Todas as outras respostas estão corretas. Essa resposta levará em consideração o fato de que se pode ter vários ul.nav.nav-pillsou ul.nav.nav-tabsna mesma página. Nesse caso, as respostas anteriores falharão.

Ainda usando, localStoragemas com um stringified JSONcomo valor. Aqui está o código:

$(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");
    }
  });
});

Este bit pode ser usado em todo o aplicativo em todas as páginas e funcionará com guias e pílulas. Além disso, certifique-se de que as guias ou pílulas não estejam ativas por padrão , caso contrário, você verá um efeito de oscilação no carregamento da página.

Importante : verifique se o pai / mãe ultem uma identificação. Obrigado Alain

Oktav
fonte
2
Além disso, para BS3, substitua o evento 'mostrado' por 'mostrado.bs.tab'
Alain
18

Para a melhor opção, use esta técnica:

$(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();
  }
});
Vaimeo
fonte
12

Eu prefiro armazenar a guia selecionada no hashvalue da janela. Isso também permite o envio de links para colegas, que então verão "a mesma" página. O truque é alterar o hash do local quando outra guia for selecionada. Se você já usa # em sua página, possivelmente a hashtag deve ser dividida. No meu aplicativo, eu uso ":" como separador de valor hash.

<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>
koppor
fonte
Obrigado por esta resposta. Funciona bem para mim e eu não queria lidar com cookies apenas para esse problema, então é ótimo.
nico008
@koppor, isso não funciona, há um evento de postback. Eu adicionei o <asp:LinkButton CssClass="form-search" ID="LinkButtonSearch" runat="server">Search</asp:LinkButton> botão do link , depois de clicar no botão, é a guia padrão que se torna ativa, não a guia atual. como posso consertar isso?
Djama de
6

Para evitar que a página pisque na primeira guia e depois na guia que foi salva pelo cookie (isso ocorre quando você determina a classe "ativa" por padrão na primeira TAB)

Remova a classe "ativa" de guias e painéis como:

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

Coloque o script abaixo para definir a primeira guia como padrão (requer o plugin de cookie jQuery)

    $(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');
        }
    });
Jeferson Tenorio
fonte
3

Quer efeito de esmaecimento? Versão atualizada do código de @ Oktav:

  1. Para Bootstrap 3
  2. Configura as classes no li e div da guia para permitir que o esmaecimento funcione corretamente. Observe que todos os divs de conteúdo precisamclass="tab-pane fade"

Código:

// 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");
    }
  });
});
Larry K
fonte
3

Eu tinha abas em várias páginas e localStorage mantém o lastTab das páginas anteriores também, então para a próxima página, uma vez que ele tinha o lastTab da página anterior armazenado, não encontrou nenhuma aba correspondente aqui, então nada estava sendo exibido. Eu modifiquei dessa forma.

$(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');
    }
})

editar: notei que terei que ter lastTabnomes de variáveis ​​diferentes para páginas diferentes, caso contrário, eles sempre sobrescreverão uns aos outros. por exemplo lastTab_klanten, lastTab_bestellingenetc. para duas páginas diferentes klantene bestellingenambas com dados exibidos em guias.

$(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');
    }
})
GoharSahi
fonte
3

Fiz funcionar com solução semelhante ao @dgabriel, neste caso, os links <a>não precisam id, ele identifica a aba atual com base na posição.

$(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');
  }
});
Jaider
fonte
Eu acho que seu código está errado em torno de getItem deve ser mostrado antes de mostrar, também resolve o problema de declarar indexTab duas vezes.
John Magnolia,
@JohnMagnolia eu nomeei indexTabduas vezes, mas é um diff. índice. Então, vou ligar para o segundo lastIndexTab. Em relação a shown, isso é um evento, então não será disparado até que você abra uma guia, então não importa se é antes getItem.
Jaider
1

Eu sugiro as seguintes mudanças

  1. Use um plug-in como amplify.store que fornece uma API de armazenamento local crossbrowser / crossplatform com fallbacks integrados.

  2. Direcione a guia que precisa ser salva $('#div a[data-toggle="tab"]')para estender essa funcionalidade a vários contêineres de guia que existem na mesma página.

  3. Use um identificador exclusivo (url ??)para salvar e restaurar as últimas guias usadas em várias páginas.


$(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');
  }
});
Sandeep
fonte
1

Solução simples sem armazenamento local:

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

Abordagem do lado do servidor. Certifique-se de que todos os elementos html tenham class = "" caso não seja especificado ou você precisará lidar com nulos.

    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";
        }
    }
Michael Goldshmidt
fonte
0

Se você quiser mostrar a primeira guia na primeira vez que entrar na página, use este código:

    <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>

ruben
fonte
0

Aqui está um trecho que fiz que funciona com Bootstrap 3 e jQuery e com URLs diferentes contendo guias diferentes . Ele não oferece suporte a várias guias por página, mas deve ser uma modificação fácil se você precisar desse recurso.

/**
 * 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();

    }

});
Cjohansson
fonte
0

$ (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" });

            }  
        });

});

Dinesh Patidar
fonte
0

se você tiver mais de uma guia na página, pode usar o seguinte código

<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>
Mohamed Sami
fonte
0

Isso irá atualizar as guias, mas somente depois que tudo no controlador for carregado.

// >= 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');
});
PHPGuru
fonte
0

Estou usando isso com MVC:

  • Existe um campo inteiro SelectedTab no modelo para enviar o valor para o método POST

Seção JavaScript:

<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>

Seção HTML:

@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>
}
Carlos toledo
fonte