Javascript number validation function acting up + constructive criticism wanted - javascript

So the goal was to make a very simple two field form and use javascript to validate that only numeric values are entered in either field.
Two issues with my code: only the else condition of the functions that follow seems to execute. Even more confusingly it also executes just clicking in the other field when the fields are empty.
Help please?
The Javascript:
// 1. Validate that only a numeric value is entered
function validateMin() {
var min = document.getElementById("min").value;
if (isNaN(min)) {
var el1 = document.getElementById("valFailMin");
el1.textContent = "Ok";
} else {
var el1 = document.getElementById("valFailMin");
el1.textContent = "Only numbers";
}
}
function validateMax() {
var max = document.getElementById("max").value;
if (isNaN(max)) {
var el2 = document.getElementById("valFailMax");
el2.textContent = "Ok";
} else {
var el2 = document.getElementById("valFailMax");
el2.textContent = "Only numbers please";
}
}
The HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="custom.css">
</head>
<body>
<div class="myForm">
<label for="min">Min</label><input id="min" type="number" placeholder="Type a min value" onblur="validateMin()"/><br>
<span id="valFailMin"></span>
</div>
<div class="myForm">
<label for="max">Max</label><input id="max" type="number" placeholder="Type a max value" onblur="validateMax()" /><br>
<span id="valFailMax"></span>
</div>
<div id="valSuccess"></div>
</body>
<script src="validate.js"></script>
</html>

isNaN() returns true, if the checked value is not a number, if it is a number, the return value is false. Also the argument is internally coerced to a number before checking it. In this coercion an empty string is evaluated to 0, which is a number, hence the check returns false.
A fix would be to add a not operator to the condition and detect empty value:
if (!isNaN(min) && min !== '') {...}
A general way to check, if a variable is a number:
var isNumber = (!isNaN(+variable) && isFinite(+variable));

