toString().length on a number with zeros and only zeros always returns 0 - javascript

I'm working on a page that accepts 4 digits (exactly 4 digits) pin from users. Something like this.
<input type="number" ng-model="passCode" class="form-control" onpaste="return false" id="passCodeField" ng-disabled="!enablePassCode" ng-change="onInputPasscode()" ng-keypress="onKeyPressPasscode($event)"/>
onKeyPressPasscode function
$scope.onKeyPressPasscode = function($event) {
if(isNaN(String.fromCharCode($event.which || $event.keyCode))){
$event.preventDefault();
}
}
onInputPasscode() function :
$scope.onInputPasscode = function() {
if ($scope.passCode.toString().length > 4){
$scope.passCode = $scope.passcode;
}
if($scope.passCode.toString().length == 4) {
$scope.passcode = $scope.passCode;
$scope.disableContinue = false;
session.put('pinFlow',true);
} else {
console.log("current length - " + $scope.passCode);
$scope.disableContinue = true;
session.put('pinFlow',false);
}
}
This is failing when the input is all zeros. i.e current length is not getting updated hence the user is allowed input as many zeros as he wants. How do I take 4 digit zeros as input and still meet the checks that I have?
This is in angular 1.5.8v. And I'm not an expert in AngularJS. So any help would be appreciated. Also, please let me know if need any other info. I'll update the answer accordingly.
Thanks in advance.

It's not possible to do this with a an input with type set to number.
When user enters a number 0001, that's actually 1.
Things like PINs should be handled with type set to text.
You can then use a regex for validation.
To allow exactly four digits, no more and no less, use the following regex:
^\d{4,4}$
From JavaScript, use this regex to test a string, like the following:
/^\d{4,4}$/.test('1234')
// => true
/^\d{4,4}$/.test('123456')
// => false
/^\d{4,4}$/.test('12')
// => false

The cause of your problem is that if you PIN Scheme allows for leadings zeros, number is not the ideal type for this (because in numbers, leading zeros can be omitted without changing meaning).
Instead, use input type=text or probably even better, input type=password. Also, I wouldn't listen to keypress - instead use the input event.

Related

nativeElement.value is NaN if there is a comma

I'm trying to set the number of decimals at 2 in an input. When I type a comma in it, the value becomes NaN so I would like get my number instead of this.
TS
#ViewChild('number') input;
limitNbOfDecimals() {
var regex =
this.form.number.search(/^(\d+(?:[\.\,]\d{0,2})?)$/) == 0
? true
: false;
if (regex == false) {
// Convert the value to a number
var nb: number = +this.input.nativeElement.value;
//set decimals at 2
this.input.nativeElement.value = nb.toFixed(2);
}
}
HTML
<input class="form-control" type="text" [(ngModel)]="form.number"
#number
name="number"
(input)="limitNbOfDecimals()"
/>
EDIT
I manage to add a comma in the number but if I try to add more than 2 decimals after it removes the numbers after the comma like 1,11 -> 1
This isn't a full answer, in the sense of having a total solution, but hopefully helps you get to one (and it's too long for a comment).
The spec at https://html.spec.whatwg.org/multipage/input.html#number-state-(type=number) states:
This specification does not define what user interface user agents
are to use; user agent vendors are encouraged to consider what would
best serve their users' needs. ..... a user agent designed for the
French market might display the value with apostrophes between
thousands and commas before the decimals, and allow the user to enter
a value in that manner, internally converting it to the submission
format described above.
It would seem that the only sure way - if you don't have control over what browsers your users have - of ensuring they can type numbers in the format they are used to in their local setting is to take input as type text and on each keystroke check that they have typed something valid (as you have defined it) and when they submit it convert to a decimal number.
Searching provides code for doing this, depending on exactly what your requirement is for the number formats though you may be better off coding it from scratch.
To add more than 2 decimal values, you need to tell like .toFixed(4) etc..

Validating numeric input while formatting numeric input

