How to make javascipt tabs work with html/css website - javascript

I'm doing work for a client and I ran into a pickle. He wanted a tab system whereby when the client clicks on the tab it opens content. Easy enough to do and I did it, however I encountered an issue. When you try to click the button to close it doesn't close for me, although it does open the new tab if clicked.
HERE is an example of the code on codepen: https://codepen.io/ghostcrawl3r/pen/vYybmJL
This is my html code:
<div className="tab">
<ul style="
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
display: flex;
justify-content: center;
">
<li><a class="tablinks" onclick="menuToggle(globalToggle, event, 'sandTesting')">THE SANDSTONE TESTING</a></li>
<li><h4>|</h4></li>
<li><a class="tablinks" onclick="menuToggle(globalToggle, event, 'cleaningCons')">THE CLEANING CONSIDERATIONS</a></li>
<li><h4>|</h4></li>
<li><a class="tablinks" onclick="menuToggle(globalToggle, event, 'codePrac')">THE CODE OF PRACTICE</a></li>
</ul>
<div id="sandTesting" class="tabcontent">
[elementor-template id="432"]
</div>
<div id="cleaningCons" class="tabcontent">
[elementor-template id="434"]
</div>
<div id="codePrac" class="tabcontent">
[elementor-template id="436"]
</div>
and this is my Javascript:
var globalToggle = false;
function menuToggle(tgl, evt, linkName){
var state = tgl;
tgl = !state;
if(tgl) {
globalToggle = false;
return openCity(evt, linkName);
} else {
globalToggle = true;
return document.getElementById(linkName).style.display = "none";
}
}
function openCity(evt, linkName) {
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(linkName).style.display = "block";
evt.currentTarget.className += " active";
}
I'm not entirely sure how to fix this. I tried to separate the globalVairable into 3 different vars and with if statements BUT when I did that to click on another tab you had to click twice.
I'd really appreciate some help as this has been plaguing me for days!

function menuToggle(tgl, evt, linkName) {
if (!evt.target.classList.contains("active")) {
return openCity(evt, linkName);
} else {
evt.target.classList.remove("active")
return document.getElementById(linkName).style.display = "none";
}
}
You've tangled up with the toggle-logic. I would refer to a class attribute and not to a JS-variable. If you don't want to use classList you must rewrite a bit, but the logic stays the same.

Related

Why do I have to click button twice for this JavaScript function to work?

