Mohamad
Mohamad

Reputation: 608

moving between section page using next and previous button in javascript

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>
   

Upvotes: 5

Views: 18651

Answers (5)

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>

Upvotes: 0

user14394673
user14394673

Reputation:

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>

Upvotes: 2

Razvan Zamfir
Razvan Zamfir

Reputation: 4666

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>

Upvotes: 4

Lajos Arpad
Lajos Arpad

Reputation: 76787

It'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>

Upvotes: 5

Forbidden
Forbidden

Reputation: 109

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')

Upvotes: 0

Related Questions