Ginodavecte
Ginodavecte

Reputation: 3

Make tabs inside tabs with JavaScript without jQuery

I have a javascript function to have tabs. And now I want to have tabs within one of the tabs. But everytime I click on one of the tabs within that specific tab, everything disapears. It is because the javascript function I use sets the style.display to none.

What I want is that when inside POP is clicked on doel1 or doel2 or doel3 that the style.display of POP stays active.

Here is my javascript function (it's from w3school.com):

function openTab(evt, openTab) {
  var i, tabcontent, tablinks;
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  document.getElementById(openTab).style.display = "block";
  evt.currentTarget.className += " active";
}
.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}

.tab button:hover {
  background-color: #ddd;
}

.tab button.active {
  background-color: #ccc;
}

.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}
<div class="tab">
  <button class="tablinks" onclick="openTab(event, 'bla')">bla</button>
  <button class="tablinks" onclick="openTab(event, 'blabla')">blabla</button>
  <button class="tablinks" onclick="openTab(event, 'pop')">POP</button>
</div>

<div id="bla" class="tabcontent">
  <h2>bla</h2>
  <table>
    <tr>
      <td>My stuff that works :)</td>
    </tr>
  </table>
</div>
<div id="blabla" class="tabcontent">
  <h3>blabla</h3>
  <table>
    <tr>
      <td>My stuff that works ;)</td>
    </tr>
  </table>
</div>

<div id="pop" class="tabcontent">
  <h1>POP</h1>
  <div class="tab">
    <button class="tablinks" onclick="openTab(event, 'doel1')">Doel 1</button>
    <button class="tablinks" onclick="openTab(event, 'doel2')">Doel 2</button>
    <button class="tablinks" onclick="openTab(event, 'doel3')">Doel 3</button>
  </div>
  <div id="doel1" class="tabcontent">
    My stuff that doesn't show when I want :(
  </div>
</div>

Upvotes: 0

Views: 2056

Answers (3)

Ginodavecte
Ginodavecte

Reputation: 3

function openTab(evt, openTab, subTab) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks");

    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    if(subTab) {
      var parent = evt.currentTarget.closest('.tabcontent');
      parent.style.display = "block";
      parent.className += " active";
    }
    document.getElementById(openTab).style.display = "block";
    evt.currentTarget.className += " active";

}
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}


.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
}


.tab button:hover {
background-color: #ddd;
}


.tab button.active {
background-color: #ccc;
}

.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
<div class="tab">
    <button class="tablinks" onclick="openTab(event, 'bla')">bla</button>
    <button class="tablinks" onclick="openTab(event, 'blabla')">blabla</button>
    <button class="tablinks" onclick="openTab(event, 'pop')">POP</button>
</div>

<div id="bla" class="tabcontent">
    <h2>bla</h2>
    <table>
        <tr><td>My stuff that works :)</td></tr>
    </table>
</div>
<div id="blabla" class="tabcontent">
    <h3>blabla</h3>
    <table>
        <tr><td>My stuff that works ;)</td></tr>
    </table>
</div>

<div id="pop" class="tabcontent">
    <h1>POP</h1>
    <div class="tab">
        <button class="tablinks" onclick="openTab(event, 'doel1',true)">Doel 1</button>
        <button class="tablinks" onclick="openTab(event, 'doel2', true)">Doel 2</button>
        <button class="tablinks" onclick="openTab(event, 'doel3', true)">Doel 3</button>
    </div>
    <div id="doel1" class="tabcontent">
        My stuff that doesn't show when I  want :(
    </div>

    <div id="doel2" class="tabcontent">
        My stuff doel2
    </div>

    <div id="doel3" class="tabcontent">
        My stuff doel3
    </div>
</div>
Thnx :)

Upvotes: 0

Rick
Rick

Reputation: 997

I've had a stab at it here, the basic change is targeting the tabs you want to alter:

html:

