Comment puis-je garder l'onglet actuel actif avec le bootstrap Twitter après le rechargement d'une page?


87

J'utilise actuellement des onglets avec Twitter Bootstrap et je souhaite sélectionner le même onglet après qu'un utilisateur a publié des données et que la page se recharge.

Comment cela se fait-il?

Mon appel actuel à inti les onglets ressemble à ceci:

<script type="text/javascript">

$(document).ready(function() {

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

Mes onglets:

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

1
Cela semble être une question en double à stackoverflow.com/questions/18999501/…
koppor

Réponses:


138

Vous devrez utiliser localStorage ou des cookies pour gérer cela. Voici une solution rapide et sale qui peut être considérablement améliorée, mais qui peut vous donner un point de départ:

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

nice one bud, votre solution pourrait être ajoutée dans joomla 30 core, joomlacode.org/gf/project/joomla/tracker/…
Benn

12
mieux utiliser $(this).attr('href')au lieu de $(e.target).attr('id')qui vous donne le hachage sans l'URL complète. Vous devez également appliquer le .tab()sur la balise a data-toggle="tab"au lieu de $('#'+lastTab). Voir aussi: stackoverflow.com/questions/16808205/…
Bass Jobsen

3
Il semble que la méthode change légèrement dans Bootstrap 3. shownne semble plus fonctionner, a dû la changer en shown.bs.tab. Note: Je comprends javascript et al ainsi que je comprends l'économie ... donc quelqu'un qui sait ce qui se passe, n'hésitez pas à me corriger.
Chaz

10
Modifié pour fonctionner avec plusieurs contrôles d'onglet (et Bootstrap 3): gist.github.com/brendanmckenzie/8f8008d3d51c07b2700f
Brendan

1
Il va au premier onglet et revient à l'onglet actuel après actualisation
Raviteja

23

Cela fonctionne en utilisant des cookies et en supprimant également la classe `` active '' de tous les autres onglets et volets d'onglets ... et en ajoutant la classe `` active '' à l'onglet et au volet d'onglets actuels.

Je suis sûr qu'il existe une meilleure façon de faire cela, mais cela semble fonctionner dans ce cas.

Nécessite le 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');
  }
});

Je n'ai pas pu faire fonctionner la solution localStorage même si cela semblait logique. Cette solution prête à l'emploi et le plugin $ .cookie sont TRÈS pratiques à avoir.
Michael J.Calkins

appliquer .tab () sur la balise a avec data-toggle = "tab" au lieu de supprimer et d'ajouter des classes voir aussi: stackoverflow.com/questions/16808205/...
Bass Jobsen

Pour ma mise en page, parce que j'utilisais «fondu en actif» pour les divs, je devais changer les deux dernières lignes pour ajouter ou supprimer «en actif».
Obromios

18

Toutes les autres réponses sont correctes. Cette réponse tiendra compte du fait que l'on peut en avoir plusieurs ul.nav.nav-pillsou ul.nav.nav-tabssur la même page. Dans ce cas, les réponses précédentes échoueront.

Toujours en utilisant localStoragemais avec un stringified JSONcomme valeur. Voici le 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");
    }
  });
});

Ce bit peut être utilisé sur l'ensemble de l'application sur toutes les pages et fonctionnera à la fois pour les onglets et les pilules. Assurez-vous également que les onglets ou les pilules ne sont pas actifs par défaut , sinon vous verrez un effet de scintillement au chargement de la page.

Important : assurez-vous que le parent ula un identifiant. Merci Alain


2
Aussi, pour BS3, remplacez l'événement 'montré' par 'shown.bs.tab'
Alain

18

Pour la meilleure option, utilisez cette 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();
  }
});

12

Je préfère stocker l'onglet sélectionné dans la valeur de hachage de la fenêtre. Cela permet également d'envoyer des liens à des collègues, qui voient alors «la même» page. L'astuce consiste à changer le hachage de l'emplacement lorsqu'un autre onglet est sélectionné. Si vous utilisez déjà # dans votre page, la balise de hachage doit peut-être être divisée. Dans mon application, j'utilise ":" comme séparateur de valeur de hachage.

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

