Mdermez
Mdermez

Reputation: 549

JS count number with thousands separator

This is my script for counting number given the final number (see html). What I want to do is to add a thousands separator. As it is my code will count the number from 0 to eg. 100,000 but it will show : "100000" which doesn't look good.

PS: I've tried toLocaleString() but it didn't work in my code or I didn't use it correctly. The problem with this is that it will not show the thousands separator WHILE animating the counting.

JS

<script>
            var a = 0;
            $(window).scroll(function() {

              var oTop = $('#counter').offset().top - window.innerHeight;
              if (a == 0 && $(window).scrollTop() > oTop) {
                $('.counter-value').each(function() {
                  var $this = $(this),
                    countTo = $this.attr('data-count');
                  $({
                    countNum: $this.text()
                  }).animate({
                      countNum: countTo
                    },

                    {

                      duration: 5000,
                      easing: 'swing',
                      step: function() {
                        $this.text(Math.floor(this.countNum));
                      },
                      complete: function() {
                        $this.text(this.countNum);
                        //alert('finished');
                      }

                    });
                });
                a = 1;
              }

            });
        </script>

HTML

<div class="counter-value" data-count="100000">0</div>

Upvotes: 2

Views: 1839

Answers (2)

zer00ne
zer00ne

Reputation: 43870

Instead of using divs use elements that'll work for you:

Tag                                        Purpose


<input type='range'>          Store the current offset value: 0 to 100,000

<output></output>                Display the value of <input type='range'> formatted with                                               Intl.NumberFormat()

<form>                                   Listens for the input event and trigger()s a synthetic input                                                 event when user scrolls.

Details commented in Demo

Demo

* {
  margin: 0;
  padding: 0
}

html,
body {
  overflow-x: hidden;
  font: 600 16px/1.5 Consolas;
  width: 100%;
  height: 100%;
  display: table;
  margin: 0 auto;
}

#countDown {
  position: relative;
  width: 96vw;
  height: 12600ch;
  overflow-x: hidden;
  overflow-y: scroll;
  margin-top: 50vh;
  z-index:-1;
}

/* The input is hidden because it cannot keep a text of numbers
and commas if it's a type='range'. Don't want to have it as a
type='text' because it's more work to validate */

#counter {
  display: none
}

#set {
  position: fixed;
  width: 15%;
  height: 96vh;
  z-index: 1;
  top: 2vh;
  text-align: center;
}

#counterView {
  display: block;
  margin-top: calc(50vh - 8px);
}
<html>

<head></head>

<body>

  <form id='countDown'>

    <fieldset id='set'>

      <input id='counter' type='range' min='0' max='100000' value='100000'>

      <output id="counterView" for='counter'>100,000</output>

    </fieldset>

  </form>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script>
    var a = 0;
    $(document).scroll(function() {

      /* label#0.mark is a fixed position at the top of viewport
      || The form#countDown is 12596ch high = window.innerHeight
      */
      var oTop = $('#set').offset().top + window.innerHeight;

      // As the distance between top of viewport decrease...
      if ($(window).scrollTop() < (oTop)) {

        // The form fires an input event
        $('#countDown').trigger('input');

        // The input records the distance
        $('#counter').val(100315 - Math.round(oTop));
      }
    });

    // The form is bound to input event
    $('#countDown').on('input', function(e) {

      // Create a special built-in Object 
      var commas = new Intl.NumberFormat('us-US');

      // Get the input's value and convert it into a number
      var c = Number($('#counter').val());

      // The value of output = value of input
      var cV = Number($('#counterView').val());

      // Display formatted value in output
      $('#counterView').val(commas.format(c));

    });
  </script>
</body>

</html>

Upvotes: 1

Mdermez
Mdermez

Reputation: 549

Sometimes the answer is right before our eyes..

                  step: function() {
                    $this.text(Math.floor(this.countNum).toLocaleString());
                  },
                  complete: function() {
                    $this.text(Number(this.countNum).toLocaleString());;
                    //alert('finished');

I need to give all the credit to @PatrickEvans. Thank you.

Upvotes: 2

Related Questions