Working with numbers often can be inconvenient if the number is big. 100000000 - what’s that? 10 million or 100 million? Or maybe 1 billion? Admit that 100,000,000 is much more visually friendly and understandable. Even working with 'thousands' we often want to format it for better readability. 100,000 is better than 100000.
This article aims to help developers how to format numbers and, in particular, numbers in inputs
Formatting numbers
There are 3 cool ways to format numbers:
Number.prototype.toLocaleString()
Intl.NumberFormat.prototype.format()
Regular Expressions (RegExp)
1. Number.prototype.toLocaleString()
const number = 400000000000;
$w('#num').text = number.toLocaleString();
The result is 400,000,000,000
2. Intl.NumberFormat.prototype.format()
This method provides greater opportunities than the toLocaleString() method. It can format number in different ways
Example 1:
const num = 1000000000;
$w('#num').text = new Intl.NumberFormat().format(num);
The result is 1,000,000,000
Example 2:
const num = 746376433;
const body = {
style: 'currency',
currency: 'USD',
maximumSignificantDigits: num2.toFixed().length // deletes decimals.
}
$w('#num').text = new Intl.NumberFormat('en-US', body).format(num);
The result is $746,376,433
Example 3:
const num = 299792458;
const options = {
style: 'unit',
unit: 'meter-per-second',
}
$w('#num').text = new Intl.NumberFormat('en-US', options).format(num);
The result is 299,792,458 m/s
3. RegExp
RegExp is a flexible way to format any number or text.
const num = 10000000;
$w('#num').text = String(num).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
The result is 10,000,000
Now you know how to easily format numbers.
Formatting inputs
But what about inputs? Input type ‘number’ prohibits using commas. The right way is to set input type to ‘text’ and to add a RegExp to permit only numbers and certain symbols.
In our case we should allow only numbers, commas, minus (for negative numbers) and dots (for decimals).
You can use these RegExp examples (or set another on your way)
/[^0-9,.-]+/g // allows numbers, comma, dot, minus.
/[^0-9]+/g - // allows only numbers
/\D+/g - // allows only numbers (another way)
Now combine character prohibition in inputs and number formatting:
Example 1:
const input = $w('#input');
input.onInput( () => {
input.value = input.value.replace(/[^0-9,.-]+/g, '');
input.value = input.value.split(',').join('').replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
})
Example 2:
const input = $w('#input');
input.onInput( () => {
input.value = input.value.replace(/[^0-9,.-]+/g, '');
input.value = new Intl.NumberFormat().format(+input.value.split(',').join(''));
})
Catch this
RegExp is more flexible because you can easily change the delimiter. Just change '$1,' to '$1 ' in the replace() method and don't forget to change the delimiter in split(',') to split(' '). And the ‘comma’ delimiter turns to ‘space’.
Finally learn more by reading documentation about these API on MDN or any other websites.
Good luck, guys :)
Hello Miguel. For this simple task you can use new Intl constructor. No necessity to dive deep into regExp
let number = 123456789; let formatted = new Intl.NumberFormat('en', { style: 'currency', currency: 'USD', maximumFractionDigits: '0' }).format(number); console.log(formatted) // $123,456,789
If you want to get $123,456,789.00 - just delete or change maximumFractionDigits property (it stands for fraction digits)
@Vlad Kliots
The following code works great for me. Is there a way to add a "$" (Ex. $100,000)
Also, is there a way to add a decimal point . (ex. $100,000.00 and $100.00)
const input = $w('#input195'); input.onInput( () => { input.value = input.value.replace(/[^0-9,.-]+/g, ''); input.value = new Intl.NumberFormat().format(+input.value.split(',').join('')); })
Thanks for any ideas and help.
Nice post Vlad. But Regex? Seriously? You're just trying to show off. 🍻