In your function:
if (isNaN(min)) {
var el1 = document.getElementById("valFailMin");
el1.textContent = "Ok";
isNaN returns true if the value isn't a number, so this will return "Ok" where min isn't a number. Depending on the type of number you are after, a regular expression may be more appropriate:
if (/^\d+\.?\d*$/.test(min)) {
// min is an integer or float
}
This will return true for values like '5' or '12.3' but false for valid numbers like '1.23e4'.
The number validation function should be separate from the function to validate the fields, so:
function validNumber (value) {
return /^\d+\.?\d*$/.test(value);
}
Then the validation can be something like:
function validateNumberField(el) {
var errField = document.getElementById(el.id + 'Err');
errField.textContent = validNumber(el.value)? 'Ok' : 'Fail';
}
if you pass this from the listener and link the id (or name) of the input being checked to its related error field.
Some markup (simplified for posting):
Min<input id="min" type="number" placeholder="Type a min value"
onblur="validateNumberField(this)"><br>
<span id="minErr" style="color:red"></span><br>
Max<input id="max" type="number" placeholder="Type a max value"
onblur="validateNumberField(this)"><br>
<span id="maxErr" style="color:red"></span>
You may want to allow for an empty value and to remove leading and trailing white.

Related

Script to correct input values set value always to max

I wrote a little script that checks 3 <input>'s for their live value property and should correct them if the live value is higher or lower than the max or min attribute. However, the script also changes the value to the max as soon as a number is entered through the keyboard.
After a couple of hours of testing I still can't figure out why the if-statement always triggers even when the entered live value is below the max-attribute and set it to the max.
document.querySelectorAll('input').forEach(inputListener => {
inputListener.addEventListener('change', function() {
//correct inputs if invalid values have been entered
let active_input = ['#input-cage-width', '#input-cage-depth', '#input-bedding-data-height'];
for (let i = 0; i < active_input.length; i++) {
let value_input = document.querySelector(active_input[i]).value,
min_input = document.querySelector(active_input[i]).min,
max_input = document.querySelector(active_input[i]).max,
element = document.querySelector(active_input[i]);
if (value_input < min_input) {
element.value = min_input;
}
if (value_input > max_input) {
element.value = max_input;
}
}
});
});
<!DOCTYPE html>
<html lang="de" dir="ltr">
<head>
<meta charset="utf-8">
</head>
<body>
<input type="number"
id="input-cage-width"
value="100"
min="10"
max="200">
<input type="number"
id="input-cage-depth"
value="50"
min="10"
max="100">
<input type="number"
id="input-bedding-data-height"
value="25"
min="1"
max="100">
</body>
Because you are dealing with strings and so the comparisons are string comparisons.
For example '55' > '200' returns true when we would expect it to return false.
To fix, replace the line that sets the min/max and value like this, by adding + in front of each value.
let value_input = +document.querySelector(active_input[i]).value,
min_input = +document.querySelector(active_input[i]).min,
max_input = +document.querySelector(active_input[i]).max,
element = document.querySelector(active_input[i]);
The + would attempt to convert a string to a number.
When you input a value in the text box, the value is a String not a Number and therefore the comparisons are not what we expect.
So for example when you enter 55 in the box, that would actually be '55' (with quotes, meaning a string). The same for the max/min.
To see this, you can simply run if('55' > '200') console.log('55 larger than 200!!'); and it will actually show that.
This is the same as if('b' > 'a') console.log('blarger than a!!');
On the other hand, try if(+'55' > +'200') console.log('55 larger than 200!!'); (notice the +). This will not output anything because Number(55) is not larger than Number(200).

How can i avoid NaN error at simple form?

I've got simple form that has to return square root of a number. But i get NaN error. As you can see, variable "number" is number-type. What am i doing wrong?
let number = parseInt(document.getElementById('value'));
function myFunction() {
alert(Math.sqrt(number));
}
<div class="container">
<form>
<fieldset>
<legend>Number squared</legend>
<p><label >Insert number here: </label><input type="number" id="value"></p>
</fieldset>
<p><input type="button" id="button" onclick="myFunction()" value="calculate"></p>
</form>
</div>
First, document.getElementById() returns an HTML element. You would have to access the value property by doing document.getElementById().value. Second, the number variable will always be equal to NaN since that line of code is executed first and is never changed.
let value = document.getElementById('value').value // Evaluates to ""
let number = parseInt(value); // Evaluates to NaN
// The number variable is never re-evaluated when the function is invoked
function() {
alert(Math.sqrt(number));
}
You would have to move that line of code into your function so that the value of number is determined when the function is called, not at the beginning of code execution.
function myFunction() {
const number = parseInt(document.getElementById('value').value)
if (isNaN(number)) {
alert('Please pass in a number')
return
}
alert(Math.sqrt(number))
}
<div class="container">
<form>
<fieldset>
<legend>Number squared</legend>
<p><label>Insert number here: </label><input type="number" id="value"></p>
</fieldset>
<p><input type="button" id="button" onclick="myFunction()" value="calculate"></p>
</form>
</div>
function myFunction() {
const number = +document.getElementById('value').value;
if (isNaN(number)) {
alert('Please pass in a number')
return
}
alert(Math.sqrt(number))
}
It is because document.getElementById() returns the element itself and not the value. You need to get the value of the input to parse it as integer.
Change the code to parseInt(document.getElementById('value').value);
You must get your element value inside your function call, otherwise you will get NaN(Not a number), like this:
function myFunction() {
let number = parseInt(document.getElementById('value').value);
if(number !== "" && number != undefined && number != null && !isNaN(number)){
alert(Math.sqrt(number));
}else{
alert("Please enter valid number");
}
}
You can also check for undefined, null and empty string values.

Why won't my alert work in one of my functions?

I want the nameVerification() function to throw the alert() message when the user hits submit. For example, if the user enters something like 45 in the name field, I want that alert in nameVerification() function to be called. Right now, when the user does type in a number in the name field, the alert() in the formSubmission() function is being called.
Side note:
formSubmissionfunction works perfectly. In other words, if the user enters a number < 13 in the age field, the functions alert() gets called normally with no problems. If the user enters a number > 13, it works, also, without a problem. Just thought I'd let you guys know that too.
signUp.html
<!DOCTYPE html>
<html>
<head>
<title>Signup Form</title>
<script type="text/javascript" src="signUp.js"></script>
</head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="signUp.css">
<body>
<form class="col-md-4 col-md-offset-4" name="formHandler" id="handle">
<div class="moveUsername">
<label for="usr">Name:</label>
<input type="field" class="form-control" id="nameVerify" placeholder="Username" required="required">
</div>
<div class="ageMovement">
<label for="usr" >Age (Must be 13 years or older to play):</label>
<input type="field" class="form-control" id="ageVerify" name="ageChecker" placeholder="Age" required="required">
</div>
<button type="submit" class="btn btn-default" onclick="formSubmission()" onclick="nameVerification()">Submit</button>
</form>
</body>
</html>
signUp.js
function nameVerification() {
var name = document.getElementById("nameVerify").value;
if(typeof name !== 'string') {
alert("That's not a name!");
}
}
function formSubmission() {
var age = document.getElementById("ageVerify").value;
if(age < 13) {
alert("You're too young, you can't play the game");
}
}
age is also a string in this function:
function formSubmission() {
var age = document.getElementById("ageVerify").value;
if(age < 13) {
alert("You're too young, you can't play the game");
}
}
If you want to do a numeric compare, you need to parse first:
function formSubmission() {
var age = document.getElementById("ageVerify").value;
if (age) {
var ageInteger = parseInt(age, 10);
if (ageInteger < 13) {
alert("You're too young, you can't play the game");
}
}
}
You have two onclick attributes on the button
<button type="submit" class="btn btn-default" onclick="formSubmission()" onclick="nameVerification()">Submit</button>
You can only have one
Your typeof test is failing because the value returned from a text input is always of type string. You can test to see if a provided text value is numeric with the following function:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
The real answer, however, is that you'll need to improve your input validation tests to determine what you want, rather than test for all the things you don't want. For example, testing for a numeric value as above would not work if someone entered "t#^!" in the field, which is likely not a value you would want in a name field. This is where regular expressions, and the built-in validations from HTML5 fields can help.
You can change your nameVerification function as follows:
function nameVerification() {
var name = document.getElementById("nameVerify").value;
if (name) {
var num = parseInt(name) || -1;
if (num >= 0 && num < 13) {
alert("That's not a name!");
}
}
}
and change your onclick values in the html to be:
onclick="formSubmission();nameVerification()"
it's because the javascript is not loaded yet.
Move:
<script type="text/javascript" src="signUp.js"></script>
To just above the </body> tag.
You should use parseInt:
var age = parseInt(document.getElementById("ageVerify").value);

Adding Numbers in JavaScript

Please advise how to ADD two numbers in JavaScript. I am not sure where I am going wrong here. Not clear how I need to convert string into integers or Numbers.
function add(){
"use strict";
num1 = parseInt(document.getElementById("firstNumber")).value;
num2 = parseInt(document.getElementById("secondNumber")).value;
parseInt(document.getElementById("result")).innerHTML =num1+num2;
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
<link href="MyStyle.css" rel="stylesheet" type="text/css">
<script src="myEvents.js"> </script>
</head>
<body>
<form>
1st Number : <input type="text" id="firstNumber" /><br>
2nd Number: <input type="text" id="secondNumber" /><br>
<input type="button" onClick="add()" Value="add" />
</form>
<p>Total:
<div id="result">
<input type="text"/> </div>
You're trying to parse the element as an int, and take the value of the int:
parseInt(document.getElementById("firstNumber")).value
Get the value from the element and parse that as an int:
parseInt(document.getElementById("firstNumber").value)
Also, parsing is unnecessary here (and doesn't really make sense when assigning to the property):
parseInt(document.getElementById("result")).innerHTML =num1+num2;
Just assign the property directly:
document.getElementById("result").innerHTML =num1+num2;
parseInt(document.getElementById("result")).innerHTML = num1 + num2;
This makes no sense. I’ll try to give an overview of the objects and functions you’re working with, because one or more of them seems to be being treated as a sort of magic.
Starting with elements:
var firstInput = document.getElementById("firstNumber");
var secondInput = document.getElementById("secondNumber");
document.getElementById is a function that takes a string, finds the element in your document with that id, and returns that element. Here, you’ve selected two <input> elements, which the above snippet assigns to firstInput and secondInput to distinguish them (<input>s) from numbers.
Each input has a value property, which is a string. Verify this in your browser’s console.
console.log(firstInput.value); // whatever you typed in the first box
console.log(typeof firstInput.value); // string
Onwards to parsing, then. parseInt is a function that parses a string into a number. You can try it out in your console, too:
var someString = "192";
var someNumber = parseInt(someString);
console.log(someNumber); // 192
console.log(typeof someNumber); // number
A quick type recap:
firstInput is an element
firstInput.value is a string
parseInt is a function that takes a string and returns a number
so you can use parseInt(firstInput.value) to get your first input’s value as a number. Writing that all out for both inputs,
var firstInput = document.getElementById("firstNumber");
var secondInput = document.getElementById("secondNumber");
var num1 = parseInt(firstInput.value);
var num2 = parseInt(secondInput.value);
Now that you have two numbers, you can add them:
var sum = num1 + num2;
Finally, to put the sum back into the result element, you just have to find that element as usual:
var resultElement = document.getElementById("result");
and assign the sum to its innerHTML.
resultElement.innerHTML = sum;
Recalling that parseInt takes a string and returns a number, now you should realize that no parseInt needs to be involved here. You have a number already – it’s sum. No string is involved.
All together with comments for easy reading, with each line performing fewer steps:
// Get <input> elements
var firstInput = document.getElementById("firstNumber");
var secondInput = document.getElementById("secondNumber");
// Parse the text entered in each into numbers
var num1 = parseInt(firstInput.value);
var num2 = parseInt(secondInput.value);
// Find their sum
var sum = num1 + num2;
// Get the output element
var resultElement = document.getElementById("result");
// Display the sum in the output element
resultElement.innerHTML = sum;
var num1 = parseInt(document.getElementById("firstNumber").value);
var num2 = parseInt(document.getElementById("secondNumber").value);
you have to define the variables and correct the parentheses
function add(){
"use strict";
var num1 = parseInt(document.getElementById("firstNumber").value);
//You need to define your variable before use.
var num2 = parseInt(document.getElementById("secondNumber").value);
console.log(document.getElementById("firstNumber"));
//this is a DOM object
console.log(typeof document.getElementById("firstNumber").value);
//this is a "string"
console.log(typeof parseInt(document.getElementById("firstNumber").value));
console.log(typeof +document.getElementById("firstNumber").value);
//quickly by use '+'
document.getElementById("result").innerHTML =num1+num2;
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
<link href="MyStyle.css" rel="stylesheet" type="text/css">
<script src="myEvents.js"> </script>
</head>
<body>
<form>
1st Number : <input type="text" id="firstNumber" /><br>
2nd Number: <input type="text" id="secondNumber" /><br>
<input type="button" onClick="add()" Value="add" />
</form>
<p>Total:
<div id="result">
<input type="text"/> </div>

Do nothing if an input field is empty and if it has a value check to see if it is numeric and display an alert if it is not

I am trying to make a form that automatically sums input fields on blur and displays the sum in an inactive "Total:" field. I don't want to run anything if a user puts focus in an input then moves focus away without inputting anything and if a user does input something I want to restrict the field to only numbers. If there is a better way of doing this, please let me know. Here is an example of my current approach:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Calc</title>
<script src="javascript.js"></script>
</head>
<body>
<h1>Sales By Month</h1>
<form method="get">
<label for="january">January:</label>
<input type="text" id="january" class="amount" onblur="isNum(); calculateSum();">
<label for="february">February:</label>
<input type="text" id="february" class="amount" onblur="isNum(); calculateSum();">
<label for="total">Total:</label>
<input type="text" id="total" disabled>
</form>
</body>
</html>
JavaScript
function calculateSum() {
var elems = document.getElementsByClassName('amount');
var myLength = elems.length;
sum = 0;
for (var i = 0; i < myLength; ++i) {
sum += elems[i].value *1;
}
document.getElementById('total').value = sum;
}
function isNum() {
var amounts = parseInt(document.getElementsByClassName('amount').value);
if (isNaN(amounts) == true && amounts != '') {
alert("Please enter a numeric value");
}
}
The calculation function currently works but the "Please enter a numeric value" alert pops up every time I tab away from a field regardless of the contents.
First you need to test the value of the element that losts focus, which means you should pass it in the argument like this
onblur="isNum(this); calculateSum();"
then in your isNum function in javascript remove document.getElementsByClassName and use the argument instead ... and don't test if amounts != '' because it will never be equal to empty string while you do this amounts = parseInt(elem.value); you have to test on the elem.value
function isNum(elem)
{
var amounts = parseInt(elem.value);
if (isNaN(amounts) == true && elem.value != '') {
alert("Please enter a numeric value");
}
Here is a jsFiddle

Categories

Resources