Form Validation Vanilla JS - javascript

I'm building a multipage form and I have some unusual validation requirements. Here's what I'd like to do/what I have done so far.
What I Want to Do:
(1) As each form field is filled in, I want a function to run and check that the user-input has met certain conditions -- i.e. for first and last name, that there are no numbers and there is a space in between the names.
(2) Once each of the field are full and have passed as true, I want another function to run that re-enabled a previously disabled "Next" button that will move the user to the next page of the form.
What I Have Done
(1) Created a mini version of the form with two inputs:
One that takes a first name, a space and a last name
One that takes a phone number set up the following way xxx xxx xxx
(2) I've console.logged the results with pass/fail logic so I know when certain things are being input by the user, that the code is validating properly.
Where I am Stuck:
I do not know how to create the secondary code that will reenabled the previously disabled "next" button that will move the form to the next page.
What I would like to do is make it so when the "Next" button is reenabled, and clicked on, it's own onclick function hides the current page, looks for the next page in the sequence and changes its display:block and I believe I have that code worked out separately, but I don't know how to integrate it with my other needs.
function checkForm()
{
var firstName = document.getElementById("name").value;
var phone = document.getElementById("phone").value;
function checkFirstName()
{
if(firstName == "" || !isNaN(firstName) || !firstName.match(/^[A-Za-z]*\s{1}[A-Za-z]*$/))
{
console.log("Put a first Name and Last Name");
}
else
{
console.log("Thank You");
}
};
checkFirstName();
function checkPhoneNumber()
{
if(!phone.match(/^[0-9]*\s{1}[0-9]*\s{1}[0-9]*$/))
{
console.log("Please Put in a proper phone number");
}
else
{
console.log("Thank you");
cansubmit = true;
}
};
checkPhoneNumber();
};
<form>
First Name: <input type="text" id="name" onblur="checkForm()" /><label id="nameErrorPrompt"></label>
<br />
Phone Number: <input type="text" id="phone" onblur="checkForm()" /><label></label>
<br />
<button id="myButton" disabled="disabled">Test Me</button>
</form>

See below code.
It might be more user-friendly to use on keyup rather than onblur, as most users I know will try and click the disabled button, rather than pressing tab or focusing on another element.
function checkForm() {
var firstName = document.getElementById("name").value;
var phone = document.getElementById("phone").value;
var phoneCanSubmit, nameCanSubmit = false;
function checkFirstName() {
if (firstName == "" || !isNaN(firstName) || !firstName.match(/^[A-Za-z]*\s{1}[A-Za-z]*$/)) {
nameCanSubmit = false;
console.log("Put a first Name and Last Name");
} else {
nameCanSubmit = true;
console.log("Thank You");
}
};
checkFirstName();
function checkPhoneNumber() {
if (!phone.match(/^[0-9]*\s{1}[0-9]*\s{1}[0-9]*$/)) {
phoneCanSubmit = false;
console.log("Please Put in a proper phone number");
} else {
phoneCanSubmit = true;
console.log("Thank you");
cansubmit = true;
}
};
checkPhoneNumber();
if (nameCanSubmit && phoneCanSubmit) {
document.getElementById("myButton").disabled = false;
} else {
document.getElementById("myButton").disabled = true;
}
};
<form>
First Name:
<input type="text" id="name" onblur="checkForm()" />
<label id="nameErrorPrompt"></label>
<br />Phone Number:
<input type="text" id="phone" onblur="checkForm()" />
<label></label>
<br />
<button id="myButton" disabled="disabled">Test Me</button>
</form>

