Angular Validator check if input is number - javascript

I'm trying to perfom form validation in Angular 9 to check if the value of a certain input is a number (integer or decimal).
I therefore created the following custom validator:
import { AbstractControl, ValidationErrors } from '#angular/forms';
export class NumberValidator {
static number(control: AbstractControl): ValidationErrors | null {
if (typeof +control.value === "number") return null;
return { notANumber: "The value is not a number"};
};
}
It works fine for an integer or decimal input, telling my that it's valid, however it also tells me that the following string value for example "foo" is valid.
How can I fix that?

+ makes string as NaN which type of is number remove it. or if u have to check one more plus of number then
if (typeof +control.value === "number" && !isNaN(+control.value)) return null;

"+" convert variable to number ( +control.value )
So in your example you convert control.value to the number, and then check if this variable is a number. In this way it will be always a number
You need to check:
if Number(control.value) == NaN
// returns true if control.value is string
// else returns parsed number

First of all, the problem comes from the fact that JavaScript returns the type of NaN to be number. So maybe add additional check if the input is also not equal to NaN.

If the user changes the value in the input, the value becomes a string like "123".
This is a string but (in your case) it should be valid. So you have to check if this is parsable.
Better: you can set the input type from text to number
<input type="number" ...
Then it's always a number.
in addition: you can set the built-in validators min an max: https://angular.io/api/forms/Validators

Drawback is that you cannot use type="number" you need to use type="text" on the input but. But here is my solution as ValidatorFn:
function notANumber(): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
const value = control.value
let nV = value
if (typeof value == 'string') {
nV = value.replace(',', '.')
}
return (Number.isNaN(Number(nV)) && !control.pristine) ? {notANumber: true} : null;
};
}

Related

Check if String can be converted to number

I created the following Typescript extension to convert a string to Number:
declare global {
interface String {
toNumber(): number | null;
}
}
String.prototype.toNumber = function(this: string) {
return parseFloat(this);
}
When it is not possible to parse the string to number either because it is invalid, null, undefined, etc I would always like to return null.
How can I do this?
I am assuming you already understand the differences between parseFloat / Number as conversion mechanisms.
Effectively all you need to do is check if the output is NaN. You can do this by:
String.prototype.toNumber = function(this: string) {
const num = parseFloat(this);
return Number.isNaN(num) ? null : num;
}
If you want to return either a non-zero valid number (well, note that NaN is a number, but I think I know what you mean), then check for what you don't want before returning:
Object.defineProperty(String.prototype, "toNumber", {
value: function(str) {
let num = Number(str);
return num === 0 || isNaN(num) ? null : num;
}
});
(Defining properties directly on the prototype is a bad habit and can lead to weird behavior; using .defineProperty gives you a property that is not enumerable.)
Oh, and that's JavaScript, obviously, not Typescript.
A simple answer would be to use return Number(this) || null;
The Number function will convert to a number or NaN, NaN || null will return null (because NaN is falsey).
Updated added testing for zero condition, which with the above code would have also returned null. If that is not what you want, this code will allow zero to return. (Note that this can be done many different ways!):
const parsedValue = Number(this);
return parsedValue === 0 ? parsedValue : parsedValue || null;
Updated to use the parseFloat function, example of early exit for string of '0'. Very similar to the previous updated example.
if (this === '0') {
return 0;
}
return parseFloat(this) || null;

Finding variable types from a string

Pardon if this question has already been answered however I'm struggling to find the any answers to it.
I'm looking to see if I can convert variable types to a string in the code below.
input = prompt('Type something please', 'your input here')
alert(input + ' is a ' + typeof input)
i.e. if the user were to type 1 typeof would return number, or if the user were to enter true it would return a boolean
You can run the input through a series of parseInt, parseFloat and
parseBool
functions.
Whenever you get a valid result, return it.
Something similar to:
if (parseInt(input) != NaN) {
return "int"
}
if (parseFloat(input) != NaN) {
return "float"
}
Generally, all inputs per your example will return a string careless of what they entered or intended to enter. We could however build a few logics to check if what they entered is; Strings (Alphabets only) or an integer (numbers only) or any other ones per a few other logics you could base your checks on.
One of the quickest ways to check if an input contains a number or not;
isNaN(input) // this returns true if the variable does NOT contain a valid number
eg.
isNaN(123) // false
isNaN('123') // false
isNaN('1e10000') // false (This translates to Infinity, which is a number)
isNaN('foo') // true
isNaN('10px') // true
you could try regex (which is not always ideal but works)
var input = "123";
if(num.match(/^-{0,1}\d+$/)){
//return true if positive or negative
}else if(num.match(/^\d+\.\d+$/)){
//return true if float
}else{
// return false neither worked
}
You could also use the (typeof input) but this will be more convenient if your user is going to enter an expected set of entries
var input = true;
alert(typeof input);
// This eg will return bolean
Let me know if this helps.

How to get highest value text while field in same class, id and name?