<div class="tabs">
  <ul>
    <li>
      <button class="tablink active" onclick="openTab(event, 'tab1', 'parent')">
        Tab 1
      </button>
    </li>
    <li>
      <button class="tablink" onclick="openTab(event, 'tab2', 'parent')">
        Tab 2
      </button>
    </li>
    <li>
      <button class="tablink" onclick="openTab(event, 'tab3', 'parent')">
        Tab 3
      </button>
    </li>
  </ul>
</div>

<div id="tab1" class="parent active">
  <h2>Tab 1</h2>
</div>

<div id="tab2" class="parent">
  <h2>Tab 2</h2>
</div>

<div id="tab3" class="parent">
  <h2>Tab 3</h2>
  <div class="tabs">
    <ul>
      <li>
        <button class="subtablink active" onclick="openTab(event, 'tab1', 'child')">
          Tab 3a
        </button>
      </li>
      <li>
        <button class="subtablink" onclick="openTab(event, 'tab2', 'child')">
          Tab 3b
        </button>
      </li>
    </ul>
  </div>

  <div id="tab1" class="child active">
    <h2>Tab 3a</h2>
  </div>

  <div id="tab2" class="child">
    <h2>Tab 3b</h2>
  </div>

</div>

CSS:

.parent, .child {
  display:none;
}

.parent.active, .child.active {
  display: block;
}

.tablink.active, .subtablink.active {
  background: red;
}

Javascript:

function openTab(event, tab, set) {
  // Hide all tabs in scope
  const className = '.' + set;
  document.querySelectorAll(className).forEach(function(item) {
    item.className = set;
  });

  // Show selected tab
  const fullPath = className + '#' + tab;
  document.querySelector(fullPath).classList.add('active');

  // Set Tab to active (and deactivate others)
  const siblingClass = event.target.className;
  document.querySelectorAll('.' + siblingClass).forEach(function(item) {
    item.classList.remove('active');
  });
  event.target.classList.add('active');
}

I've just added the basic of styling here. Here it is in action: https://codepen.io/anon/pen/VyzWPQ

Just for clarity, the tab navigation links have their own classes (tablink & subtablink) depending on their scope, you can of course name them whatever you want, you'll need to if you have sub tabs in another parent tab. The javascript uses this to unset the active class on siblings when a button is clicked.

Upvotes: 0

cdoshi
cdoshi

Reputation: 2832

See if this fits you as a solution, what I have done is added another parameter to the function that indicates if it is a sub tab. If it is, keep parent active and make the child active as well

function openTab(evt, openTab, subTab) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks");

    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    if(subTab) {
      var parent = evt.currentTarget.closest('.tabcontent');
      parent.style.display = "block";
      parent.className += " active";
    }
    document.getElementById(openTab).style.display = "block";
    evt.currentTarget.className += " active";

}
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}


.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
}


.tab button:hover {
background-color: #ddd;
}


.tab button.active {
background-color: #ccc;
}

.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
<div class="tab">
    <button class="tablinks" onclick="openTab(event, 'bla')">bla</button>
    <button class="tablinks" onclick="openTab(event, 'blabla')">blabla</button>
    <button class="tablinks" onclick="openTab(event, 'pop')">POP</button>
</div>

<div id="bla" class="tabcontent">
    <h2>bla</h2>
    <table>
        <tr><td>My stuff that works :)</td></tr>
    </table>
</div>
<div id="blabla" class="tabcontent">
    <h3>blabla</h3>
    <table>
        <tr><td>My stuff that works ;)</td></tr>
    </table>
</div>

<div id="pop" class="tabcontent">
    <h1>POP</h1>
    <div class="tab">
        <button class="tablinks" onclick="openTab(event, 'doel1',true)">Doel 1</button>
        <button class="tablinks" onclick="openTab(event, 'doel2', true)">Doel 2</button>
        <button class="tablinks" onclick="openTab(event, 'doel3', true)">Doel 3</button>
    </div>
    <div id="doel1" class="tabcontent">
        My stuff that doesn't show when I  want :(
    </div>

    <div id="doel2" class="tabcontent">
        My stuff doel2
    </div>

    <div id="doel3" class="tabcontent">
        My stuff doel3
    </div>
</div>

Upvotes: 1

Related Questions