The code below gives you what you want. I removed some extraneous checks to simplify the code and also moved the event handlers from he HTML to the JavaScript. I also pulled the field checks out of the larger checkForm function. This provides you the flexibility to use them one at at time if need be.
window.addEventListener('load', function(e) {
var nameInput = document.getElementById('name');
var phoneInput = document.getElementById('phone');
var myButton = document.getElementById('myButton');
myButton.addEventListener('click', function(e) {
e.preventDefault(); //Stop the page from refreshing
getNextPage('Next page shown!!');
}, false);
nameInput.addEventListener('blur', function(e) {
checkName(this.value);
}, false);
phoneInput.addEventListener('blur', function(e) {
//Uncomment below to make this responsible only for checking the phone input
//checkPhoneNumber(this.value);
/*You could do away with diasbling and check the form
on submit, but if you want to keep the disable logic
check the whole form on the blur of the last item*/
checkForm();
}, false);
}, false);
function getNextPage(foo) {
console.log('Callback fired: ', foo);
//Do something here
}
function checkPhoneNumber(phone) {
if(!phone.match(/^[0-9]*\s{1}[0-9]*\s{1}[0-9]*$/)) {
console.log("Please Put in a proper phone number");
return 0;
}
else {
console.log("Thank you name entered");
return 1;
}
};
//Removed a bit of over coding, no ned to check isNaN or empty string since using regex already
function checkName(firstAndLastName) {
if(!firstAndLastName.match(/^[A-Za-z]*\s{1}[A-Za-z]*$/)) {
console.log("Put a first Name and Last Name");
return 0;
}
else {
console.log("Thank You phone entered");
return 1;
}
};
function checkForm() {
var validCount = 0;
fieldCount = document.forms[0].elements.length - 1; //substract one for the submitbutton!
var phoneNum = document.getElementById('phone').value;
var name = document.getElementById('name').value;
var myButton = document.getElementById('myButton');
validCount += checkPhoneNumber(phoneNum);
validCount += checkName(name);
console.log(validCount + ' of ' + fieldCount + ' fields are valid');
if (validCount > 0 && validCount === fieldCount) {//Compare the inputs to the number of valid inputs
myButton.disabled = false;
}
else {
myButton.disabled = true;
}
}
HTML
<form>
First Name: <input type="text" id="name" /><label id="nameErrorPrompt"></label>
<br />
Phone Number: <input type="text" id="phone" /><label></label>
<br />
<button id="myButton" disabled="disabled">Test Me</button>
</form>

How about you start by making the onblur for each input return a boolean indicating if the field is valid.
Then setting a cansubmit variable (= checkName && checkPhone) in the checkForm function and only moving on after that - then you don't need to enable and disable the button.
If you really want the button to enable you can use the same pattern, but do
document.getElementById("myButton").disabled = !canSubmit;
and you will always want to call checkForm on field blur like you are now.
Also note you aren't scoping canSubmit locally right now.

Related

Form submission validation with JavaScript

