1

Using different level of tabs to display lots of information. I have 2 level of tabs. 1st Level is the main category. 2nd Level is the sub category.

Currently when I pass the href of level 1 tab from a different page I'm navigated to the specific tab. What I want to achieve is clicking on a button from a different page and get navigated to the 2nd level of tab directly.

For example: Consider 2 main tabs (Level 1 tabs) Marvel and DC
Hulk and Spider-Man are 2 tabs under Marvel Tab
Super Man and Batman are 2 tabs under DC tab

What I want to achieve is, If I place a button of Batman on different page on clicking it directs me to Batman tab of DC category.

My code is as follows:

<!--Level 1 tabs-->
    <a href="#marvel" data-toggle="tab">Marvel</a>
    <a href="#dc" data-toggle="tab">dc</a>

    <!--Level 1 content-->

    <div class="tab-content">
      <div class="tab-pane fade in active" id="marvel">

    <!--Level 2 tabs-->
    <ul class="nav nav-pills nav-stacked col-md-2">
       <li class="active><a href="#marvel_1" data-toggle="pill">Hulk</a></li>
      <li><a href="#marvel_2" data-toggle="pill">SpiderMan</a></li>
    </ul>

  <!--Level 2 Container-->
        <div class="tab-pane active" id="marvel_1">
            <p>The Hulk Tab!</p>
        </div>

        <div class="tab-pane" id="marvel_2">
            <p>The Spiderman Tab!</p>
        </div>
   </div> <!--End: Marvel Main Tab-->
 </div> <!--End: Tab Content-->

   <div class="tab-content">
      <div class="tab-pane fade in" id="dc">

    <!--Level 2 tabs-->
    <ul class="nav nav-pills nav-stacked col-md-2">
       <li class="active><a href="#dc_1" data-toggle="pill">Superman</a></li>
      <li><a href="#dc_2" data-toggle="pill">Batman</a></li>
    </ul>

  <!--Level 2 Container-->
        <div class="tab-pane active" id="dc_1">
            <p>The SuperMan Tab!</p>
        </div>

        <div class="tab-pane" id="dc_2">
            <p>The Batman Tab!</p>
        </div>
   </div> <!--End: DC Main Tab-->

From a different page when I click on

   <a href="description.html#marvel">Marvel</a>

Where description.html is the page containing tabs. jQuery on description page:

  <script>
    $(function () {
       var activeTab = $('[href=' + location.hash + ']');
       activeTab && activeTab.tab('show');
    });
    </script>

Takes to the specific Marvel or Dc tab from a different page. What I'm looking to achieve is going to Spiderman tab or batman tab under DC tab directly.

Summary: Currently navigating to Level 1 of Tabs from different page want to get to 2nd Level directly from a different page.

Consider:

-Marvel
--Hulk
--SpiderMan

-DC
--Superman
--Batman
Currently going to dc tab directly through anchorlink from a different page want to navigate to Batman directly

Luca Kiebel
  • 9,790
  • 7
  • 29
  • 44

1 Answers1

0

usually you would want to use url variables instead of the location hash, to achieve that. but the downside is, that then, browser history doesn't recognize you cycling through the different hero pages (enabling you to use forward/backward buttons). so you would have to create additional code to make this working.

so here's a solution, where we 'store' all needed information within the location hash. to make parsing easier, we use special characters as separators (which happens to be the same, as if you'd use url variables): & to distinct between the different variables and = to separate the key, value pairs. the new location hash would look like: #universe=dc&hero=aquaman

the script will convert this into an object with the name selectedHero, so that the values are accessible with selectedHero.universe and selectedHero.hero

