0

How to make it return to false once exceeded max step (which is the last step), previous function not working once exceeded max step, I tried to set current step as -1 but still doesn't work.

I get this error msg (TypeError: bullets[current] is undefined) on my console when it exceeded max step.

Can somebody help me with this? Thanks in advance.

const bullets=[...document.querySelectorAll('.bullet')];

const max=4;
let current=-1;

function next(){
 current+=1;
 if(!bullets[current]){
  return false; 
 }
 
 bullets[current].classList.add('hovered');
}

function previous(){
 bullets[current].classList.remove('hovered');
 current-=1;
 if(!bullets[current]){
  return false; 
 }
 
 bullets[current].classList.add('hovered');
}
.progressbar{
 display:flex;
 justify-content:space-between;
 align-items:flex-end;
 width:90%;
 margin:0 auto;
 margin-bottom:40px;
}
.item{
 text-align:center;
 width:20%;
 position:relative;
}
.text{
 height:50px;
 margin:10px 0px;
 color:#3CB371;
}
.bullet{
 border:1px solid #3CB371;
 height:20px;
 width:20px;
 color:#3CB371;
 display:inline-block;
 transition:background-color 500ms;
 line-height:20px;
}
.bullet.hovered{
 color:#fff;
 background-color:#3CB371;
 bottom:10px;
}
.bullet.completed:after{
 content:'';
 position:absolute;
 bottom:80px;
 height:1px;
 width:calc(133% - 21px);
 background-color:#3CB371;
 margin-left:7px;  
}
<div class="progressbar">
 <div class="item">
  <div class="bullet completed">1</div>
  <div class="text">Hello Hello Hello</div>
 </div>
 <div class="item">
  <div class="bullet completed">2</div>
  <div class="text">Hello</div>
 </div>
 <div class="item">
  <div class="bullet completed">3</div>
  <div class="text">Hello</div>
 </div>
 <div class="item completed">
  <div class="bullet">4</div>
  <div class="text">Hello</div>
 </div>
</div>
<div onclick="previous();">Previous</div>
<div onclick="next();">Next</div>
Stacie T.
  • 420
  • 6
  • 17

1 Answers1

1

You're unconditionally incrementing/decrementing current at the moment. Even if you don't try changing the classList on this call of next or previous, the next time either button is clicked, the current index may not exist. So, in previous, when you do bullets[current].classList.remove('hovered'); at the beginning of the function, that will throw if the last current went beyond the possible indicies for the bullets collection.

Consider using Math.max / Math.min to ensure that current is constrained to the possible indicies (or -1, in the case that nothing should be highlighted):

const bullets = [...document.querySelectorAll('.bullet')];

let current = -1;

function next() {
  current = Math.min(current + 1, bullets.length - 1);
  bullets[current].classList.add('hovered');
}

function previous() {
  if (bullets[current]) {
    bullets[current].classList.remove('hovered');
  }
  current = Math.max(current - 1, -1);
}
.progressbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  width: 90%;
  margin: 0 auto;
  margin-bottom: 40px;
}

.item {
  text-align: center;
  width: 20%;
  position: relative;
}

.text {
  height: 50px;
  margin: 10px 0px;
  color: #3CB371;
}

.bullet {
  border: 1px solid #3CB371;
  height: 20px;
  width: 20px;
  color: #3CB371;
  display: inline-block;
  transition: background-color 500ms;
  line-height: 20px;
}

.bullet.hovered {
  color: #fff;
  background-color: #3CB371;
  bottom: 10px;
}

.bullet.completed:after {
  content: '';
  position: absolute;
  bottom: 80px;
  height: 1px;
  width: calc(133% - 21px);
  background-color: #3CB371;
  margin-left: 7px;
}
<div class="progressbar">
  <div class="item">
    <div class="bullet completed">1</div>
    <div class="text">Hello Hello Hello</div>
  </div>
  <div class="item">
    <div class="bullet completed">2</div>
    <div class="text">Hello</div>
  </div>
  <div class="item">
    <div class="bullet completed">3</div>
    <div class="text">Hello</div>
  </div>
  <div class="item completed">
    <div class="bullet">4</div>
    <div class="text">Hello</div>
  </div>
</div>
<div onclick="previous();">Previous</div>
<div onclick="next();">Next</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320