In an asp.net-mvc project using C#.
I use a function to format larger numbers with commas such as 1,000,000, thanks to this post:
function numberWithCommas(str) {
return str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
The issue is, I have the inputs locked down to accept only numbers with a min value of zero.
<input type="number" min="0" class="myclass" value="#somevalue" />
This poses a problem using the JS, as it needs only number input. Which brings me to a question like this How to make HTML input tag only accept numerical values?, which also offers a JS solution.
I'm wondering if anyone has developed an elegant way to format numeric input display, while validating numeric input, is there are any other options available here? It doesn't have to purely be a JS solution.
You can't use the numeric input, because, well, JavaScript doesn't consider formatted number to be a number.
The option is to use the non-numeric input but filter out any "problematic" chars.
In the following example, I'm also handling the dot separator in case you need to accept fractions.
As the text box is being edited, it also has to preserve the cursor position. I've achieved it there with the help of Updating an input's value without losing cursor position.
function format(inp){
var start = inp.selectionStart, // get the selection start
end = inp.selectionEnd; // and end, as per the linked post
var s1=inp.value.split(",").length-1; //count the commas before edit
inp.value=numberWithCommas(inp.value.replace(/,|[^\d.]/g,''));
var s2=inp.value.split(",").length-s1-1; //count the commas after edit so as to know where to place the cursor, as the position changes, if there are new commas or some commas have been removed
inp.setSelectionRange(start+s2, end+s2); // set the selection start and end, as per the linked post
}
function numberWithCommas(str) {
var a=str.split('.');
var p=/\B(?=(\d{3})+(?!\d))/g;
if(a.length>1)
return a[0].toString().replace(p, ",")+"."+a[1];
else
return str.toString().replace(p, ",");
}
<input onkeyup="format(this)">
I have the answer of your first question.
You can disable all keys rather than only numbers keys.
function isNumberKey(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode;
if (charCode != 43 && charCode > 31
&& (charCode < 48 || charCode > 57))
return false;
return true;
}
I also created working demo on jsfiddle
The program flow:
Getting the input via an on change event and calling the other functions, showing passing the data through a Ajax POST.
$('.Amount').on("change", function (e) {
var myInput = $(e.target);
var input = this.value;
// Remove any non digits (including commas) to pass value to controller.
var Amount = validateInput(input);
// Format the string to have commas every three digits 1,000,000 for display.
var val = numberWithCommas(Amount);
$(myInput).val(val);
$.ajax({
type: 'POST',
dataType: "json",
url: somesUrl + '/' + somethingelse,
data: JSON.parse('{"Amount": "' + Amount + '"}'), // Amount is a nice format here and will not throw an error.
// TODO etc
});
});
Remove any non numbers and give a value of zero if no numbers are inputted.
var validateInput = function (input) {
input = input.toString().replace(/[^0-9]/g, "");
/* Remove leading zeros. */
input = input.replace(/^0+/, '');
if (input == "")
input = 0;
return input;
}
Format the input with commas 1,000,000,000.
function numberWithCommas(str) {
return str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
So even if the user types input with commas e.g. 1,734,567 it will work and if they misplace where they put a commas e.g. 17,35,555 it will still validate.
See working fiddle.
I actually worked out a nice solution while trying to meet project deadlines and in part this was solved by this answer by nicael.
This solution does not check the input as it is being typed, but after it is finished, I chose the change event, as opposed to the input event, as it calls the function once and (similar to a submit event) than validates the input in one call. Removing any commas and non digits; solving the issue of formatting with commas, by removing them for the ajax call, then reformatting it with commas for the display. There is a check to remove leading zeros.
If all the input is garbage I replace this value with zero to prevent an error passing to the controller with null data (just a design choice, could display a toast message instead).

How to validate a decimal value input?

Currently working on only decimal values where in the text field user enter only deciaml value. Should accept only 10 numbers for example if user enter 12345.000000 it should get an alert says Number field format error. Please re-enter using the proper format. (6.3)
With my current jquery code it will accept decimal value
$("#txtQty").keyup(function() {
var $this = $(this);
$this.val($this.val().replace(/[^\d.]/g, ''));
});
This is my html code for the text box with this html it will allow only 10 character
<input id="txtQty" type="text" maxlength="10"/>
I tired the below SO user told but still I am getting the same issue
$('#txtQty').focusout(function(e) {
if('123456.789'.match(/^[0-9]{6}\.[0-9]{3}$/) !== null){
alert("Number field format error. Please re-enter using the proper format. (6.3)");
}else{
'123456.7890'.match(/^[0-9]{6}\.[0-9]{3}$/) !== null
}
});
before decimal point it has to accept (1-6) 6 number after decimal point it has to accept 3 only zero's if wrongly typed it should throw an alert not at all working still not getting that
Here is the fiddle link for the same
123456.000 -- true
12345.000 -- true
1234.000 -- true
123.000 -- true
12.000 -- true
1.000 -- true
Thanks in advance
$('.ipt_Havg').focusout(function (e) {
var regexp = /\d*\.\d{3}/
if (document.getElementById("ipt_Havg").value !== regexp) {
alert("Number field format error. Please re-enter using the proper format. (6.3)");
} else {
alert('nothing wrong here');
}
});
1) Your if/else is broken...
if('123456.789'.match(/^[0-9]{6}\.[0-9]{3}$/) !== null){
alert("Number field format error. Please re-enter using the proper format. (6.3)");
}else{
'123456.7890'.match(/^[0-9]{6}\.[0-9]{3}$/) !== null // <- comparison makes no sense here
}
You are incorrectly using a comparison operator in place of a "statement" within the else. The else needs to contain a "statement" (something to do) not another comparison operator.
See: MDN "if...else" documentation
If some condition is true then do something, otherwise do something else.
if ('123456.789'.match(/^[0-9]{6}\.[0-9]{3}$/) !== null) {
alert("Number field format error. Please re-enter using the proper format. (6.3)");
} else {
alert('nothing wrong here');
}
2) NOTE: I previously thought this was too obvious to even mention, however, you've hard coded '123456.789' into the conditional. In other words, it will never matter what value gets entered into your form...
'123456.789'.match(/^[0-9]{6}\.[0-9]{3}$/) is always going to be true since '123456.789' is the only value being used here.
Otherwise, use the value of the field...
$('#ipt_Havg').val().match(/\d*\.\d{3}/) !== null
3) Your logic was also backwards.
if ($('#ipt_Havg').val().match(/\d*\.\d{3}/) !== null) {
alert('nothing wrong here');
} else {
alert("Number field format error. Please re-enter using the proper format. (6.3)");
}
DEMO: http://jsfiddle.net/wfzv0h5y/
4) Incorrect regex...
but one small mistake in the end it has to accept only three zero not more than tht but now if i enter 1234.0000 still it was accepting
Your regex also needed fixing...
^\d{1,6}\.0{3}$
DEMO: http://jsfiddle.net/wfzv0h5y/6/
JQuery Number Formatter Plugin is a good alternative in your situation.
https://github.com/andrewgp/jsNumberFormatter
You can check your input through this and validate the way you want.
You could use HTML5 input number:
<input type='number' step='0.001' max="999999.999" />
The step= sets the decimal places, the max= guarantees the other side.
You can specify repetitions in RegExps:
'123456.789'.match(/^[0-9]{6}\.[0-9]{3}$/) !== null
true
'123456.7890'.match(/^[0-9]{6}\.[0-9]{3}$/) !== null
false