Merci pour cette réponse. Cela fonctionne bien pour moi et je ne voulais pas traiter les cookies uniquement pour ce problème, donc c'est génial.
nico008

@koppor, cela ne fonctionne pas, il y a un événement de publication. J'ai ajouté le linkbutton <asp:LinkButton CssClass="form-search" ID="LinkButtonSearch" runat="server">Search</asp:LinkButton> , après avoir cliqué sur le bouton, c'est l'onglet par défaut qui devient actif et non l'onglet actuel. comment puis-je résoudre ce problème?
Djama

6

Pour éviter que la page ne clignote sur le premier onglet, puis sur l'onglet qui a été enregistré par le cookie (cela se produit lorsque vous déterminez la classe "active" par défaut dans le premier onglet)

Supprimez la classe "active" des onglets et des volets comme:

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

Mettez le script ci-dessous pour définir le premier onglet comme par défaut (nécessite le 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');
        }
    });

3

Vous voulez un effet de décoloration? Version mise à jour du code de @ Oktav:

  1. Pour Bootstrap 3
  2. Configure les classes sur le div li et tab pour permettre à la décoloration de fonctionner correctement. Notez que tous les contenus divs ont besoinclass="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");
    }
  });
});

3

J'avais des onglets dans plusieurs pages et localStorage conserve également lastTab des pages précédentes, donc pour la page suivante, comme il y avait le dernierTab de la page précédente en stockage, il n'a trouvé aucun onglet correspondant ici, donc rien n'était affiché. Je l'ai modifié de cette façon.

$(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: J'ai remarqué que je devrais avoir lastTabdes noms de variables différents pour différentes pages, sinon, ils se remplaceront toujours. par exemple lastTab_klanten, lastTab_bestellingenetc. pour deux pages différentes klantenet les bestellingendeux ayant des données affichées dans des onglets.

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

3

Je l'ai fait fonctionner avec une solution similaire à @dgabriel, dans ce cas, les liens <a>n'ont pas besoin id, il identifie l'onglet actuel en fonction de la 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');
  }
});

Je pense que votre code est faux autour de getItem devrait être avant montré, résout également le problème de la déclaration d'indexTab deux fois.
John Magnolia

@JohnMagnolia J'ai nommé le indexTabdeux fois mais c'est un diff. indice. J'appellerai donc le 2ème lastIndexTab. En ce qui concerne shown, c'est un événement, donc il ne se déclenchera pas tant que vous n'aurez pas ouvert un onglet, donc peu importe si c'est avant getItem.
Jaider

1

Je suggère les changements suivants

  1. Utilisez un plugin comme amplify.store qui fournit une API de stockage local crossbrowser / crossplatform avec des solutions de secours intégrées.

  2. Ciblez l'onglet qui doit être enregistré de $('#div a[data-toggle="tab"]')manière à étendre cette fonctionnalité à plusieurs conteneurs d'onglets qui existent sur la même page.

  3. Utilisez un identifiant unique (url ??)pour enregistrer et restaurer les derniers onglets utilisés sur plusieurs 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');
  }
});

1

Solution simple sans stockage local:

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

0

Approche côté serveur. Assurez-vous que tous les éléments html ont class = "" au cas où non spécifié ou vous aurez besoin de gérer des valeurs nulles.

    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";
        }
    }

0

Si vous souhaitez afficher le premier onglet la première fois que vous entrez dans la page, utilisez ce 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>


0

Voici un extrait que j'ai créé qui fonctionne avec Bootstrap 3 et jQuery et avec différentes URL contenant différents onglets . Cependant, il ne prend pas en charge plusieurs onglets par page, mais cela devrait être une modification facile si vous avez besoin de cette fonctionnalité.

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

    }

});

0

$ (document) .ready (fonction () {

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

            }  
        });

});


0

si vous avez plus d'un onglet dans la page, vous pouvez utiliser le code suivant

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

0

Cela rafraîchira les onglets, mais seulement après que tout dans le contrôleur est chargé.

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

0

J'utilise ceci avec MVC:

  • Il existe un champ entier SelectedTab dans le modèle pour envoyer la valeur à la méthode POST

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

Section 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>
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.