I am writing three functions in javascript to do different things. Search functions only needs firstname and lastname. Add and update functions needs everything to filled out completely. I have those working, however when submitting form, if anything is missing, it alerts me but still submits it. I don't want it to do that, how can i do it?
function search() {
checkme = false
//alert('all feilds must be filled out');
var nameExpression = /^[a-zA-Z]+$/;
firstName = document.getElementById('firstName').value;
lastName = document.getElementById('lastName').value;
//check firstname
if (firstName!=""&&nameExpression.test(firstName)) {
checkme = true;
}else{
document.getElementById("firstName").classList.add("is-invalid");
alert("Please enter valid first name");
}
//check lastName
if (lastName!=""&&nameExpression.test(lastName)) {
checkme = true;
}else{
document.getElementById("lastName").classList.add("is-invalid");
alert("Please enter valid last name");
}
return checkme;
}
, here is how i am calling the function as well
<input name="Action" type="submit" name="Search" value="Search" onclick="return search();"">
The reason your function fails to stop submission, is because of a system called event bubbling, where an event propagates up the DOM tree, and any handlers related to that event are triggered. There are also default events that occur on certain actions. Some of these are cancelable events, one of which is the Form Submit event. The e.preventDefault() command basically cancels the default action of the event, which is submitting the form, and prevents it from submitting regardless of the output of your function. We then call the submit() function manually when all requirements are satisfied.
Here's a version that I feel is shorter and easier to understand. No checkme variables needed either. It assumes your form has the id yourForm, and submits it if both first and last names pass the RegEx check.
function search(e) {
e.preventDefault();
const nameExpression = /^[a-zA-Z]+$/;
const firstName = document.getElementById('firstName').value;
const lastName = document.getElementById('lastName').value;
const yourForm = document.getElementById('yourForm');
if (nameExpression.test(firstName) && nameExpression.test(lastName)) {
yourForm.submit();
} else {
alert('All fields must be filled out, and contain only alphabets');
}
}
document.getElementById('yourForm').addEventListener('submit', search);
<form id="yourForm">
<input type="text" id="firstName" placeholder="First Name" />
<br>
<input type="text" id="lastName" placeholder="Last Name" />
<br>
<input name="Action" type="submit" name="Search" value="Search">
</form>
P.S. You can do what you are trying to do here in pure HTML by adding the pattern attribute to your first and last name inputs. This also helps in case the user has an extension like NoScript installed, but the downside is you cannot control how the validation error looks.
(I'm beginner/intermediate in JS) I once also worked on something like this. I would suggest to add a paramater of 'e' in your function, en then writing "e.preventDefault" In your code. It would prevent the default submit action of your form. And then, you can submit the form in JS if it matches a certain condition, and if not, it will give you an alert.
Im guessing checkme, firstName and lastName weren't defined yet.
function search(e) {
e.preventDefault();
var checkme = false;
//alert('all fields must be filled out');
var nameExpression = /^[a-zA-Z]+$/;
var firstName = document.getElementById('firstName').value;
var lastName = document.getElementById('lastName').value;
//check firstname
if (firstName!=""&&nameExpression.test(firstName)) {
checkme = true;
} else {
document.getElementById("firstName").classList.add("is-invalid");
alert("Please enter valid first name");
}
//check lastName
if (lastName!=""&&nameExpression.test(lastName)) {
checkme = true;
} else {
document.getElementById("lastName").classList.add("is-invalid");
alert("Please enter valid last name");
}
if (checkme == true) {
your_form.submit();
}
This may not be a perfect solution to your problem, but this is roughly how I do these things with JS and validating forms. I hope this helped.
Edit:
The code is the author's source code, I tried to not edit it too much.

How to Trigger Validation

How do I force a user to enter a valid time and valid number before pressing the button "Show"?
I have two fields in my html code and I found two good validation scripts in JS. One for time and one to determine if input field has a numeric value.
I can't change anything in the HTML.
function checkTime() {
re = /^\d{1,2}:\d{2}([ap]m)?$/;
if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
alert("Wrong time!");
return false;
}
}
function checkRoomNr() {
var numbers = /^[0-9]+$/;
if (roomopt.value.match(numbers)) {
console.log("is number");
} else {
console.log("not a number!");
}
}
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
</div>
<button id="show-schedule">Show</button>
If you want the validation to take place as data is being entered into the fields, you should set your functions up to run on the input event of the fields. If you want to wait until the user leaves the field and has made changes to the value of the field, then you can use the change event of the fields.
But, you'll also want the data to be checked when the form that contains the fields is submitted, so you need to set up a submit event handler for the form as well.
The way to connect a function to an event is to register the function as an "event handler" and that is done (using modern standards-based code) with the .addEventListener() method:
// First, get references to the elements you'll want to work with.
// And, use those variable names to reference the elements in your
// code, not their IDs.
var timeUntil = document.getElementById("time-until");
var room = document.getElementById("room");
var form = document.querySelector("form");
// We'll set up a variable to keep track of whether there are any errors
// and we'll assume that there are not any initially
var valid = true;
// Set up the event handling functions:
timeUntil.addEventListener("change", checkTime);
room.addEventListener("change", checkRoomNr);
form.addEventListener("submit", validate);
function checkTime(evt){
re = /^\d{1,2}:\d{2}([ap]m)?$/;
if(timeUntil.value != '' && !timeUntil.value.match(re)) {
console.log("Wrong time!");
valid = false; // Indicate an error
} else {
valid = true;
}
}
function checkRoomNr(evt){
var numbers = /^[0-9]+$/;
if(!room.value.match(numbers)){
console.log ("not a number!");
valid = false; // Indicate an error
} else {
valid = true;
}
}
// This function is called when the form is submitted
function validate(evt){
// Invoke the validation functions in case the fields have not been checked yet
checkTime();
checkRoomNr();
if(!valid){
evt.preventDefault(); // Cancel the form's submission
console.log("Submission cancelled due to invalid data");
}
}
<form action="#">
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
<div>
<button id="show-schedule">Show</button>
<form>
function checkTime( val ) { //Pass a value
return /^\d{1,2}:\d{2}([ap]m)?$/.test( val ); //Return a boolean
}
function checkNum( val ) { //Pass a value
return /^\d+$/.test( val ); //Return a boolean
}
const time = document.getElementById("time-until"),
room = document.getElementById("room"),
show = document.getElementById("show-schedule");
function validateForm () {
show.disabled = (checkTime( time.value ) && checkNum( room.value )) === false;
}
[time, room].forEach( el => el.addEventListener("input", validateForm) );
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
</div>
<!-- MAKE BUTTON DISABLED -->
<button id="show-schedule" disabled>Show</button>
Now you can reuse your functions like checkTime( val ) regardless of the input ID.
This may be a starting point basically you need to add event handlers and wire up time_untiloptand time_untilopt and add disabled to the show button. and listen for changes. There many ways, this is just an idea.
const button = document.getElementById('show-schedule');
const time_untilopt = document.getElementById('time-until');
const roomopt = document.getElementById('room');
function checkTime() {
re = /^\d{1,2}:\d{2}([ap]m)?$/;
if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
alert("Wrong time!");
return false;
}
return true;
}
function checkRoomNr() {
var numbers = /^[0-9]+$/;
if (roomopt.value.match(numbers)) {
console.log("is number");
return true;
} else {
console.log("not a number!");
return false;
}
}
function change() {
button.disabled = !(checkTime() && checkRoomNr());
}
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until" onchange="change()">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room" onchange="change()">
</div>
<button id="show-schedule" disabled="true">Show</button>
Inside both of your functions you'll want to set up your variables (time_untilopt and roomopt) to actually point to your two <input> fields. Then you'll simply want to return true if they pass validation, and return false if they don't.
To trigger these checks, you'll want to set up an onlick attribute for your submission, which is tied in to a third function, which I have named show(). This third function should conditionally check that both of the other functions return true. If they do, all is good, and you can continue with the submission. If they're not good, simply return false in this function as well.
This can be seen in the following:
function checkTime() {
re = /^\d{1,2}:\d{2}([ap]m)?$/;
var time_untilopt = document.getElementById('time-until');
if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
return true;
}
else {
console.log("Wrong time!");
return false;
}
}
function checkRoomNr() {
var numbers = /^[0-9]+$/;
var roomopt = document.getElementById('room');
if (roomopt.value.match(numbers)) {
return true;
} else {
console.log("The room number is not a number!");
return false;
}
}
function show() {
if (checkTime() && checkRoomNr()) {
console.log('Both validations passed!');
return true;
}
else {
return false;
}
}
<div>
<label for="time-until">Time</label>
<input type="text" id="time-until">
</div>
<div>
<label for="room">Room</label>
<input type="text" id="room">
</div>
<button id="show-schedule" onclick="show()">Show</button>
Also note that your checkTime() function is actually doing the exact opposite of what you want; if the time is not empty and matches the validation, you want to return true, not false. This has been corrected in the above example.
Hope this helps! :)