I'm trying to get this function to change the display to the "active" div on the first click then back to "Insurance" on the second click.
Currently, it doesn't change to "active" until the second click of the button, then it rotates back and forth as it should.
Why does it take 2 clicks initially? How do I get it to work with the first click of the button?
var timesClicked = 0;
function openDiv(evt, divName, divName2) {
if (name1 === 'Insurance' && timesClicked < 1) {
evt.currentTarget.className += " active";
}
var name1 = divName;
var name2 = divName2;
timesClicked++;
if (name1 !== 'Insurance' && timesClicked > 1) {
// timesClicked = 0;
// openDiv(evt, 'Insurance', 'Insurance2');
// console.log("switch back");
// return;
name1 = 'Insurance';
name2 = 'Insurance2';
evt.currentTarget.className.replace(" active", "");
timesClicked = 0;
}
var i, tabcontent, tabcontent2, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
tabcontent2 = document.getElementsByClassName("tabcontent2");
for (i = 0; i < tabcontent2.length; i++) {
tabcontent[i].style.display = "none";
tabcontent2[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(name1).style.display = "block";
document.getElementById(name2).style.display = "block";
if (timesClicked === 1) {
evt.currentTarget.className += " active";
}
}
document.getElementById("defaultOpen").click();
<button class="tablinks" onclick="openDiv(event, 'Insurance', 'Insurance2')" id="defaultOpen"></button>
<div class="dw12">
<button class="tablinks" onclick="openDiv(event, 'Retiree-Medical', 'Retiree-Medical2')"><div class="tab---icon"><img class="tab-img" src="images/retiree-medical_icon.png" alt="Retiree Medical"/></div><div class="shadow-div"></div><p class="bold-title"><strong>RETIREE MEDICAL</strong></p><p class="small-title">CLICK FOR MORE</p></button>
</div>
Your approach is quiet cumbersome for what I think it supposed to do. In fact if your only objective is to toggle visibility of elements with only 2 possible states: on or off, than you can do this without any javascript, by utilizing a hidden checkbox and based on it's state display or hide certain siblings via CSS:
#tab1:checked ~ #Retiree-Medical,
#tab1:checked ~ #Retiree-Medical2,
#tab1:not(:checked) ~ #Insurance,
/*note, you can't use #Insurance2 directly because it's not sibling of #tab1*/
#tab1:not(:checked) ~ .some-child #Insurance2,
/*or you can use * to make it more universal */
#tab1:not(:checked) ~ * .tab1toggle.checkedonly,
#tab1:checked ~ * .tab1toggle:not(.checkedonly) {
display: none;
}
label {
user-select: none;
/* prevent text selection on double click */
}
label>button {
pointer-events: none;
}
.div {
display: block;
}
.red {
background-color: pink;
display: inline-block;
}
<div class="content">
<!-- must be above any elements it controls -->
<input id="tab1" type="checkbox" checked hidden>
<!-- using label to redirect clicks to the checkbox -->
<label class="dw12 div" for="tab1">
<!-- to prevent this button from capturing clicks we must disable it in css via pointer-events style -->
<button class="tablinks"><div class="tab---icon"><img class="tab-img" src="images/retiree-medical_icon.png" alt="Retiree Medical"/></div><div class="shadow-div"></div><p class="bold-title"><strong>RETIREE MEDICAL</strong></p><p class="small-title">CLICK FOR MORE</p></button>
</label>
<div id="Insurance">Insurance</div>
<div class="some-child">
<div class="another-child">
<div id="Insurance2">Insurance2</div>
</div>
</div>
<div id="Retiree-Medical">Retiree-Medical</div>
<div id="Retiree-Medical2">Retiree-Medical2</div>
<div class="red">
<div class="tab1toggle checkedonly">generic div1 checked</div>
<div class="tab1toggle checkedonly">generic div2 checked</div>
<div class="tab1toggle checkedonly">generic div3 checked</div>
<div>
<div>
<div>
<div class="tab1toggle checkedonly">generic div4 checked, has multiple parents</div>
</div>
</div>
</div>
<div class="tab1toggle checkedonly">generic div5 checked</div>
<div class="tab1toggle">generic div6</div>
<div class="tab1toggle">generic div7</div>
<div class="tab1toggle">generic div8</div>
<div class="tab1toggle">generic div9</div>
<div class="tab1toggle">generic div10</div>
</div>
</div>

Can't seem to close previously opened elements with JS or jQuery

I have personnel images on a website that when clicked is supposed to open a profile panel. This works as it should but if I click on another image without clicking the close button it will open the correct panel but it opens underneath the currently opened panel. I'm trying to figure out how to close the currently opened panel before opening the new one.
I have tried toggling a show-content class, that changes the display property, with jQuery and JS. This did not even show the panel properly. I have also tried to remove the class and display property before finding the profile-panel id and setting the class, with no success.
The code below is the current code that will pull up the profile-panel like it should but it will not close the opened one when I click another image, leaving the new panel covered.
My relevant HTML code:
<div class="col-md-3 col-xs-12">
<a href="#Jane" onclick="openProfile()">
<img class="profile-pic" src="/images/uploads/test-image.jpg">
<div class="name-overlay" onclick="openProfile('Jane', '1')">
<h2>Jane Doe</h2>
</div>
</a>
</div>
<div class="col-md-3 col-xs-12">
<a href="#John" onclick="openProfile()">
<img class="profile-pic" src="/images/uploads/test-image-2.jpg">
<div class="name-overlay" onclick="openProfile('John', '2')">
<h2>John Doe</h2>
</div>
</a>
</div>
My relevant CSS code:
.profile-panel { position: absolute; display: none; }
My relevant JS code:
var slideIndex;
var slides = document.getElementsByClassName("profile-panel");
function plusSlides() {
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
else if(slideIndex < 1){slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "flex";
console.log(slideIndex);
}
function minusSlides() {
slideIndex--;
if (slideIndex > slides.length) {slideIndex = 1}
else if(slideIndex < 1){slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "flex";
console.log(slideIndex);
}
function openProfile(id, number) {
document.getElementById(id).style.display = "flex";
slideIndex = number;
}
function closeProfile(id) {
document.getElementById(id).style.display = "none";
}

Display Tab Content Immediately On Page Load

I am creating a cinema website (school assignment) with three tabs: "Now Showing", "Coming Soon", "Promotions". I would like all content under "Now Showing" to be immediately visible upon page load. What do I need to edit in the HTML + Javascript code to do this?
I have only learnt HTML & CSS so far and adapted the Javascript code from w3schools. Hence, I'm not sure what to do. Thank you.
Here is the HTML code.
<div id="tab-rows">
<div class="tab">
<button class="tablinks" onclick="openContent(event, 'now-
showing')">Now Showing</button>
<button class="tablinks" onclick="openContent(event, 'coming-
soon')">Coming Soon</button>
<button class="tablinks" onclick="openContent(event,
'promotions')">Promotions</button>
</div>
<div id="now-showing" class="tabcontent">
<p>Placeholder Content</p>
</div>
<div id="coming-soon" class="tabcontent">
<p>Placeholder Content</p>
</div>
<div id="promotions" class="tabcontent">
<p>Placeholder Content</p>
</div>
Here is the Javascript code.
<script>
function openContent(evt, contentName) {
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(contentName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
There are multiple ways of doing it.
You could use the onload in the html and call your openContent function in it.
If you would wish to do it with the javascript only you can add event listener have to pass in your openContent as the second argument document.addEventListener("DOMContentLoaded", openContent);
You could change:
<div id="now-showing" class="tabcontent">
to:
<div id="now-showing" class="tabcontent active">
and add this to <head>:
<style>
.tabcontent { display: none; }
.tabcontent.active { display: block; }
.tablinks.active { cursor: not-allowed; }
</style>
and update your script like:
function openContent(evt, contentName) {
var tabcontent = document.getElementsByClassName("tabcontent");
for (var i = 0; i < tabcontent.length; i++) {
tabcontent[i].classList.remove("active");
}
var tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("active");
}
evt.currentTarget.classList.add("active");
document.getElementById(contentName).classList.add("active");
}
https://codepen.io/anon/pen/qLVQmp

How to make a tab automatically appear upon loading up the page

I have a set of tabs that look like this in my HTML:
<div class = "tab">
<button id = "Hom" class = "tablinks" onclick = "openTab(event, 'Home')">Home</button>
<button id = "Con" class = "tablinks" onclick = "openTab(event, 'Conjugations')">Conjugations</button>
<button id = "AutoCon" class = "tablinks" onclick = "openTab(event, 'Auto Conjugator')">Auto Conjugator</button>
</div>
<div id = "Home" class = "tabcontent">
<center>
<img src = "http://youth-portal.com/wp-content/uploads/2015/10/online-courses-of-French.jpg" height = "283.5" width = "567">
</center>
</div>
JavaScript:
function openTab(evt, tabName) {
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(tabName).style.display = "block";
evt.currentTarget.className += " active";
}
I want to make the home tab appear first when the page loads so that the user does not have to click the tab. I have tried it in CSS but it does not seem to be working. How do you do this with CSS or JavaScript?
Here is a working example;
https://codepen.io/curthusting/pen/vpeqWp?editors=1000
I would suggest instead of modifying styles with javascript, i.e.
tabcontent[i].style.display = "none"; & document.getElementById(tabName).style.display = "block";
control it with css;
.tabcontent {
display: none;
}
.tabcontent.active {
display: block;
}
.tablinks {
background: #fff;
}
.tablinks.active {
background: #5fba7d;
}
Then modify your initial html like this
<div class="tab">
<button id="Home" class="tablinks active" onclick="openTab(event, 'HomePanel')">Home</button>
<button id="Con" class="tablinks" onclick="openTab(event, 'ConjugationsPanel')">Conjugations</button>
<button id="AutoCon" class="tablinks" onclick="openTab(event, 'AutoConPanel')">Auto Conjugator</button>
</div>
<div id="HomePanel" class="tabcontent active">
<center>
<h1>Home</h1>
<img src="http://youth-portal.com/wp-content/uploads/2015/10/online-courses-of-French.jpg" height="283.5" width="567">
</center>
</div>
<div id="ConjugationsPanel" class="tabcontent">
<center>
<h1>Conjugations</h1>
<img src="http://youth-portal.com/wp-content/uploads/2015/10/online-courses-of-French.jpg" height="283.5" width="567">
</center>
</div>
<div id="AutoConPanel" class="tabcontent">
<center>
<h1>Auto Conjugator</h1>
<img src="http://youth-portal.com/wp-content/uploads/2015/10/online-courses-of-French.jpg" height="283.5" width="567">
</center>
</div>
and your javascript would look like this
// move these outside the `openTab()` so we can cache them and not retrieve them every time the active tab is changed
const tabcontent = document.getElementsByClassName("tabcontent");
const tablinks = document.getElementsByClassName("tablinks");
function openTab(evt, tabName) {
[].forEach.call(tabcontent, function(el) {
el.classList.remove("active");
});
[].forEach.call(tablinks, function(el) {
el.classList.remove("active");
});
document.getElementById(tabName).classList += " active";
evt.currentTarget.classList += " active";
}

How to always show the first TAB

I want to show the first tab always whenever the page load, which is the "Details" tab, any idea to do it? I have tried added JavaScript which runs on pageload, but it didn't work out as I wish.
HTML:
<ul class="tab">
<li>Details</li>
<li>Reviews</li>
</ul>
<div id="Details" class="tabcontent">
<h3>Details</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Reviews" class="tabcontent">
<h3>Reviews</h3>
<p>Paris is the capital of France.</p>
</div>
JavaScript:
function getFirstChildWithTagName(evt, tagName) {
for (var i = 0; i < element.childNodes.length; i++) {
if (element.childNodes[i].nodeName == tagName) return element.childNodes[i];
}
}
function openTab(evt, tabName) {
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 < tabcontent.length; i++) {
tablinks[i].classList.remove("active");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.classList.add("active");
}
$(document).ready(function () {
$('.tablinks:first').addClass('active');
});
Tried the following code, but it didn't work:
function LoadFunction() {
var mybtn = document.getElementsByClassName("tablinks")[0];
mybtn.click();
}
window.onload = LoadFunction();
One approach is to add style elements that mimic button click in the initial HTML.
Add active class to tablink button
<li>Details</li>
Add display style to tab content
<div id="Details" class="tabcontent" style="display:block">
Hope that helps
This code should work for you.
$(document).ready(function(){
$('.tab li:first-child').find('a').addClass('active');
$('.tabcontent').hide();
$('.tabcontent:first-child').show();
});
remove jQuery code:
$(document).ready(function () {
$('.tablinks:first').addClass('active');
});
or add jQuery library to your code
you can achieve you goal with small correction in your code. Please not that you are using both JQuery and JavaScript syntax so I assume you have included JQuery in your code.
html
<ul class="tab">
<li>Details</li>
<li>Reviews</li>
</ul>
<div id="Details" class="tabcontent">
<h3>Details</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Reviews" class="tabcontent">
<h3>Reviews</h3>
<p>Paris is the capital of France.</p>
</div>
script
function getFirstChildWithTagName(evt, tagName) {
for (var i = 0; i < element.childNodes.length; i++) {
if (element.childNodes[i].nodeName == tagName) return element.childNodes[i];
}
}
function openTab(elem, tabName) {
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 < tabcontent.length; i++) {
tablinks[i].classList.remove("active");
}
document.getElementById(tabName).style.display = "block";
console.log(elem)
$(elem[0]).addClass("active");
}
$(document).ready(function () {
var elem = $('.tablinks:first');
var tabName = "Details"
openTab(elem,tabName);
});
plunker : http://plnkr.co/edit/G8Kw76nvK4Xsz8oY6fRQ?p=preview

Categories

Resources