bad_at_code bad_at_code - 26 days ago 9
CSS Question

Multiple Tabbed Areas On One Page (Pure Javascript)

I have this Codepen going.

Overview:

There are two divs, "code-box-1" and "code-box-2"

Each div has three pre elements and three buttons within.

The buttons act as tabs, toggling visibility of their corresponding pre element via an onClick() function called openTab()

Lastly, I am using .click() to toggle a tab on by default on page load.

Problem:

The problem is, I don't know how to scope my function to treat each menu separately.

As it stands, clicking a button targets the correct pre element when toggling visibility on; however it turns off visibility for ALL OTHER pre elements across BOTH divs, as opposed to turning off the visibility for only the other divs within its same "code-box". If anyone could advise on this, that would be lovely. Thank you.

I've reproduced the code below:

HTML

<div id="code-box-1">
<div class="code-tabs">
<button class="tablinks" onclick="openTab(event, 'disp-Apples')" id="defaultOpen-1">Apples</button>
<button class="tablinks" onclick="openTab(event, 'disp-Oranges')">Oranges</button>
<button class="tablinks" onclick="openTab(event, 'disp-Bananas')">Bananas</button>
<div class="spacer"></div>
</div>

<pre id="disp-Apples" class="sg-tab-content">
<p>foo-1</p>
</pre>

<pre id="disp-Oranges" class="sg-tab-content">
<p>foo-2</p>
</pre>

<pre id="disp-Bananas" class="sg-tab-content">
<p>foo-3</p>
</pre>
</div>

<div id="code-box-2">
<div class="code-tabs">
<button class="tablinks" onclick="openTab(event, 'disp-Plums')" id="defaultOpen-2">Plums</button>
<button class="tablinks" onclick="openTab(event, 'disp-Pears')">Pears</button>
<button class="tablinks" onclick="openTab(event, 'disp-Grapes')">Grapes</button>
<div class="spacer"></div>
</div>

<pre id="disp-Plums" class="sg-tab-content">
<p>foo-4</p>
</pre>

<pre id="disp-Pears" class="sg-tab-content">
<p>foo-5</p>
</pre>

<pre id="disp-Grapes" class="sg-tab-content">
<p>foo-6</p>
</pre>
</div>


CSS

pre {
background-color: #f2f2f2;
border: 1px solid #cccccc;
padding: 0 0 0 20px;
margin-top: 0;
margin-bottom: 20px;
font-family: Consolas, Monaco, monospace;
font-size: 92%;
max-width: 100%;
height: 200px;
box-sizing: border-box;
position: relative;
z-index: 1;
}

div.code-tabs {
display: -webkit-flex;
display: flex;
width: 100%;
}

div.code-tabs button {
outline: none;
border: 1px solid #ccc;
background-color: #f2f2f2;
margin-right: 4px;
margin-bottom: -1px;
color: #9e9e9e;
font-family: Consolas, Monaco, monospace;
font-size: .875em; /*14px*/
height: 25px;
flex: 1;
z-index: 2;
}

div.code-tabs button.sg-current {
border-bottom: none !important;
}

.sg-tab-content {
display: none;
}

div.spacer {
height: 24px;
margin-bottom: -1px;
flex: 3;
}


Javascript

document.getElementById("defaultOpen-1").click();

function openTab(evt, tabName) {
var i, tabcontent, tablinks;

tabcontent = document.getElementsByClassName("sg-tab-content");
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(" sg-current", "");
}

document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " sg-current";
}

Answer Source

There are many ways to achieve this. The easiest for now would be, to pass the id of the box along:

HTML

<div id="code-box-1">
    <div class="code-tabs">
        <button class="tablinks" onclick="openTab(event, 'disp-Apples','code-box-1')" id="defaultOpen-1">Apples</button>
        <button class="tablinks" onclick="openTab(event, 'disp-Oranges','code-box-1')">Oranges</button>
        <button class="tablinks" onclick="openTab(event, 'disp-Bananas','code-box-1')">Bananas</button>
        <div class="spacer"></div>
    </div>

    <pre id="disp-Apples" class="sg-tab-content">
        <p>foo-1</p>
    </pre>

    <pre id="disp-Oranges" class="sg-tab-content">
        <p>foo-2</p>
    </pre>

    <pre id="disp-Bananas" class="sg-tab-content">
        <p>foo-3</p>
    </pre>
</div>

<div id="code-box-2">
    <div class="code-tabs">
        <button class="tablinks" onclick="openTab(event, 'disp-Plums','code-box-2')" id="defaultOpen-2">Plums</button>
        <button class="tablinks" onclick="openTab(event, 'disp-Pears','code-box-2')">Pears</button>
        <button class="tablinks" onclick="openTab(event, 'disp-Grapes','code-box-2')">Grapes</button>
        <div class="spacer"></div>
    </div>

    <pre id="disp-Plums" class="sg-tab-content">
        <p>foo-4</p>
    </pre>

    <pre id="disp-Pears" class="sg-tab-content">
        <p>foo-5</p>
    </pre>

    <pre id="disp-Grapes" class="sg-tab-content">
        <p>foo-6</p>
    </pre>
</div>

JS

document.getElementById("defaultOpen-1").click();

function openTab(evt, tabName, boxName) {    
    var i, tabcontent, tablinks;

    var box = document.getElementById(boxName)

    tabcontent = box.getElementsByClassName("sg-tab-content");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    tablinks = box.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" sg-current", "");
    }

    document.getElementById(tabName).style.display = "block";
    evt.currentTarget.className += " sg-current";
}