Javascript - Enable Submit button when all input is valid

So I have a form with some inputs (First and last name, user name, birthday, password and email) with some validation conditions which I made like this for example :
function checkfnlname(field) {
curr = document.getElementById(field).value;
if ( curr.length > 0) {
updateCSSClass(field, 1);
return true;
}
else {
updateCSSClass(field, 0);
return false;
}}
This changes it's color and return true . I call these function using onKeyUp="". Now what I want to do is make the Submit button disabled until all the fields have been completed and validated by the functions up there. I wrote this function :
function formvalid() {
if (checkfnlname('fname') && && (all other fields)) {
document.getElementByID("submitinput").disabled = false;
}
else {
document.getElementByID("submitinput").disabled = true;
}
return 1;}
But I have no idea how/where to call it. (I tried a lot of things I found but nothing worked)
Is this the right way to do it ? if so how can I call this function ?
Here's a pure ES6 and HTML5 way.
You can watch your form for changes and then check to see if the form is valid.
const form = document.getElementById('form');
form.addEventListener("change", () => {
document.getElementById('submitBtn').disabled = !form.checkValidity()
});
I have modified an example from MDN to show this in action -> https://jsfiddle.net/denov/hxf3knob/2/
My approach:
function updateCSSClass(a, b) {
}
function checkfnlname(field) {
curr = document.getElementById(field).value;
if (curr.length > 0) {
updateCSSClass(field, 1);
return true;
} else {
updateCSSClass(field, 0);
return false;
}
}
window.onload = function () {
var btnSubmit = document.getElementById('submit');
// disable submit
btnSubmit.setAttribute('disabled', 'disabled');
// attach the keyup event to each input
[].slice.call(document.querySelectorAll('form input:not([type="submit"])')).forEach(function (element, index) {
element.addEventListener('keyup', function (e) {
// compute the number of invalid fields
var invalidFields = [].slice.call(document.querySelectorAll('form input:not([type="submit"])')).filter(function (element, index) {
return !checkfnlname(element.id);
});
if (invalidFields.length == 0) {
// reenable the submit if n. of invalid inputs is 0
btnSubmit.removeAttribute('disabled');
} else {
// disable submit because there are invalid inputs
btnSubmit.setAttribute('disabled', 'disabled');
}
}, false);
});
}
<form action="http://www.google.com">
First name:<br>
<input type="text" name="firstname" id="firstname"><br>
Last name:<br>
<input type="text" name="lastname" id="lastname"><br>
User name:<br>
<input type="text" name="username" id="username"><br>
Birthday:<br>
<input type="date" name="birthday" id="birthday"><br>
Password:<br>
<input type="password" name="password" id="password"><br>
email:<br>
<input type="email" name="email" id="email"><br>
<input type="submit" value="submit" id="submit">
</form>
It's simple, invoke button enable/disable function on within your type/value check function, something like this-
function checkfnlname(field) {
//here you can perform input check
curr = document.getElementById(field).value;
if ( curr.length > 0) {
updateCSSClass(field, 1);
return true;
}
else {
updateCSSClass(field, 0);
return false;
}
// to check button validations
formvalid();
}
Going this way, every time you type in the form it'll check it whether the condition for button matches or not, and will function accordingly.!
You need to call the validation function in the events.
// For example
<input type="text" onkeyup="validateForm()">
<select onchange="validateForm()"></select>
Second way:
Instead of using a submit button, use a normal button and call a function which checks your form items.
// Into the form or anywhere you want
<button type="button" onclick="validateForm()">Submit</button>
function validateForm() {
// Code to validate the form items
// if validated, send the form
// For example submitting a form with javascript
document.getElementById("myForm").submit();
}
The easiest way would be to call formvalid() onkeyup for every field. That function validates every field and shows the button if they are valid.
This should do the job, although it is not very efficient. It is a job in vain to check every field every time you type anything on any field. Ex: when you start on the first input there's no point in checking the last.
Instead you could have a check function that updates a global boolean variable when the field has valid data, and then the validate function to check the booleans instead of calling the check function. Then onkeyup in everyfield you should call both separately (first the check, then the validate).
Something like:
validFields=[];
function checkField(field) {
if (conditionIsMet) validFields[validFields.length]=field;
}
function validateForm() {
if (validFields.length==numberOfFields) ...
}
and
<input type="text" name="field1" value="" onkeyup="checkfield(this.name);validateForm()" />