Javascript Regex for Decimal Numbers - Replace non-digits and more than one decimal point

I am trying to limit an input to a decimal number. I'd like any invalid characters not to be displayed at all (not displayed and then removed). I already have this implemented but for whole integers (like input for a phone number) but now I need to apply it for decimal input.
Sample input/output:
default value 25.00 -> type 2b5.00 -> display 25.00
default value 265.50 -> type 2.65.50 -> display 265.50 (as if prevented decimal point from being entered)
default value 265.52 -> type 265.52. -> display 265.52 (same as previous one)
End New Edit
I found many threads that dealt with "decimal input" issue but almost 99% of them deal only with "match"ing and "test"ing the input while my need is to replace the invalid characters.
Other than trying many regexes like /^\d+(\.\d{0,2})?$/, I also tried something like the below which keeps only the first occurrence in the input. This still isn't my requirement because I need the "original" decimal point to remain not the first one in the new input. This was the code for it:
[this.value.slice(0, decimalpoint), '.', this.value.slice(decimalpoint)].join('')
This thread is the closest to what I need but since there was no response to the last comment about preventing multiple decimal points (which is my requirement), it wasn't useful.
Any help would be appreciated.
Outline: find the first ., split there and clean the parts, else just return cleaned value.
function clean(string) {
return string.replace(/[^0-9]/g, "");
}
var value = "a10.10.0";
var pos = value.indexOf(".");
var result;
if (pos !== -1) {
var part1 = value.substr(0, pos);
var part2 = value.substr(pos + 1);
result = clean(part1) + "." + clean(part2);
} else {
result = clean(value);
}
console.log(result); // "10.100"

Decimal Field Validation in Textbox with Jquery or Javascript

I searched on the forum but didn't find the correct answer.
What I am trying is
Textbox which accepts decimal numbers, so user should be able
to enter either 0 or 1 decimal point ie. dot(.)
at the max 5 digits before the dot and at the max 5 digits after the dot
no other character should be allowed, but arrow keys and other keys like f1 f2 should work
eg. it should be valid for following
12345
12345.1
12345.12345
1.12345
.12345
Need help in making this textbox.
Try this:
function isFloat(s) {
return s ? /\d{1,5}(?:\.\d{1,5})?/.test(s) : true;
}
$('input.float').on('change', function() {
if (!isFloat($(this).val())) {
alert('not a float');
}
});
And here's the fiddle: http://jsfiddle.net/foxbunny/Vabj4/
The code doesn't make the field required. If it's empty, it'll just pass. If you can change that by changing true in the ternary conditional to false (line 2).
EDIT:
Oh, and if you want to restrict input to certain keys, you should reconsider. It's not a very good user experience. People are used to typing just about anything. It's best to just warn them. It's cheaper to do and it's effective enough:
http://jsfiddle.net/foxbunny/Vabj4/1/

Categories

Resources