Decimal Field Validation in Textbox with Jquery or Javascript - 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/

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..

How can I make a text box in React which allows only numbers or an empty value, which triggers the number keypad on mobile?

There are lots of questions like this on StackOverflow, but none of them captures all of my requirements in the same solution. Any help appreciated.
The problem
In my React app, I need a text box with the following characteristics:
It only allows digits to be entered - no minus signs, decimal places, letters, or anything besides just the digits 0-9.
It automatically brings up the number keypad on iOS and Android
I can further restrict the numbers that should be entered, e.g. only allow 4 digits
Leading zeroes are automatically trimmed, e.g. if a user types 02 it should correct to just 2
It allows an empty textbox, and can differentiate between empty and a value of 0
Current code
https://codepen.io/micahrl/pen/RwGeLmo
This code allows typing non-digits, and will just interpret the value as NaN. For instance, the user can type 2f or asdf and the page will say You typed: NaN.
Additionally, while the page loads initially with an empty text box, the user cannot type something and then delete it back to empty. Attempting to delete all text in the input box places a 0 in the box.
Finally, this code doesn't reliably trim leading zeroes, which causes me particular problems because I want to restrict the number to four digits. Typing 01 will not truncate the leading zero; on some browsers, typing 01111 will result in 1111, which is good enough, while on others, typing 01111 will result in 0111, which is a problem.
What I've tried
Because I have set type="number" on the input element, if there is ever a non-number added to the text box, event.target.value in setNumWrapper will be an empty string. This means I can't differentiate between a true empty string (where the user has deleted all text) and invalid input (where the user has typed a non-number, like asdf).
I could set type="text" on the input element, except that I think I need to set it to number to get the number keypad on mobile OSes like iOS and Android.
With further experimentation, and some help from #Keith in a comment, I've solved almost all my problems.
I've forked the codepen in my question and made these changes in the fork: https://codepen.io/micahrl/pen/GRjwqdO.
Checking input validity
#Keith pointed me to validity.badInput (https://developer.mozilla.org/en-US/docs/Web/API/ValidityState/badInput). With this, I can differentiate between empty input, where a user types something then deletes it, and bad input, where the user attempts to add a non-numeric character.
That means I add this to the beginning of setNumWrapper():
if (event.target.value === "") {
if (event.target.validity.badInput) {
// Set the text box and number to the old value - ignore the bad input
inputRef.current.value = String(num);
setNum(num);
} else {
// The data in the text box was deleted - set everything to empty
inputRef.current.value = "";
setNum(NaN);
}
return;
}
I also have to make an inputRef with useRef(), and set it on the <input> element.
This solves #5 most of #1 (but see below for one remaining minor problem).
Trimming leading zeroes
All I had to do for this was use that inputRef to set the value in the <input> element at the end of setNumWrapper():
inputRef.current.value = String(newNum);
The <input> element's value is always a string anyway, and casting the number to a string removed leading zeroes, if there were any.
Remaining problem: invalid input is allowed if the text box is empty
When the text box is empty, the user can type non-numeric characters into it, and setNumWrapper() doesn't even fire. If you put a console.log() at the top of setNumWrapper(), it won't print anything to the log if the user types a letter, but it will print to the log if the user types a number.
This means I cannot use setNumWrapper() to solve this problem.
However, it's also relatively minor. On mobile, the number keypad comes up, preventing non-numeric input. On the desktop nothing stops the user from typing letters with their keyboard, but for my app, it's clear that only numbers are allowed, so this is good enough for now.
Still, if there's a way to fix this, I'd be curious to hear about it.

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

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.

Regex replace for commas in the thousands

I have a Javascript function I'm using to loop through a bunch of inputs on a page and convert them to a thousands-compatible comma system. In short, regardless of what the user types into the field, they'll get a friendly thousands-separated number back.
Input: 5000
Return: 5,000
Here's how the function breaks down
function add_commas()
{
$('.field-group .field input[type=text]').each(function()
{
// format number
$(this).val(function(index, value) {
return value
.replace(/\D/g, "")
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
;
});
});
}
Everything's working right except for one thing. Here's another example of the data being passed in and what's returned:
Input: 9.5
Return: 95
Note the whole number.
I'm wondering if there's a way to ignore or leave off the decimal if it didn't have one, but keep it and treat it respectfully if there is one. Here's the input/output as I would hope for:
Input: 5000
Return: 5,000
Input: 9.5
Return: 9.5
Input: 1000.50
Return: 1,000.50
Hopefully this was clear, but please do let me know if you require more information about the issue at hand. Thank you!
Actually regular expressions are not appropriate for this problem, because not every culture uses commas as thousands separators and periods for the radix separator. You should be using toLocaleString. In node, for example:
> (52342.214).toLocaleString()
'52,342.214'
> (52342.214).toLocaleString('de-DE')
'52.342,214'
> (52342.214).toLocaleString('ar-EG')
'٥٢٬٣٤٢٫٢١٤'
> (5234289877.21).toLocaleString('en-US')
'5,234,289,877.21'
This way you don't have to write your own error-prone code and you can localize for different cultures. The work has already been done for you!
You also get the zeros part of your question for free too! Notice:
> (38209).toLocaleString()
'38,209'
> (38209.0000).toLocaleString()
'38,209'
Again, all for free!
Change the first replace because it is removing the dot in the string
.replace(/[^0-9\.]/g, "")

how to have one decimal point for numbers using angularJS

i've seen a few things for regExp but for some reason i'm thinking this should be more simple. Maybe not. Maybe regExp fits this perfectly and i don't understand the concept. Which, i do not. I don't understand regExp and thats why i haven't used it.
but what i am trying to do is build a basic calculator using AngularJS. My calculator has an ng-disable feature for my equals sign. So its not allowed to be pressed and won't work until a leftOperand, operator, and rightOperand are clicked.
Now i don't want to disable the decimal when its clicked, because i might need it for my rightOperand.
But in essence i want my code to reflect "if there is an operator, then the rightOperand is rightOperand + any other Operand entered. Otherwise, the leftOperand is going to equal the leftOperand + any other Operand Entered. (which this is currently working ex. 333 + 45948594 works. The decimal works too. But! it can allow 333.464.6454 and i don't want that).
Trying to implement:
Also/And/Or/If a decimal is put into the leftOperand, then no other decimals are allowed for the leftOperand. If the rightOperand has a decimal, then no other decimals are allowed for the rightOperand.
what is the simplest way to go about this?
https://codepen.io/tevon/pen/Moewba
this is my setDecimal method, but its allowing more than 1 decimal for both the right and left operands
$scope.setDecimal = function (decimalEntered) {
if ($scope.operator){
$scope.rightOperand += decimalEntered;
};
else {$scope.leftOperand += decimalEntered;
};
i was givin something like this: if string.indexOf('.') > -1 // then do something
but honestly, i'm not sure how to about the 'do something' part works, nor the -1 portion
not using Jquery.
So you're building your operand as a string. That means you can test the operand you currently have on your scope to see if it has a point using .indexOf.
if (myVariable.indexOf('.') === -1) myVariable += '.';
You were right when you thought about indexOf - you just need to stop execution of this method if there's already dot there - and easiest way is return
if ($scope.rightOperand.indexOf('.')>-1) return;
LINK

Categories

Resources