as usual, the code is placed within the $( document ).ready(function(){ function.

create a function to read the location hash and return the data as an object.

  function getSelectedHero() {
      var mySelectedHero = {}; //initialize a new empty object
      var currentLocationHashValue = window.location.hash //read the location hash 
        .replace("#", "") //trim the '#' out of the string
        .split(/[&]+/); //split the string into an array

      $(currentLocationHashValue).each(function() { //loop through the freshly created array
        mySelectedHero[this.split(/[=]+/)[0]] = this.split(/[=]+/)[1]; //split the string into key/value pairs and assign them to the object, created at the beginning of the function 
      });
      return mySelectedHero; //return the object
    }

we have to major parts here. the first one splits the hash from #universe=dc&hero=aquaman into an array with [0]="universe=dc" and [1]="hero=aquaman" in the second part, we cycle through all array elements (in this case there are only the two, mentioned above) and split them again, creating key -> value pairs for the desired object. the return delivers the following object:

object{ universe: "dc", hero: "aquaman" }

this can now easily be used, to choose the right tab for the chosen hero

    function showSelectedHeroTab(selectedHero) {
      //don't forget to 'reset' the page, hiding all currently visible tabs
      $(".universe").hide();
      $(".hero").hide();

      //then open tab for selected hero
      $("#" + selectedHero.universe).show();
      $("#" + selectedHero.hero).show();
    }

this is pretty straight forward, the function gets the object passed, so you can access the values, then you build your jquery selector with "#"+ and your variable name.

when including only the above functions, nothing would happen. so we initially have to call the functions:

    var selectedHero = getSelectedHero();
    showSelectedHeroTab(selectedHero);

and additionally, we want to 'update' the page, whenever the location hash changes:

    $(window).on("hashchange", function() {
      var selectedHero = getSelectedHero();
      showSelectedHeroTab(selectedHero);
    }); 

this code completely misses some kind of error handling. so, if the location hash is empty, the universe/hero pair doesn't match (e.g. marvel+batman) - so you'd have to add some kind of logic to forward to a default tab, when the data is unusable!

for testing purposes, i created a standalone html page, so this looks different to your markup, but i guess, you'll figure out how to move the needed parts into your code.

here's the complete file, including html markup, script and jquery cdn. just copy&paste into an empty file, open with browser and see it'working...

<html>
<body>
    <div id="header">
        <p>
          <a href="#universe=dc&hero=superman">superman</a>
          <a href="#universe=dc&hero=batman">batman</a>
          <a href="#universe=dc&hero=aquaman">aquaman</a>
          <a href="#universe=dc&hero=flash">flash</a>
        </p>
        <p>
          <a href="#universe=marvel&hero=hulk">the hulk</a>
          <a href="#universe=marvel&hero=wolverine">wolverine</a>
          <a href="#universe=marvel&hero=ironman">iron man</a>
          <a href="#universe=marvel&hero=spiderman">spiderman</a>
        </p>
    </div>

<div id="body">
    <div id="marvel" class="universe">marvel: <br/>
        <div class="hero" id="hulk">
            hulk
        </div>
        <div class="hero" id="ironman">
            ironman
        </div>
        <div class="hero" id="wolverine">
            wolverine
        </div>
        <div class="hero" id="spiderman">
            spiderman
        </div>
    </div>
    <div id="dc" class="universe">dc: <br/>
        <div class="hero" id="superman">
            superman
        </div>
        <div class="hero" id="batman">
            batman
        </div>
        <div class="hero" id="aquaman">
            aquaman
        </div>
        <div class="hero" id="flash">
            flash
        </div>
    </div>
</div>

</body>

<script
    src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="crossorigin="anonymous">
</script>

<script>
    $( document ).ready(function() {            

        // we create a function to get the location hash 'data' as an object
        function getSelectedHero() {
          var mySelectedHero = {}; //initialize a new empty object
          var currentLocationHashValue = window.location.hash //read the location hash -> e.g. "#universe=dc&hero=batman"
            .replace("#", "") //trim the '#' out of the string -> "universe=dc&hero=batman"
            .split(/[&]+/) //split the string into an array -> [0]="universe=dc" [2]="hero=batman"
          $(currentLocationHashValue).each(function() { //loop through the freshly created array
            mySelectedHero[this.split(/[=]+/)[0]] = this.split(/[=]+/)[1]; //split the string into key/value pairs and assign them to the object, created at the beginning of the function 
          });
          return mySelectedHero; //return the object
        }

        // and we create a function, that opens the desired tab
        function showSelectedHeroTab(selectedHero) {
          //first make sure, nothing is shown 
          $(".universe").hide();
          $(".hero").hide();

          //then open tab for selected hero
          $("#" + selectedHero.universe).show();
          $("#" + selectedHero.hero).show();
          console.log (selectedHero);
        }

        //then we initally call the functions, to read the hash and show the tab 
        var selectedHero = getSelectedHero();
        showSelectedHeroTab(selectedHero);

        // additionally bind the event handler 'onhashchange' to fire when the location hash changes, to call the first two functions
        $(window).on("hashchange", function() {
        var selectedHero = getSelectedHero();
        showSelectedHeroTab(selectedHero);
        }); 
    });
</script>   
</html>
errand
  • 980
  • 1
  • 7
  • 18