Search code examples
jqueryhtmlprogress-barjquery-animatecss-counter

Animated progressbar list Counter only count last aria-valuenow


I'm currently doing my own online resume. I wanted to put several animated progress-bar for the skills section. I also integrated a counter to display the animation of the count percentage for each progress-bar, which is located in another div above each corresponding div class="progress-bar".

The problem is when I try to set the text() for the counter in the div above progress-bar, it shows the counted value from the last progress bar's "aria-valuenow" attribute.

$(".progress-bar").each(function(i) {
  $(this).animate({
    width: $(this).attr('aria-valuenow') + '%'
  });

  $(this).prop('Counter', 0).animate({
    Counter: $(this).attr('aria-valuenow')
  }, {
    duration: 3000,
    step: function(now) {
      $(".progressbar-number").text(Math.ceil(now));
    }
  });
});
.pt-4 {
  padding-top: 1.5rem !important;
}

.progress_elements {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

.progress_elements>div {
  flex: 0 0 100%;
  max-width: 100%;
  padding-bottom: 1rem !important;
}

.title-wrap {
  display: -webkit-flex;
  justify-content: space-between;
  -webkit-justify-content: space-between;
}

.progressbar-title {
  color: #000;
  font-size: 1rem;
}

.progressbar-title p {
  margin-bottom: 6px;
  letter-spacing: 0.03em;
}

.progress_value {
  position: relative;
  color: #000;
  font-size: 1rem;
}

.progressbar-number {
  display: inline-block;
}

.progress {
  width: 100%;
  height: 5px;
  border-radius: 0;
}

.progress-bar {
  height: 5px;
  background-color: #2ecc71;
  -webkit-transition: width 5s ease;
  -moz-transition: width 5s ease;
  -o-transition: width 5s ease;
  transition: width 5s ease;
}
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="progress1">
  <div class="title-wrap">
    <div class="progressbar-title">
      <p>
        PHP & MYSQL
      </p>
    </div>
    <div class="progress_value">
      <div class="progressbar-number"></div>
      <span>%</span>
    </div>
  </div>
  <div class="progress">
    <div class="progress-bar progress-bar-1" role="progressbar" aria-valuenow="90" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
</div>

<div class="progress2">
  <div class="title-wrap">
    <div class="progressbar-title">
      <p>
        HTML5 & CSS3
      </p>
    </div>
    <div class="progress_value">
      <div class="progressbar-number"></div>
      <span>%</span>
    </div>
  </div>
  <div class="progress">
    <div class="progress-bar progress-bar-2" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
</div>

<div class="progress3">
  <div class="title-wrap">
    <div class="progressbar-title">
      <p>
        WORDPRESS
      </p>
    </div>
    <div class="progress_value">
      <div class="progressbar-number"></div>
      <span>%</span>
    </div>
  </div>
  <div class="progress">
    <div class="progress-bar progress-bar-3" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
</div>


Solution

  • One solution is to add a common class to the main div holding the progress bar (in the next example it is called progress-wrapper). Now, after this, you need to use next code to update the % text value:

    step: function(now)
    {
      $(this).closest(".progress-wrapper")
          .find(".progressbar-number")
          .text(Math.ceil(now));
    }
    

    The previous code, for each progress bar, found his wrapper and then uses find() to get the related .progressbar-number div to update. The difference with your code is that the next logic:

    $(".progressbar-number").text(Math.ceil(now));
    

    was updating the text of all the divs with class .progressbar-number.

    Updated Example:

    $(".progress-bar").each(function(i)
    {
      $(this).animate({
        width: $(this).attr('aria-valuenow') + '%'
      });
    
      $(this).prop('Counter', 0).animate({
        Counter: $(this).attr('aria-valuenow')
      }, {
        duration: 3000,
        step: function(now)
        {
          $(this).closest(".progress-wrapper")
              .find(".progressbar-number")
              .text(Math.ceil(now));
        }
      });
    });
    .pt-4 {
      padding-top: 1.5rem !important;
    }
    
    .progress_elements {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-wrap: wrap;
    }
    
    .progress_elements>div {
      flex: 0 0 100%;
      max-width: 100%;
      padding-bottom: 1rem !important;
    }
    
    .title-wrap {
      display: -webkit-flex;
      justify-content: space-between;
      -webkit-justify-content: space-between;
    }
    
    .progressbar-title {
      color: #000;
      font-size: 1rem;
    }
    
    .progressbar-title p {
      margin-bottom: 6px;
      letter-spacing: 0.03em;
    }
    
    .progress_value {
      position: relative;
      color: #000;
      font-size: 1rem;
    }
    
    .progressbar-number {
      display: inline-block;
    }
    
    .progress {
      width: 100%;
      height: 5px;
      border-radius: 0;
    }
    
    .progress-bar {
      height: 5px;
      background-color: #2ecc71;
      -webkit-transition: width 5s ease;
      -moz-transition: width 5s ease;
      -o-transition: width 5s ease;
      transition: width 5s ease;
    }
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div class="progress-wrapper">
      <div class="title-wrap">
        <div class="progressbar-title">
          <p>
            PHP & MYSQL
          </p>
        </div>
        <div class="progress_value">
          <div class="progressbar-number"></div>
          <span>%</span>
        </div>
      </div>
      <div class="progress">
        <div class="progress-bar progress-bar-1" role="progressbar" aria-valuenow="90" aria-valuemin="0" aria-valuemax="100"></div>
      </div>
    </div>
    
    <div class="progress-wrapper">
      <div class="title-wrap">
        <div class="progressbar-title">
          <p>
            HTML5 & CSS3
          </p>
        </div>
        <div class="progress_value">
          <div class="progressbar-number"></div>
          <span>%</span>
        </div>
      </div>
      <div class="progress">
        <div class="progress-bar progress-bar-2" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100"></div>
      </div>
    </div>
    
    <div class="progress-wrapper">
      <div class="title-wrap">
        <div class="progressbar-title">
          <p>
            WORDPRESS
          </p>
        </div>
        <div class="progress_value">
          <div class="progressbar-number"></div>
          <span>%</span>
        </div>
      </div>
      <div class="progress">
        <div class="progress-bar progress-bar-3" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>
      </div>
    </div>