Right now I have the following code implemented:
$(document).ready(function() {
let maximumFractionDigits = 2;
var valueInput = $("#exampleInput");
const formatNumber = (value) => {
return parseFloat(value.replace(/,/g,'')).toLocaleString('en-US', { maximumFractionDigits });
}
valueInput.on('input', function() {
if (!this.value || (maximumFractionDigits && this.value.endsWith('.'))) {
return
}
$(this).val(formatNumber(this.value));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="exampleInput" aria-label="Grant Amount" type="text" placeholder="0" name="price" required="">
It works fine and does what I want: when the user enters more than 3 digits the thousand comma separator is added and two decimal places are allowed (USD format).
However, if the user enters some number in another charset, for example with a Japanese keyboard, or any unexpected char the following message appears:
'NaN'
Expected outcome:
If the user enters an invalid character, it should not appear in the input (I want to avoid NaN message), for example if I enter 'a' nothing will appear in the input.
What I've tried:
Somehow I tried to use the isNaN function but my approach is definitely wrong.
const formatNumber = (value) => {
if (isNaN(value)){
return 0;
} else{
return parseFloat(value.replace(/,/g,'')).toLocaleString('en-US', { maximumFractionDigits });
}
}
If anyone could help me I would really appreciate it
CodePudding user response:
Well the solution is simple you must check the character right before the input
event, which is the keypress
event.
valueInput.keypress(
/**
* Handle the keypress event on valueInput.
*
* Used to filter in only the numbers.
*/
function(e) {
var keyCode = e.which
if ((keyCode >= 32 && keyCode <= 43)
|| keyCode == 45
|| keyCode == 47
|| (keyCode >= 58 && keyCode <= 126))
return false
}
);
keyCode
is just the ASCII code of the key that is pressed:
- from 32 to 47 these are all symbols. (44 is
,
character and 46 is.
character) - from 58 to 126 these are all other symbols, letters, and parentheses.
Finally, by returning false
when a non-number character is typed in, you basically tell jQuery to refuse it as input. Thus, not firing the input
event and your problem is solved.
CodePudding user response:
Firstly, you need to remove all character except number and point,and remove redundant point. Finally, remove parseFloat because parseFloat('')'s value is NaN.
$(document).ready(function() {
let maximumFractionDigits = 2;
var valueInput = $("#exampleInput");
const formatNumber = (value) => {
const parsedValue = value.replace(/[^\d.]/gi, '').replace(/(?<!^[\d-] )\./g, '');
return parsedValue ? ( parsedValue).toLocaleString('en-US', {
maximumFractionDigits
}) : '';
}
valueInput.on('input', function() {
if (!this.value || (maximumFractionDigits && this.value.endsWith('.'))) {
return
}
$(this).val(formatNumber(this.value));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="exampleInput" aria-label="Grant Amount" type="text" placeholder="0" name="price" required="">
CodePudding user response:
I found a potential solution:
const formatNumber = (value) => {
var result = parseFloat(value.replace(/,/g,'')).toLocaleString('en-US', { maximumFractionDigits });
const withoutCommas = result.replace(/,/g, '');
if (isNaN(withoutCommas)){
return
}
return result;
}
Basically, if after parsing the Float and removing the ',' isNaN=True, then return, if it's a number I can just return the result as expected. Might not be the most elegant solution but it works.