In the same page I have multiple sections.
One section
will be shown and this will happen using an active
class
.
In the same page I have li
buttons 1, 2 and 3 and when I click on one of them the section
related to it appears and the old one disappears. For that purpose I'm using Javascript.
Also in the same page I have a next and previous button. When I click on the next button the next section
should appear and the old one should disappear.
And also the related li
to the section should have the active
class
, the same thing for the previous: when I click on it it should go to the old section
and the current should disappear and the li
class
should be active
.
When I'm in the first section
the previous button should disappear and when I'm in the last section the next button should disappear.
How can I implement this behavior for the next and previous buttons in this way using Javascript?
Any Help Please!!?
let tab = document.querySelector(".nav li");
let tabs = document.querySelectorAll(".nav li");
let tabsArray = Array.from(tabs);
let section = document.querySelectorAll(".section");
let sectionArray = Array.from(section);
let nextButton = document.querySelector(".next");
let prevButton = document.querySelector(".previous");
let current = 0;
tabsArray.forEach((ele) => {
ele.addEventListener("click", function (e) {
tabsArray.forEach((ele) => {
ele.classList.remove("active");
});
e.currentTarget.classList.add("active");
sectionArray.forEach((sec) => {
sec.classList.remove("active");
});
if(e.currentTarget.dataset.cont =='r1'){
prevButton.classList.add("disable");
}else{
prevButton.classList.remove("disable");
}
if (
document.querySelector("#" + e.currentTarget.dataset.cont) ==
sectionArray[sectionArray.length - 1]
) {
nextButton.classList.add("disable");
} else {
nextButton.classList.remove("disable");
}
document.querySelector('#' + e.currentTarget.dataset.cont).classList.add("active");
});
});
.section {
display: none;
}
.section.active{
display: block;
}
ul {
list-style: none;
margin:0;
padding: 0;
display: flex;
align-items: center;
}
ul li {
background: #ccc;
padding: 10px 15px;
margin-left: 6px;
border-radius: 50%;
cursor: pointer;
opacity: .5;
}
ul li.active{
opacity: 1 !important;
}
.next,
.previous {
padding: 15px 10px;
border-radius: 6px;
background: deepskyblue;
color: white;
border:0;
outline: none;
cursor: pointer;
width: 100px;
}
.next.disable,
.previous.disable{
cursor: none;
opacity: .5;
}
<ul class="nav">
<li class="active" data-cont="r1">1</li>
<li data-cont="r2">2</li>
<li data-cont="r3">3</li>
</ul>
<section id="r1" class="section section-one active">
<h2>section 1</h2>
</section>
<section id="r2" class="section section-two">
<h2>section 2</h2>
</section>
<section id="r3" class="section section-three">
<h2>section 3</h2>
</section>
<button class="previous disable" id="previous">Previous</button>
<button class="next" id="next">Next</button>
In the same page I have multiple sections.
One section
will be shown and this will happen using an active
class
.
In the same page I have li
buttons 1, 2 and 3 and when I click on one of them the section
related to it appears and the old one disappears. For that purpose I'm using Javascript.
Also in the same page I have a next and previous button. When I click on the next button the next section
should appear and the old one should disappear.
And also the related li
to the section should have the active
class
, the same thing for the previous: when I click on it it should go to the old section
and the current should disappear and the li
class
should be active
.
When I'm in the first section
the previous button should disappear and when I'm in the last section the next button should disappear.
How can I implement this behavior for the next and previous buttons in this way using Javascript?
Any Help Please!!?
let tab = document.querySelector(".nav li");
let tabs = document.querySelectorAll(".nav li");
let tabsArray = Array.from(tabs);
let section = document.querySelectorAll(".section");
let sectionArray = Array.from(section);
let nextButton = document.querySelector(".next");
let prevButton = document.querySelector(".previous");
let current = 0;
tabsArray.forEach((ele) => {
ele.addEventListener("click", function (e) {
tabsArray.forEach((ele) => {
ele.classList.remove("active");
});
e.currentTarget.classList.add("active");
sectionArray.forEach((sec) => {
sec.classList.remove("active");
});
if(e.currentTarget.dataset.cont =='r1'){
prevButton.classList.add("disable");
}else{
prevButton.classList.remove("disable");
}
if (
document.querySelector("#" + e.currentTarget.dataset.cont) ==
sectionArray[sectionArray.length - 1]
) {
nextButton.classList.add("disable");
} else {
nextButton.classList.remove("disable");
}
document.querySelector('#' + e.currentTarget.dataset.cont).classList.add("active");
});
});
.section {
display: none;
}
.section.active{
display: block;
}
ul {
list-style: none;
margin:0;
padding: 0;
display: flex;
align-items: center;
}
ul li {
background: #ccc;
padding: 10px 15px;
margin-left: 6px;
border-radius: 50%;
cursor: pointer;
opacity: .5;
}
ul li.active{
opacity: 1 !important;
}
.next,
.previous {
padding: 15px 10px;
border-radius: 6px;
background: deepskyblue;
color: white;
border:0;
outline: none;
cursor: pointer;
width: 100px;
}
.next.disable,
.previous.disable{
cursor: none;
opacity: .5;
}
<ul class="nav">
<li class="active" data-cont="r1">1</li>
<li data-cont="r2">2</li>
<li data-cont="r3">3</li>
</ul>
<section id="r1" class="section section-one active">
<h2>section 1</h2>
</section>
<section id="r2" class="section section-two">
<h2>section 2</h2>
</section>
<section id="r3" class="section section-three">
<h2>section 3</h2>
</section>
<button class="previous disable" id="previous">Previous</button>
<button class="next" id="next">Next</button>
Share
Improve this question
edited Jan 2, 2022 at 9:31
Lajos Arpad
76.6k40 gold badges116 silver badges220 bronze badges
asked Dec 28, 2021 at 7:59
MohamadMohamad
6082 gold badges8 silver badges23 bronze badges
4
|
5 Answers
Reset to default 5 +50It's advisable to have a collection of buttons and another for sections, connecting the two via the index, which needs to also be tracked. If we have all this, then going next is increasing the index, while going previous is decreasing the index. I'm not making previous and next disappear, even though the question asks me to do so. Instead I'm using the disable
class. If we want to make them appear/disappear, then we can use the invisible
class
instead.
let currentSection = 0;
let sections = document.querySelectorAll(".section");
let sectionButtons = document.querySelectorAll(".nav > li");
let nextButton = document.querySelector(".next");
let previousButton = document.querySelector(".previous");
for (let i = 0; i < sectionButtons.length; i++) {
sectionButtons[i].addEventListener("click", function() {
sections[currentSection].classList.remove("active");
sectionButtons[currentSection].classList.remove("active");
sections[currentSection = i].classList.add("active");
sectionButtons[currentSection].classList.add("active");
if (i === 0) {
if (previousButton.className.split(" ").indexOf("disable") < 0) {
previousButton.classList.add("disable");
}
} else {
if (previousButton.className.split(" ").indexOf("disable") >= 0) {
previousButton.classList.remove("disable");
}
}
if (i === sectionButtons.length - 1) {
if (nextButton.className.split(" ").indexOf("disable") < 0) {
nextButton.classList.add("disable");
}
} else {
if (nextButton.className.split(" ").indexOf("disable") >= 0) {
nextButton.classList.remove("disable");
}
}
});
}
nextButton.addEventListener("click", function() {
if (currentSection < sectionButtons.length - 1) {
sectionButtons[currentSection + 1].click();
}
});
previousButton.addEventListener("click", function() {
if (currentSection > 0) {
sectionButtons[currentSection - 1].click();
}
});
.section {
display: none;
}
.section.active{
display: block;
}
.invisible {
display: none;
}
ul {
list-style: none;
margin:0;
padding: 0;
display: flex;
align-items: center;
}
ul li {
background: #ccc;
padding: 10px 15px;
margin-left: 6px;
border-radius: 50%;
cursor: pointer;
opacity: .5;
}
ul li.active{
opacity: 1 !important;
}
.next,
.previous {
padding: 15px 10px;
border-radius: 6px;
background: deepskyblue;
color: white;
border:0;
outline: none;
cursor: pointer;
width: 100px;
}
.next.disable,
.previous.disable{
cursor: none;
opacity: .5;
}
<ul class="nav">
<li class="active" data-cont="r1">1</li>
<li data-cont="r2">2</li>
<li data-cont="r3">3</li>
</ul>
<section id="r1" class="section section-one active">
<h2>section 1</h2>
</section>
<section id="r2" class="section section-two">
<h2>section 2</h2>
</section>
<section id="r3" class="section section-three">
<h2>section 3</h2>
</section>
<button class="previous disable" id="previous">Previous</button>
<button class="next" id="next">Next</button>
I hope I understand your question well and the solution below helps.
It is broken into small functions, the goal being that one function does one thing.
let tabs = document.querySelectorAll(".nav li");
let sections = document.querySelectorAll(".section");
let nextButton = document.querySelector("#nextBtn");
let prevButton = document.querySelector("#prevBtn");
let current = 0;
const toggleTabs = () => {
tabs.forEach(function(tab) {
tab.classList.remove('active');
});
tabs[current].classList.add("active");
//console.log(current);
}
const toggleSections = () => {
sections.forEach(function(section) {
section.classList.remove('active');
});
sections[current].classList.add("active");
}
const togglePrev = () => {
const method = current == 0 ? 'add' : 'remove';
prevButton.classList[method]("disable");
}
const toggleNext = () => {
const method = current == tabs.length - 1 ? 'add' : 'remove';
nextButton.classList[method]("disable");
}
const goNext = () => {
if (current < tabs.length - 1) {
current++
}
toggleTabs();
toggleSections();
toggleNext();
togglePrev();
}
const goPrev = () => {
if (current > 0) {
current--
}
toggleTabs();
toggleSections();
toggleNext();
togglePrev();
}
.section {
display: none;
}
.section.active {
display: block;
}
ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
align-items: center;
}
ul li {
background: #ccc;
padding: 10px 15px;
margin-left: 6px;
border-radius: 50%;
cursor: pointer;
opacity: .5;
}
ul li.active {
opacity: 1 !important;
}
.next,
.previous {
padding: 15px 10px;
border-radius: 6px;
background: deepskyblue;
color: white;
border: 0;
outline: none;
cursor: pointer;
width: 100px;
}
.next.disable,
.previous.disable {
cursor: none;
opacity: .5;
}
<ul class="nav">
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<section class="section section-one active">
<h2>section 1</h2>
</section>
<section class="section section-two">
<h2>section 2</h2>
</section>
<section class="section section-three">
<h2>section 3</h2>
</section>
<button class="previous disable" id="prevBtn" onclick="goPrev()">Previous</button>
<button class="next" id="nextBtn" onclick="goNext()">Next</button>
Here is a class-based solution with some CSS changes to center the content:
class TabbedContent {
constructor() {
this.tabs = document.querySelectorAll(".nav li");
this.sections = document.querySelectorAll(".section");
this.nextButton = document.querySelector("#nextBtn");
this.prevButton = document.querySelector("#prevBtn");
this.current = 0;
}
toggleTabs() {
this.tabs.forEach(function(tab) {
tab.classList.remove('active');
});
this.tabs[this.current].classList.add("active");
}
toggleSections() {
this.sections.forEach(function(section) {
section.classList.remove('active');
});
this.sections[this.current].classList.add("active");
}
togglePrev() {
const method = this.current == 0 ? 'add' : 'remove';
this.prevButton.classList[method]("disable");
}
toggleNext() {
const method = this.current == this.tabs.length - 1 ? 'add' : 'remove';
this.nextButton.classList[method]("disable");
}
goNext() {
if (this.current < this.tabs.length - 1) {
this.current++
}
this.toggleTabs();
this.toggleSections();
this.toggleNext();
this.togglePrev();
}
goPrev() {
if (this.current > 0) {
this.current--
}
this.toggleTabs();
this.toggleSections();
this.toggleNext();
this.togglePrev();
}
}
const tabbedContent = new TabbedContent();
.container {
max-width: 600px;
margin: 0 auto;
text-align: center;
}
.section {
display: none;
}
.section.active {
display: block;
}
ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
ul li {
background: #ccc;
padding: 10px 15px;
margin-left: 6px;
border-radius: 50%;
cursor: pointer;
opacity: .5;
}
ul li.active {
opacity: 1 !important;
}
.next,
.previous {
padding: 15px 10px;
border-radius: 6px;
background: deepskyblue;
color: white;
border: 0;
outline: none;
cursor: pointer;
width: 100px;
}
.next.disable,
.previous.disable {
cursor: none;
opacity: .5;
}
<div class="container">
<ul class="nav">
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<section class="section section-one active">
<h2>section 1</h2>
</section>
<section class="section section-two">
<h2>section 2</h2>
</section>
<section class="section section-three">
<h2>section 3</h2>
</section>
<button class="previous disable" id="prevBtn" onclick="tabbedContent.goPrev()">Previous</button>
<button class="next" id="nextBtn" onclick="tabbedContent.goNext()">Next</button>
</div>
If you want to make the "previous"/"next" button disappear without changing the layout, then you can set those buttons to "visibility:hidden;" by default in CSS and change it to "visibility:visible;" when the relevant event is triggered.
Also you can use the "button" tag instead of the "li" tag for the top navbar as well.
Below is my code:
const sectionContent = ["r1", "r2", "r3"];
let currentSection = sectionContent[0];
const displayContent = (q, area) => {
document.getElementById(q).classList.add("active");
document.getElementById(q + "-button").classList.add("button-active");
currentSection = sectionContent[area.indexOf(q)];
const toNone = area.filter(e => e !== q);
for (i in toNone) {
document.getElementById(toNone[i]).classList.remove("active");
document.getElementById(toNone[i] + "-button").classList.remove("button-active");
}
if (sectionContent.indexOf(q) == 0) {
document.getElementById("previous").classList.remove("button-active");
document.getElementById("next").classList.add("button-active");
}
else if (sectionContent.indexOf(q) == sectionContent.length - 1) {
document.getElementById("previous").classList.add("button-active");
document.getElementById("next").classList.remove("button-active");
} else {
document.getElementById("previous").classList.add("button-active");
document.getElementById("next").classList.add("button-active");
}
}
const displayR1 = () => displayContent("r1", sectionContent);
const displayR2 = () => displayContent("r2", sectionContent);
const displayR3 = () => displayContent("r3", sectionContent);
const displayNext = () => displayContent(sectionContent[sectionContent.indexOf(currentSection) + 1], sectionContent);
const displayPrevious = () => displayContent(sectionContent[sectionContent.indexOf(currentSection) - 1], sectionContent);
.container {
display: grid;
place-items: center;
}
.section {
display: none;
}
.section.active {
display: block;
}
.nav {
list-style: none;
margin:0;
padding: 0;
display: flex;
align-items: center;
}
.nav button {
background: #ccc;
padding: 10px 15px;
margin-left: 6px;
border-radius: 50%;
cursor: pointer;
opacity: .5;
border: none;
}
.next,
.previous {
padding: 15px 10px;
border-radius: 6px;
background: deepskyblue;
color: white;
border:0;
outline: none;
cursor: pointer;
width: 100px;
visibility: hidden;
}
.button-active {
opacity: 1 !important;
visibility: visible;
}
<div class="container">
<nav class="nav">
<button class="button-active" id="r1-button" onclick="displayR1()">1</button>
<button id="r2-button" onclick="displayR2()">2</button>
<button id="r3-button" onclick="displayR3()">3</button>
</nav>
<section id="r1" class="section active">
<h2>section 1</h2>
</section>
<section id="r2" class="section">
<h2>section 2</h2>
</section>
<section id="r3" class="section">
<h2>section 3</h2>
</section>
<nav>
<button class="previous" id="previous" onclick="displayPrevious()">Previous</button>
<button class="next button-active" id="next" onclick="displayNext()">Next</button>
</nav>
</div>
tabsArray.forEach((ele) => {
ele.addEventListener("click", function (e) {
tabsArray.forEach((ele) => {
ele.classList.remove("active");
});
e.currentTarget.classList.add("active");
sectionArray.forEach((sec) => {
sec.classList.remove("active");
});
// get the current click section
// if the current section is 3
// Then next button should be disabled
// else if the current section is 1
// Then prev button should be disabled
document.querySelector('#' + e.currentTarget.dataset.cont).classList.add("active");
});
});
Sorry not good at plain Javascript, But for easy visualization That should be the process
You may identify the current section by getting the data-cont
attribute,
Using jQuery the code will be
$(ele).attr('data-cont')
which will return any r1
, r2
, or r3
// Get the current data-cont value in li attribute
var currSection = $(ele).attr('data-cont')
// Disable previous button when currSection is r1
$('button.previous').prop('disabled', currSection == 'r1')
// Disable next button when currSection is r3
$('button.next').prop('disabled', currSection == 'r3')
const sectionContent = ["r1", "r2", "r3"];
let currentSection = sectionContent[0];
const displayContent = (q, area) => {
document.getElementById(q).classList.add("active");
document.getElementById(q + "-button").classList.add("button-active");
currentSection = sectionContent[area.indexOf(q)];
const toNone = area.filter(e => e !== q);
for (i in toNone) {
document.getElementById(toNone[i]).classList.remove("active");
document.getElementById(toNone[i] + "-button").classList.remove("button-active");
}
if (sectionContent.indexOf(q) == 0) {
document.getElementById("previous").classList.remove("button-active");
document.getElementById("next").classList.add("button-active");
}
else if (sectionContent.indexOf(q) == sectionContent.length - 1) {
document.getElementById("previous").classList.add("button-active");
document.getElementById("next").classList.remove("button-active");
} else {
document.getElementById("previous").classList.add("button-active");
document.getElementById("next").classList.add("button-active");
}
}
const displayR1 = () => displayContent("r1", sectionContent);
const displayR2 = () => displayContent("r2", sectionContent);
const displayR3 = () => displayContent("r3", sectionContent);
const displayNext = () => displayContent(sectionContent[sectionContent.indexOf(currentSection) + 1], sectionContent);
const displayPrevious = () => displayContent(sectionContent[sectionContent.indexOf(currentSection) - 1], sectionContent);
.container {
display: grid;
place-items: center;
}
.section {
display: none;
}
.section.active {
display: block;
}
.nav {
list-style: none;
margin:0;
padding: 0;
display: flex;
align-items: center;
}
.nav button {
background: #ccc;
padding: 10px 15px;
margin-left: 6px;
border-radius: 50%;
cursor: pointer;
opacity: .5;
border: none;
}
.next,
.previous {
padding: 15px 10px;
border-radius: 6px;
background: deepskyblue;
color: white;
border:0;
outline: none;
cursor: pointer;
width: 100px;
visibility: hidden;
}
.button-active {
opacity: 1 !important;
visibility: visible;
}
<div class="container">
<nav class="nav">
<button class="button-active" id="r1-button" onclick="displayR1()">1</button>
<button id="r2-button" onclick="displayR2()">2</button>
<button id="r3-button" onclick="displayR3()">3</button>
</nav>
<section id="r1" class="section active">
<h2>section 1</h2>
</section>
<section id="r2" class="section">
<h2>section 2</h2>
</section>
<section id="r3" class="section">
<h2>section 3</h2>
</section>
<nav>
<button class="previous" id="previous" onclick="displayPrevious()">Previous</button>
<button class="next button-active" id="next" onclick="displayNext()">Next</button>
</nav>
</div>
1
and click on3
, should clicking the previous button take you back to1
(because you were just on1
)? Or should it take you to2
, because that's the option before3
– Nick Parsons Commented Jan 2, 2022 at 9:38