I want to get value from highest while text field in the same class
I have tried to make a script like this but it does not work.
<input class="resbobot" name="BobotY2" id="BobotY2" type="text"value="100">
<input class="resbobot" name="BobotY3" id="BobotY3" type="text"value="80">
<input class="resbobot" name="BobotY4" id="BobotY4" type="text"value="70">
JS
$(".resbobot").each(function() {
if ($(this).val()===100) {
alert($(this).val());
}
The === operator compares value and type. Your code is comparing the string literal '100' against the number 100. You can use the == operator to ignore the type or use parseInt(..) as #RGS suggested.
$(".resbobot").each(function() {
if(parseInt($(this).val())===100)
{
alert($(this).val());
}
});
You have to check text box value with string data type i.e. ' ' or else with integer data type because you are using equal value and equal type operator.
Demo:
http://jsfiddle.net/h9jap3gp/1/
var max = 0
$(".resbobot").each(function() { if ($(this).val()>max) { max = $(this).val()})
alert(max)
=== Checks type and value, == checks value. So "100" === 100 returns false where "100" == 100 returns true.
To find the highest value from the input fields using jQuery, use the following code:
var highestVal = null;
$('.resbobot').each(function(){
var curVal = Number($(this).val());
highestVal = (highestVal === null || highestVal < curVal) ? curVal : highestVal;
});
alert(highestVal);
The above code will work even if the input values are all negative numbers.

Type of HTML element returned from document.getElementById String not Number

I am obtaining the value of an HTML element by using document.getElementById.innerHTML, and then passing that value to a function that returns the type of the value. I am then using an if / else if block to print out the type of value to the console. My problem, is that the typeof method always returns a type of string. If I don't use document.getElementById and declare the variable directly, typeof returns the correct type. Thanks for your help!
JS Fiddle here: http://jsfiddle.net/sY7uW/
// get innerhtml of div
var LowTemperature = document.getElementById('LowTemperature').innerHTML;
// check type from function return
if(check_type(LowTemperature) === 'number') {
console.log(LowTemperature + " is a number");
}
else if(check_type(LowTemperature) === 'string') {
console.log(LowTemperature + " is a string");
}
// return var type
function check_type(value) {
return typeof value;
}
innerHTML will only return a string. You will need to parse that to an integer.
How do I convert a string into an integer in JavaScript?
You can try to parse the value as an integer, and then compare this back to the original:
if(parseInt(LowTemperature) == LowTemperature) alert("LowTemperature is an integer");
What's happening here is that you're checking the type of number, which exists in string form. Try this instead:
// return var type
function check_type(value) {
//you could also use parseInt or parseFloat here, but that would return a number for a string like "2014 asdf".
//By multiplying by 1, the value will be changed into a number if it is one
var valueNumber = value*1;
return typeof valueNumber;
}
var LowTemperature = document.getElementById('LowTemperature').value;
or
var LowTemperature = parseInt(document.getElementById('LowTemperature').innerHTML);

isFinite of space giving true value

I am trying to validate a price field. I was trying this:
var productId = document.getElementById("productId");
var productName = document.getElementById("productName");
var productPrice = document.getElementById("price");
alert(isFinite(productPrice.value));
if(isNaN(productPrice.value)||!isFinite(productPrice.value)){
error = document.getElementById("priceError");
error.innerHTML = "Please enter correct value";
productPrice.style.border="thin solid red";
}else{
error = document.getElementById("priceError");
error.innerHTML = "";
}
The line alert is giving me true when the input is space/ multiple spaces only.
This is my HTML page.
<td>Price</td>
<td><input type = "text" id = "price" size = "14"/></td>
Thanks
Why this happens i cant say, but this code should solve the problem
isFinite(parseFloat(" ")) // false
// because -->
parseFloat(" "); // => result NaN
// tested in Chrome 27+ on Win7
in the MDN refernce of isNaN here
it says
isNaN(" "); // false: a string with spaces is converted to 0 which is not NaN
Update:
in the Reference of isFinite found Here it states that isFinite only returns false if the argument is:
NaN
positive infinity, (Number.POSITIVE_INFINITY)
negative infinity (Number.NEGATIVE_INFINITY)
In any other Case it returns true. (like Paul S mentioned)
Now i Think i got all loose ends, and in that course learned something. :)
with window.isFinite, you must be aware of the issues that window.isNaN suffers from when coercing types.
window.IsNaN Summary
Determines whether a value is NaN or not. Be careful, this function is
broken. You may be interested in ECMAScript 6 Number.isNaN.
Examples
isNaN(NaN); // true
isNaN(undefined); // true
isNaN({}); // true
isNaN(true); // false
isNaN(null); // false
isNaN(37); // false
// strings
isNaN("37"); // false: "37" is converted to the number 37 which is not NaN
isNaN("37.37"); // false: "37.37" is converted to the number 37.37 which is not NaN
isNaN(""); // false: the empty string is converted to 0 which is not NaN
isNaN(" "); // false: a string with spaces is converted to 0 which is not NaN
// This is a false positive and the reason why isNaN is not entirely reliable
isNaN("blabla") // true: "blabla" is converted to a number. Parsing this as a number fails and returns NaN
In ECMAScript 6 there are new methods Number.isNaN and Number.isFinite that address these issues. (of course these are not available in many browsers)
Number.isFinite is equivalent to
function isFinite(number) {
return typeof number === "number" && window.isFinite(number);
}
So as a solution, you would need to consider something like this (cross-browser).
Note: this solution will still allow you to enter hexadecimal or scientific notations, "0xA", "1e10"
Javascript
function isFinite(number) {
return typeof number === "number" && window.isFinite(number);
}
function trim(string) {
return string.replace(/^\s+|\s+$/g, "");
}
var price = document.getElementById("price");
price.onchange = function (e) {
var evt = e || window.event,
target = evt.target || evt.srcElement,
value = trim(target.value) || "NaN",
number = +value;
console.log("number:", number);
console.log("isFinite:", isFinite(number));
}
On jsfiddle
You could do it using reqular expression.
Try this.
function validatePrice() {
var el = document.getElementById('price');
if (
el.value.length < 14 &&
/^ *\+?\d+ *$/.test( el.value )
)
{
return true;
}
return false;
}
This function checks if the input is positive integer. I didnt know if you want floated values also.
If you do, switch the regex to this /^ *+?\d+((.|,)\d+)? *$/

Categories

Resources