¿Cómo mantengo activa la pestaña actual con twitter bootstrap después de una recarga de página?

87

Actualmente estoy usando pestañas con Twitter Bootstrap y quiero seleccionar la misma pestaña después de que un usuario haya publicado datos y la página se vuelva a cargar.

¿Cómo se hace esto?

Mi llamada actual para inti las pestañas se ve así:

<script type="text/javascript">

$(document).ready(function() {

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

Mis pestañas:

<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>
Paul
fuente
1
Esta parece ser una pregunta duplicada para stackoverflow.com/questions/18999501/…
koppor
relacionado con stackoverflow.com/questions/7862233/…
Tim Abell

Respuestas:

138

Tendrá que usar localStorage o cookies para administrar eso. Aquí hay una solución rápida y sucia que se puede mejorar enormemente, pero que puede darle un punto 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
fuente
buen amigo, su solución podría agregarse en joomla 30 core, joomlacode.org/gf/project/joomla/tracker/…
Benn
12
mejor uso en $(this).attr('href')lugar de lo $(e.target).attr('id')que le da el hash sin la URL completa. También debe aplicar la .tab()etiqueta data-toggle="tab"en a con en lugar de $('#'+lastTab). Ver también: stackoverflow.com/questions/16808205/…
Bass Jobsen
3
Parece que el método cambia ligeramente en Bootstrap 3. shownya no parece funcionar, tuve que cambiarlo a shown.bs.tab. Nota: Entiendo javascript et al tan bien como entiendo economía ... así que alguien que sepa lo que pasa, no dude en corregirme.
Chaz
10
Modificado para trabajar con múltiples controles de pestañas (y Bootstrap 3): gist.github.com/brendanmckenzie/8f8008d3d51c07b2700f
Brendan
1
Va a la primera pestaña y vuelve a la pestaña actual después de la actualización
Raviteja
23

Consiguió que esto funcione usando cookies y también eliminando la clase 'activa' de cualquier otra pestaña y panel de pestañas ... y agregando la clase 'activa' a la pestaña actual y al panel de pestañas.

Estoy seguro de que hay una mejor manera de hacer esto, pero parece funcionar en este caso.

Requiere el complemento de cookies 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
fuente
No pude hacer que la solución localStorage funcionara a pesar de que parecía lógico. Esta solución lista para usar y el complemento $ .cookie es MUY útil.
Michael J. Calkins
aplique .tab () en la etiqueta a con data-toggle = "tab" en lugar de eliminar y agregar clases, consulte también: stackoverflow.com/questions/16808205/…
Bass Jobsen
Para mi diseño, debido a que estaba usando 'fade in active' para los divs, necesitaba cambiar las últimas dos líneas para agregar o eliminar 'in active'.
Obromios
18

Todas las demás respuestas son correctas. Esta respuesta tendrá en cuenta el hecho de que uno puede tener múltiples ul.nav.nav-pillso ul.nav.nav-tabsen la misma página. En este caso, las respuestas anteriores fallarán.

Todavía se usa localStoragepero con una cadena JSONcomo valor. Aquí está el 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 se puede usar en toda la aplicación en todas las páginas y funcionará tanto para pestañas como para píldoras. Además, asegúrese de que las pestañas o píldoras no estén activas de forma predeterminada ; de lo contrario, verá un efecto de parpadeo al cargar la página.

Importante : asegúrese de que el padre ultenga una identificación. Gracias alain

Oktav
fuente
2
Además, para BS3, reemplace el evento 'mostrado' con 'shown.bs.tab'
Alain
18

Para obtener la mejor opción, 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
fuente
12

Prefiero almacenar la pestaña seleccionada en el valor hash de la ventana. Esto también permite enviar enlaces a colegas, que ven "la misma" página. El truco consiste en cambiar el hash de la ubicación cuando se selecciona otra pestaña. Si ya usa # en su página, posiblemente la etiqueta hash deba dividirse. En mi aplicación, 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
fuente
Gracias por esta respuesta. Funciona bien para mí y no quería lidiar con cookies solo por este problema, así que es genial.
nico008
@koppor, esto no funciona, hay un evento de devolución de datos. Agregué <asp:LinkButton CssClass="form-search" ID="LinkButtonSearch" runat="server">Search</asp:LinkButton> el botón de enlace , después de hacer clic en el botón, es la pestaña predeterminada la que se activa, no la pestaña actual. ¿Cómo puedo arreglar eso?
Djama
6

Para evitar que la página parpadee en la primera pestaña y luego en la pestaña que guardó la cookie (esto ocurre cuando se determina la clase "activa" por defecto en la primera PESTAÑA)

Elimina la clase "activa" de pestañas y paneles como:

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

Coloque el siguiente script para configurar la primera pestaña como predeterminada (Requiere el complemento de cookies 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
fuente
3

¿Quieres un efecto de desvanecimiento? Versión actualizada del código de @ Oktav:

  1. Para Bootstrap 3
  2. Configura las clases en el div li y tab para permitir que el desvanecimiento funcione correctamente. Tenga en cuenta que todos los divs de contenido necesitanclass="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
fuente
3

Tenía pestañas en varias páginas y localStorage también mantiene lastTab de las páginas anteriores, por lo que para la página siguiente, dado que tenía la lastTab de la página anterior almacenada, no encontró ninguna pestaña coincidente aquí, por lo que no se mostraba nada. Lo modifiqué de esta manera.

$(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: He notado que tendré que tener diferentes lastTabnombres de variable para diferentes páginas, de lo contrario, siempre se sobrescribirán entre sí. por ejemplo lastTab_klanten, lastTab_bestellingenetc. para dos páginas diferentes klanteny bestellingenambas con datos mostrados en pestañas.

$(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
fuente
3

Hice que funcionara con una solución similar a @dgabriel, en este caso, los enlaces <a>no necesitan id, identifica la pestaña actual en función de la posición.

$(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
fuente
Creo que su código está equivocado antes de que se muestre getItem, también soluciona el problema de declarar indexTab dos veces.
John Magnolia
@JohnMagnolia Lo nombré indexTabdos veces pero es una diferencia. índice. Así que llamaré al segundo lastIndexTab. Con respecto a shown, eso es un evento, por lo que no se activará hasta que abra una pestaña, por lo que no importa si fue antes getItem.
Jaider
1

Sugiero los siguientes cambios

  1. Utilice un complemento como amplify.store, que proporciona una API de almacenamiento local entre navegadores / plataformas cruzadas con alternativas integradas.

  2. Apunte a la pestaña que debe guardarse $('#div a[data-toggle="tab"]')como para extender esta funcionalidad a varios contenedores de pestañas que existen en la misma página.

  3. Utilice un identificador único (url ??)para guardar y restaurar las últimas pestañas utilizadas en varias 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
fuente
1

Solución simple sin almacenamiento local:

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

Enfoque del lado del servidor. Asegúrese de que todos los elementos html tengan class = "" en caso de que no se especifique o necesitará manejar 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
fuente
0

Si desea mostrar la primera pestaña la primera vez que ingresa a la 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
fuente
0

Aquí hay un fragmento que hice que funciona con Bootstrap 3 y jQuery y con diferentes URL que contienen diferentes pestañas . Sin embargo, no admite varias pestañas por página, pero debería ser una modificación fácil si necesita esa función.

/**
 * 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
fuente
0

$ (documento) .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
fuente
0

si tiene más de una pestaña en la página, puede usar el siguiente 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
fuente
0

Esto actualizará las pestañas, pero solo después de que se cargue todo en el controlador.

// >= 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
fuente
0

Estoy usando esto con MVC:

  • Hay un campo entero SelectedTab en el modelo para enviar el valor al método POST

Sección de 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>

Sección 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
fuente