I have a long page, where one section is tabbed content. However, at the same time as showing tabs, I'd like for other sections further down the page to be visible or hidden, depending on which tab is clicked. Since each tab would display about 4 containers further down the page, I'd like to use classes for this rather than ID's. This is a rough outline of what I have so far (tab content removed, as it's unnecessary):
<div class="horisontal-tabs">
<ul class="tabs">
<li class="tab-label active person-sam" rel="tab1">Sam</li>
<li class="tab-label person-bob" rel="tab2">Bob</li>
<li class="tab-label person-jack" rel="tab3">Jack</li>
<li class="tab-label person-kelly" rel="tab4">Kelly</li>
</ul>
</div>
<div class="container-sam section-visible">Custom content only for Sam</div>
<div class="container-bob section-hidden">Custom content only for Bob</div>
<div class="container-jack section-hidden">Custom content only for Jack</div>
<div class="container-kelly section-hidden">Custom content only for Kelly</div>
<div class="container-sam section-visible">Other content for Sam</div>
<div class="container-bob section-hidden">Other content for Bob</div>
<div class="container-jack section-hidden">Other content for Jack</div>
<div class="container-kelly section-hidden">Other content for Kelly</div>
And I have jquery as per below for each person, but it doesn't seem to be working, and I can't figure out how to simplify it down. The idea is that when you click on one person's tab, all the other people's sections will be hidden and that person's will be visible.
$('.horizontal-tabs ul.tabs li.person-sam').click(function (event) {
$('.container-sam').removeClass('section-hidden').addClass('section-visible');
$('.container-sam.section-visible').removeClass('section-visible').addClass('section-hidden');
event.stopPropagation();
});
I have opted to not use ID on the sections and use a class instead, because multiple will need to show at once, so they wouldn't be unique.
Any tips will be greatly appreciated! :)
So the question is how to make simpler?
What comes to mind is you don't need active and inactive classes, you just need one of them, and then you can make the other be the default state . That is, add a default class .section to all sections and either use .section as the visible state and add .section-hidden to hide it, or use .section as the hidden state and add .section-visible to show it.
Say you go with .section-visible, the css would be something like this:
.section { display: none }
.section.section-visible { display: block }
This would also simplify your javascript because now you can reset all sections and just turn on/off the ones you need.
If you go, again, with .section-visible, run this on click:
$('.section').removeClass('section-visible'); // reset all sections
$('.container-sam').addClass('section-visible'); // add visible class to specific sections
You can see you only need one extra class, not two.
BONUS 1: you can use BEM to make it clearer.
BONUS 2: it looks like you have one click listener for each person, but instead you can use the HTML dataset API and the jQuery .data() function to detect which person's button you're pressing. That way you would have only one click listener, and you can detect which li was clicked by checking the data- attribute. Like <li data-person="sam">sam</li> and const containerSelector = `.container-${$(this).data('person')}`;. $(this) will select the li clicked, and .data('person') will return 'sam'. So the selector will be .container-sam.