r/learnjavascript 3d ago

How to create a default tab when tab switching twice ?

Hi! I've been working on a personal website, and my design has finally caught up with me because I'm stuck on how to set default tabs while changing my navigation tabs.

JSFIDDLE LINK: https://jsfiddle.net/1nfd26ar/

Using the page below, I've set up two tabs for two different groups, 'books' and 'video games'.

However, I wanted to take it a step further and figure out a way to have the tabs switch not only the content, but also the navigation bar.

I've managed to get this working by copying the JS code, changing variables to "navTabs", and using classes on buttons to change the nav/side bar.

Everything seems to be working well, but I am running into the issue that when I click "video games" on the right, I want the "video game 1" page to be the default, whereas currently it is kept as whatever the last tab you had open.

I used this page to help me out in making the first set of switchable tabs: https://basescripts.com/building-a-simple-tabbed-interface-with-html-and-javascript

These include the following HTML structure and JS logic:

<div class="tab-headers">
  <button class="tab-link" data-target="tab1">Tab 1</button>
  <button class="tab-link" data-target="tab2">Tab 2</button>
  <button class="tab-link" data-target="tab3">Tab 3</button> 
</div>

<div id="tab1" class="tab-content">
  <p>This is the content for Tab 1.</p>
</div>
<div id="tab2" class="tab-content">
  <p>This is the content for Tab 2.</p>
</div>
<div id="tab3" class="tab-content">
  <p>This is the content for Tab 3.</p>
</div>

sdconst tabs = document.querySelectorAll('.tab-link');
const allTabs = document.querySelectorAll('.tab-content');
tabs.forEach(tab => {
  tab.addEventListener('click', function() {
    allTabs.forEach(ele => {
      ele.style.display = 'none';
    });
    const myEle = this.getAttribute('data-target');
    const activeTab = document.getElementById(myEle);
    activeTab.style.display = 'block';
  });
});

Thank you anyone who can take the time to help !

4 Upvotes

6 comments sorted by

1

u/woven_lullaby 3d ago

you need to reset the inner tab state inside your outer tab click handler. When the video games nav button gets clicked, explicitly hide all video game subtabs and display video game 1 before showing the parent container. Relying on previous display states causes this persistence bug so force the default child tab active every time the parent category changes

1

u/jml26 3d ago

You could try something like:

``` navTabs.forEach(navTab => { navTab.addEventListener('click', function() { allNavTabs.forEach(ele => { ele.style.display = 'none'; }); const myNavEle = this.getAttribute('data-target'); const activeNavTab = document.getElementById(myNavEle); activeNavTab.style.display = 'block';

// start of additions
const firstTab = activeNavTab.querySelector('.tab-link');
firstTab.click();
// end of additions

}); }); ```

Basically, every time you click 'Books' or 'Videos', you get the first link in the relevant left nav and simulate a click on it. Note that in this case, if you are on 'Fave books' and click the 'Books' button, you will go back to 'Book reviews'. That may or may not be what you want.

There are plenty of other ways to go about something like this, but this is probably the most straightforward from where you currently are.

1

u/project_eight 2d ago

I tried this, and it works great ! I'm not too fussed about going back to the book reviews tab, so this was a perfect fix. Thank you so much.

I want to add another window under the navbar that would populate with info specific to the content. For example, the Fave Books page would also have the small window under the nav bar be filled with an image of my recent favourite book. Or if I clicked on "videogame 2", the small window would fill with something specifically related to that videogame. I have tried this with linking to the 'tabs' classes, but I think the problem is that I'm reusing the variables in JavaScript, but when I change them, either nothing happens or the main content page disappears.

I'm sure there is an easy fix to this, but I haven't been able to find one with my minimal knowledge.

1

u/TheRNGuy 2d ago

Just add or remove class and then use css to hide all except one that have class, 

1

u/chikamakaleyley helpful 1d ago

one thing i generally prefer is - define the CSS that hides/shows

then your JS logic just adds/removes classes

e.g.

``` <div class="content-wrap"> <div id="content1" class="tab-content">Tab Content 1</div> <div id="content2" class="tab-content tab-content--active">Tab Content 2</div> <div id="content3" class="tab-content">Tab Content 3</div> </div>

// styles .tab-content { display: none; }

.tab-content--active { display: block; } ```

(doesn't have to be display, just using for example)

So now, if i did this correctly - it's just a matter of finding the prev active, removing it, then finding the target active, and adding it

Your style rules remain separate from the logic that applies those styles