Want to prevent a textbox from becoming empty with javascript

So i already have a textbox in which you can only enter numbers and they have to be within a certain range.The textbox defaults to 1,and i want to stop the user from being able to make it blank.Any ideas guys?Cheers
<SCRIPT language=Javascript>
window.addEventListener("load", function () {
document.getElementById("quantity").addEventListener("keyup", function (evt) {
var target = evt.target;
target.value = target.value.replace(/[^\d]/, "");
if (parseInt(target.value, 10) > <%=dvd5.getQuantityInStock()%>) {
target.value = target.value.slice(0, target.value.length - 1);
}
}, false);
});
<form action="RegServlet" method="post"><p>Enter quantity you would like to purchase :
<input name="quantity" id="quantity" size=15 type="text" value="1" />
You could use your onkeyup listener to check if the input's value is empty. Something along the lines of:
if(target.value == null || target.value === "")
target.value = 1;
}
You could add a function to validate the form when the text box loses focus. I ported the following code at http://forums.asp.net/t/1660697.aspx/1, but it hasn't been tested:
document.getELementById("quantity").onblur = function validate() {
if (document.getElementById("quantity").value == "") {
alert("Quantity can not be blank");
document.getElementById("quantity").focus();
return false;
}
return true;
}
save the text when keydown
check empty when keyup, if empty, restore the saved text, otherwise update the saved text.
And you could try the new type="number" to enforce only number input
See this jsfiddle

