1

I am trying to create a progress bar of css circles, in which after clicking on every circle like 1, 2, 3 all the three circles and their connected line will be filled by red color and if go back like 3, 2, 1 then color should be removed.

HTML :

<div class="row well" id="rows">
        <ul id="progressbar" class="progressbar">
            <li class="cir danger">THOUGHFUL</li>
            <li class="cir">PASSION</li>
            <li class="cir">POWER OF DESIGN</li>
            <li class="cir">BUILDING RELATIONSHIPS</li>
            <li class="cir">ENHANCE HUMAN INTERATION</li>
        </ul>
    </div>

JS :

var header = document.getElementById("rows");
        var bar = document.getElementsByClassName("progressbar");
        var btns = header.getElementsByClassName("cir");
        for (var i = 0; i < btns.length; i++) {
            btns[i].addEventListener("click", function () {
                var danger = document.getElementsByClassName("danger");
                danger[0].className = danger[0].className.replace("danger", "");
                this.className += " danger";
            });
        }

Sample Img: enter image description here

Referring to above imag, if i click on circle 3 then circle 1,2,3 should be in red color and then if i click circle 2 then circle 3 should be white and 1 & 2 should be red, vice versa. I have tried to achieve it by JS but classnotfound error .

Any help for this would be appreciated.

Prathamesh Doke
  • 797
  • 2
  • 16
  • 38
  • 1
    Can you post the full error – The Codesee Mar 28 '20 at 21:17
  • now there is no error, wrong classname i have added, now the filling by red color is not worlking – Prathamesh Doke Mar 28 '20 at 21:25
  • You need to target the previous siblings and next siblings to ensure previous siblings get coloured and any siblings after are decoloured. For help on targeting previous and next siblings, refer to [How to find all Siblings of the currently selected DOM object](https://stackoverflow.com/questions/4378784/how-to-find-all-siblings-of-the-currently-selected-dom-object). – Daemon Beast Mar 28 '20 at 21:48
  • Also, is the GIF just meant to be you moving the cursor, because it doesn't seem to be any more helpful than an image? – Daemon Beast Mar 28 '20 at 21:51
  • yes that gif is not working here, i've converted video to gif, i have through the link you shared but how can i make them colored can you please about it. – Prathamesh Doke Mar 28 '20 at 21:53

2 Answers2

2

Every time a circle is clicked, grab its data-id and activate all circles of an equal or lesser data-id.

let circles = document.querySelectorAll(".circle")
circles.forEach(el => {
   el.addEventListener("click", (e) => {
     let id = e.target.dataset.id
     circles.forEach(el2 => {
        if(el2.dataset.id <= id){
            el2.classList.add("active")
        }else{
            el2.classList.remove("active")
        }
     })   
   })
})
.circled{display:flex}
.circle{
   border-radius:50%;
   width:50px;
   height:50px;
   border: solid 2px #333;
   display:inline-flex;
   align-items:center;
   justify-content:center;
   position:relative;
   margin-left: 44px;
   cursor:pointer;
}

.circle:not(:first-of-type)::before{
   height: 2px;
   width: 50px;
   content:"";
   background-color: #333;
   position:absolute;
   left:-50px;
}

.circle.active{
   border-color: #f00;
}

.circle.active:not(:first-of-type)::before{
   background-color: #f00;
}
<div class="circles">
   <div class="circle active" data-id="1">1</div>
   <div class="circle" data-id="2">2</div>
   <div class="circle" data-id="3">3</div>
   <div class="circle" data-id="4">4</div>
   <div class="circle" data-id="5">5</div>
</div>
symlink
  • 11,984
  • 7
  • 29
  • 50
1

Not proud of this

var header = document.getElementById("rows");
var bar = document.getElementsByClassName("progressbar");
var btns = header.getElementsByClassName("cir");

Array.prototype.forEach.call(btns,function(btn){
    btn.addEventListener('click', function(e){
    updateProgress(btn,e)
  })
});

function updateProgress(btn,e){
    removeDangerFromAll();

  for( let btnToCheck of btns){
    btnToCheck.classList.add('danger');

    if (btnToCheck == btn) {
      break;
    }
  }
}

function removeDangerFromAll(){
    Array.prototype.forEach.call(btns,function(btn){
    btn.classList.remove('danger');
  });
}

UPDATE: Switched to cleaner classList as Other Answer

Shaun Forsyth
  • 454
  • 4
  • 7