HTML Input type number Thousand separator
JavascriptHtmlJavascript Problem Overview
I want to have a thousand separator (e.g. 1,000,000) in my Input field. However, it has to be of type number because I need to be able to adjust its value using "step". Code:
<input type="number" id='myNumber' value="40,000" step='100'>
I tried using Javascript to adjust the value but didn't work. Any help would be appreciated. Thanks!
Javascript Solutions
Solution 1 - Javascript
Using autoNumeric plugin you can made a field as numeric input with different separators.
Include plugin:
<script src="~/Scripts/autoNumeric/autoNumeric.min.js" type="text/javascript"></script>
Html:
<input type="text" id="DEMO" data-a-sign="" data-a-dec="," data-a-sep="." class="form-control">
Script:
<script>
jQuery(function($) {
$('#DEMO').autoNumeric('init');
});
</script>
You can type only number, if you input 100000,99 you will see 100.000,99.
Solution 2 - Javascript
-
Check this webdesign.tutsplus.com tutorial
-
Final result is summarized here (look at direct Codepen playground)
$("#formInput".on("keyup", function(event ) { // When user select text in the document, also abort. var selection = window.getSelection().toString(); if (selection !== '') { return; } // When the arrow keys are pressed, abort. if ($.inArray(event.keyCode, [38, 40, 37, 39]) !== -1) { return; } var $this = $(this); // Get the value. var input = $this.val(); input = input.replace(/[\D\s\._\-]+/g, ""); input = input?parseInt(input, 10):0; $this.val(function () { return (input === 0)?"":input.toLocaleString("en-US"); }); });
Notes:
-
toLocaleString() javascript function Actually show thousands separator (example and doc)
-
run below code in your console to get the idea
(30000000).toLocaleString('en-US',{useGrouping:true})
Solution 3 - Javascript
You can fake this functionality by using a pseudo-element to display the comma version.
div[comma-value]{
position:relative;
}
div[comma-value]:before{
content: attr(comma-value);
position:absolute;
left:0;
}
div[comma-value] input{
color:#fff;
}
A wrapping div is required because inputs can't have pseudo elements.
<div>
<input type="number" id='myNumber' value="40000" step='100'>
</div>
And a little bit of JavaScript to insert commas every third character
myNumber.value = commify(myNumber.value)
myNumber.addEventListener("change", function(){
commify(event.target.value)
})
function commify(value){
var chars = value.split("").reverse()
var withCommas = []
for(var i = 1; i <= chars.length; i++ ){
withCommas.push(chars[i-1])
if(i%3==0 && i != chars.length ){
withCommas.push(",")
}
}
var val = withCommas.reverse().join("")
myNumber.parentNode.setAttribute("comma-value",val)
}
Check out the fiddle
Solution 4 - Javascript
try
function addCommas(nStr)
{
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
Solution 5 - Javascript
csq recommends using the jQuery autoNumeric plugin. I found it to be very easy and intuitive to use.
My only gripe is that it forces <input type="text">
rather than <input type="number">
. This means you lose the funcionality of step
, but you gain users of your site being able to use commas in fields.
I guess you could use expected values of less than 1,000 as <input type="number">
and values more than 1,000 as <input type="text">
Solution 6 - Javascript
Create a mask input displaying the formatted number. This solution avoids changing the type or the value of the input.
$("input.mask").each((i,ele)=>{
let clone=$(ele).clone(false)
clone.attr("type","text")
let ele1=$(ele)
clone.val(Number(ele1.val()).toLocaleString("en"))
$(ele).after(clone)
$(ele).hide()
clone.mouseenter(()=>{
ele1.show()
clone.hide()
})
setInterval(()=>{
let newv=Number(ele1.val()).toLocaleString("en")
if(clone.val()!=newv){
clone.val(newv)
}
},10)
$(ele).mouseleave(()=>{
$(clone).show()
$(ele1).hide()
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="mask" type="number" value="12345.678"/>
Solution 7 - Javascript
> function addCommas(nStr) { ....
In addition of yovanny's answer I create a Vue component which use this function.
Vue.component("in-n", {
template:
`<input @keyup="keyup" @keypress="isNumber($event)" v-model="text" type="text" />`,
props: ["value"],
data() {
return {
text: ""
}
},
methods: {
addCommas(nStr) {
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
},
isNumber: function (evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
evt.preventDefault();;
} else {
return true;
}
},
keyup() {
this.text = this.addCommas(this.text.replace(/,/g, ''));
this.$emit("input", parseInt(this.text.replace(/,/g, '')))
}
}
})
Solution 8 - Javascript
I found a much simpler answer:
- Start with
<input type="text">
. You can still add min, max and step properties. - Add onfocus and onblur handlers to the
<input>
node:
node.addEventListener('onfocus', () => {
const value = node.value;
node.type = 'number';
node.value = Number(value.replace(/,/g, '')); // or equivalent per locale
});
node.addEventListener('onblur', () => {
const value = node.value;
node.type = 'text';
node.value = value.toLocaleString(); // or other formatting
});
When the user selects the input, it will convert to a regular numeric input with thousands separators removed, but with a normal spinner. When the user blurs the input, it reverts to formatted text.
I add an onkeyup handler that blurs the input when the "enter" key is pressed.