Wrapper Function not working properly (Javascript)

I have two functions: One the validates the information in name fields of a form, and another that takes the information in those fields and prints them out in an alert box. Separately these functions work fine. I have to call them both, so I created a wrapper function. The function runs, but it refreshes instead of focusing. The weird thing is, if I check the first field, everything is fine, including the .focus();, but when I try to validate the second field, .focus(); doesn't work and the page refreshes. Any help would be appreciated. (I tried to revise my first question to add this, but when I went to save it, nothing happend.)
function main() {
var test = validate();
if (test == true) {
concatinate();
return true;
}
}
function validate() {
//alert ("TEST!!!");
var first = document.getElementById('firstname').value;
if (first.length == 0 || first.length > 25) {
alert("Please enter your first name, no longer than 25 chracters.");
document.getElementById('firstname').focus();
return false;
}
var last = document.getElementById('lastname').value;
if (last.length == 0 || last.length > 25) {
alert("Please enter your last name, no longer than 25 characters.");
document.getElementsByName('lastname').focus();
return false;
}
var title = document.getElementById('title').value;
if (document.getElementById('title').selectedIndex == 0) {
alert("Please select your salutation");
document.getElementById('title').focus();
return false;
}
return true;
}
function concatinate() {
var first = document.getElementById('firstname').value;
var last = document.getElementById('lastname').value;
var title = document.getElementById('title').value;
var fullname = title + " " + first + " " + last;
var printFull = "Welcome, " + fullname;
alert(printFull);
}
<form name="name" form id="name" method="post" onsubmit="return main();">
Salutation: <select name="title" select id="title">
<option selected="Please Select">Please select</option>
<option value="Mr.">Mr.</option>
<option value="Mrs.">Mrs.</option>
<option value="Miss">Miss</option>
</select><br><br>
First Name : <input type="text" input id="firstname" name="firstname">
Last Name : <input type="text" input id="lastname" name="lastname"><br><br>
<input type="submit" value="Submit"><br><br>
</form>
In your form, you have an erroneous attribute "form" in your <form>, "select" in the middle of the <select> tag, and "input" in the <input> tags. I'm not sure what they are there for, or whether they are causing you trouble, but you should get rid of them nonetheless.
Also, your problem is this line:
document.getElementsByName('lastname').focus();
document.getElementsByName() returns an array, and there is no focus() method on an array. This was causing your issue with validating the last name.
Change it to match your other focus() calls:
document.getElementById('lastname').focus();
I also removed the temporary variable in your main() method:
function main(form) {
if (validate()) {
concatinate();
return true;
}
return false;
}
Working Demo: http://jsfiddle.net/cFsp5/4/
Your main function must return false if validation doesn't pass. Otherwise, it will return undefined, and the form will submit anyway (which is what you describe). So a simple fix would be:
function main() {
var test = validate();
if (test == true) {
concatinate();
return true;
}
return false;
}
http://jsfiddle.net/LhXy4/

Categories

Resources