Shafizadeh
Shafizadeh

Reputation: 10340

How can I add a comma after each 3 digits?

This is simplified of my code:

$("#annual_sales").on('keyup', function () {
    $(this).val( $(this).val().replace(/(\d{3})/g, "$1,") );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="annual_sales" type="text" />

I'm trying to add a comma after every 3 digits.

The patterns works well here, but as you can see (in the code snippet above) it doesn't work in the JS. Any idea what's wrong?

Upvotes: 3

Views: 5231

Answers (7)

behza_d
behza_d

Reputation: 25

$("#digits_to_update").on('keyup', function() {
  $(this).val($(this).val().replace(/(\d{3}(?!,))/g, "$1,"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="digits_to_update" type="text" />`enter code here`
here  '/(\d{3}(?!,))/g, "$1,") ' change the 3 to 4 or 5 it will seperate the number by 4 or 5 too.

Upvotes: 0

Mentega Terbang
Mentega Terbang

Reputation: 148

Well, you coul've just use this simple trick :

tooltips: {
    callbacks: {
        label: function(tooltipItem, data) {
            let label = data.labels[tooltipItem.index];
            let value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
            return ' ' + label + ' : ' + value.replace(/(.)(?=(.{3})+$)/g,"$1,");
        }
    }
}

Upvotes: 0

Zakaria Acharki
Zakaria Acharki

Reputation: 67505

Doesn't work here since the event fire multiple time, then you need to remove the previous added comma's first every time the event fired and add new ones in the desired positions :

$(this).val().replace(/,/g,'').replace(/(\d{3})/g, "$1,")

** NOTE:** I suggest the use of input event instead since it's more efficient when tracking the use inputs, also you could adjust the regex so the comma will not be added at the end of the line :

/(\d{3}(?!$))/g

$("#annual_sales").on('input', function() {
  $(this).val($(this).val().replace(/,/g, '').replace(/(\d{3}(?!$))/g, "$1,"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="annual_sales" type="text" />

Upvotes: 2

The fourth bird
The fourth bird

Reputation: 163207

In your current pattern (\d{3}) you add a comma after matching 3 digits and also when there is already a comma following the 3 digits.

What you might do is match 3 digits using a negative lookahead (?!,) to assert what follows is not a comma:

(\d{3}(?!,))

$("#annual_sales").on('keyup', function() {
  $(this).val($(this).val().replace(/(\d{3}(?!,))/g, "$1,"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="annual_sales" type="text" />

If you don't want the comma at the end of the line you could use an alternation in the negative lookahead that asserts what follows is neither a comma or the end of the line (\d{3}(?!,|$))

$("#annual_sales").on('keyup', function() {
  $(this).val($(this).val().replace(/(\d{3}(?!,|$))/g, "$1,"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="annual_sales" type="text" />

Upvotes: 2

Damian T.
Damian T.

Reputation: 332

Honestly, I think the best and most straightforward way to accomplish this is not to rely on directly using regex substitution to add a comma. Because regular expressions run from left to right, and in this case we want to parse from right to left, there's really no easy way to do this.

Instead, I would recommend using javascript to do the heavy lifting:

$("#annual_sales").on('keyup', function () {
    var value = $(this).val();
    var match = value.match(/[0-9,.$]+/);    // Match any chars seen in currency
    var new_value = "";
    if (match) {
        var digits = match[0].match(/\d/g);  // Match single digits into an array
        if (digits.length > 3) {
            for (var i = digits.length - 3; i > 0; i = i - 3) {
                // Start at 3 less than the length,
                // continue until we reach the beginning,
                // step down at intervals of 3

                digits.splice(i, 0, ",");    // Insert a comma
            }
            new_value = digits.join("");
            $(this).val(new_value);
        }
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="annual_sales" type="text" />

With this function, you could expand its handling of currency values, such as prepending the value with a dollar sign, or also splitting on a decimal point and forcing two digits following it.

Edit: Scott's answer is a much shorter version of what I am suggesting here (very nice, by the way).

Upvotes: 0

Scott Sauyet
Scott Sauyet

Reputation: 50787

Presumably, you want these commas added from the right as a US-style number separator. This code will do that by reversing before and after adding the commas.

var addCommas = s => s.split('').reverse().join('')
    .replace(/(\d{3})/g, '$1,').replace(/\,$/, '')
    .split('').reverse().join('')  // Really want String.prototype.revese!

$("#annual_sales").on('keyup', function () {
    $(this).val( addCommas($(this).val().replace(/\,/g, '')) );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="annual_sales" type="text" />

(Doing the reverses by converting to an array really makes me want a String.prototype.reverse method.)

If you have to support numbers with more than two decimal places, there would have to be additional work on this function.

Upvotes: 2

Discobarry
Discobarry

Reputation: 64

You need to strip the previously added "," from the value on beforehand like below.

$("#annual_sales").on('keyup', function () {
    $(this).val($(this).val().replace(new RegExp(",", "g"), ""));
    $(this).val( $(this).val().replace(/(\d{3})/g, "$1,") );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="annual_sales" type="text" />

Upvotes: 1

Related Questions