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! :)
Related
I'm brand new to coding. I've created a form with three fields- two with "number" types and one with radio button selection. I'm trying to utilize "try catch throw" to validate these fields and have error messages echoed onto the screen (not as an alert). I know that there is a lot of code in here, but I am really lost with this. Here is my HTML and js:
HTML:
<form>
<fieldset>
<label for="hshld" class="formhdr">Total number of people in your household:</label>
<input type="number" id="hshld" name="hshld" min="1">
</fieldset>
<fieldset>
<label for="hrrisk" class="formhdr">Number of high-risk people in your household:</label>
<input type="number" id="hrrisk" name="hrrisk" min="0">
</fieldset>
<fieldset>
<legend class="formhdr">Number of weeks in isolation:</legend>
<input type="radio" id="countone" name="headcount">
<label for="countone" class="numweeks">1</label>
<input type="radio" id="counttwo" name="headcount">
<label for="counttwo" class="numweeks">2</label>
<input type="radio" id="countthree" name="headcount">
<label for="countthree" class="numweeks">3</label>
<input type="radio" id="countfour" name="headcount">
<label for="countfour" class="numweeks">4+</label>
</fieldset>
<input type="submit" value="Submit" id="submit">
</form>
and my .js:
//Global variables
var hshld = document.getElementById("hshld");
var mysubmit = document.getElementById("submit");
var radioError = document.getElementById("radioError");
var weekCount;
//this function checks to see if the user entered a number into the field
function validatehshld() {
try {
if (hshld.value == "") {
throw "Enter a number!";
}
hshld.style.outline = "none";
// clear input box
}
catch (hshldError) {
hshld.style.outline = "2.5px dashed red";
hshld.placeholder = hshldError;
return false;
}
}
// makes sure that the radio button is selected. If not, throws an error message into the "radioError" paragraph at under the form.
function validatewkCount() {
try {
if (weekCount == 0) {
throw document.getElementById('radioError').innerHTML = "Select a number!";
}
// clear input box
hshld.style.outline = "none";
}
catch (weekCountError) {
radioError.style.outline = "2.5px dashed red";
radioError.placeholder = radioError;
return false;
}
}
// stop the form from submitting if a field needs attention
function endEvent() {
return event.preventDefault();
}
function validateSubmit() {
if(validatehshld() === false && validatewkCount() === false) {
endEvent();
}
}
// EventListeners, includes IE8 compatibility
if (hshld.addEventListener) {
hshld.addEventListener("focusout", validatehshld, false);
} else if (hshld.attachEvent) {
hshld.attachEvent("onclick", validatehshld);
}
// runs validateSubmit() function when the user clicks the submit button
if (mysubmit.addEventListener) {
mysubmit.addEventListener("click", validateSubmit, false);
} else if (mysubmit.attachEvent) {
mysubmit.attachEvent("onclick", validateSubmit);
}
if (mysubmit.addEventListener) {
mysubmit.addEventListener("click", numBottles, false);
} else if (mysubmit.attachEvent) {
mysubmit.attachEvent("onclick", numBottles);
}
// this function gets called via the onclick attribute (line 44)
function numBottles() {
// takes the current value of the input field from id "hshld"
var people = document.getElementById("hshld").value;
var hrrisk = document.getElementById("hrrisk").value;
// this variable represents the number of gallons a single person should have for one week of isolation- 1 gallon per day
var weekWater = 7;
// this variable will hold the number of weeks selected from the radio buttons
var weekCount;
// this code determines which radio button is selected and assigns a value to the variable depending on which radio button is selected
if (document.getElementById('countone').checked) {
var weekCount = 1;
} else if (document.getElementById('counttwo').checked) {
var weekCount = 2;
} else if (document.getElementById('countthree').checked) {
var weekCount = 3;
} else if (document.getElementById('countfour').checked) {
var weekCount = 4;
} else if (isNaN(weekCount) === true) {
var weekCount = 0;
}
// echo out the calculation (people X weekWater) to the span object with id=bottles
document.getElementById("bottles").innerHTML = (people * weekWater * weekCount) + (hrrisk * weekCount);
}
Try not to use try, catch, or throw here, instead create your error message in a new element and place it in the html somewhere you think it looks nice.
I would just use:
if (typeof hshld.value !== 'number') { // if a wrong data type was entered
document.getElementById("error-zone").innerHTML += "<div>Enter a number!</div"
} else {
// continue calculating answer
}
for the quick and dirty method.
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.
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()" />
I would like to validate myForm, so the user can input a value between 1 and a max on 99. When I submit a number I get showed a blank page, which is the select.php. But I would like to stay on my indexpage, and get the message "You are below". Can anyone see what is wrong here?
index.html:
<div class="content">
<p id="number"></p>
<div class="form">
<form id="myForm" action="select.php" method="post">
<input type="number" name="numbervalue" id="numberinput">
<input type="submit" id="sub" Value="Submit">
<span id="result"></span>
<span id="testnumber"></span>
</form>
</div>
</div>
JS:
var minNumberValue = 1;
var maxNumberValue = 99;
$('#sub').click(function(e){
e.preventDefault();
var numberValue = $('input[name=numbervalue]').val();
if(isNaN(numberValue) || numberValue == ''){
$('#testnumber').text('Please enter a number.')
return false;
}
else if(numberValue < minNumberValue){
$('#testnumber').text('You are below.')
return false;
}
else if(numberValue > maxNumberValue){
$('#testnumber').text('You are above.')
return false;
}
return true;
});
// Insert function for number
function clearInput() {
$("#myForm :input").each( function() {
$(this).val('');
});
}
$(document).ready(function(){
$("#sub").click( function(e) {
e.preventDefault(); // remove default action(submitting the form)
$.post( $("#myForm").attr("action"),
$("#myForm :input").serializeArray(),
function(info){
$("#result").html(info);
});
clearInput();
});
});
// Recieve data from database
$(document).ready(function() {
setInterval(function () {
$('.latestnumbers').load('response.php')
}, 3000);
});
How about utilizing the 'min' and 'max' attributes of the input tag, it would handle all the validation itself:
<input type="number" name="numbervalue" min="1" max="99">
Cheers,
Here's a little function to validate the number:
var minNumberValue = 1;
var maxNumberValue = 99;
$('#sub').click(function(e){
e.preventDefault();
var numberValue = $('input[name=numbervalue]').val();
if(isNaN(numberValue) || numberValue == ''){
$('#result').text('Please enter a number.')
return false;
}
else if(numberValue < minNumberValue){
$('#result').text('You are below.')
return false;
}
else if(numberValue > maxNumberValue){
$('#result').text('You are above.')
return false;
}
return true;
});
You can define the minimum and maximum values by changing the two variables (be sure to check these server-side too if you are submitting to a server, as the user could manipulate the code via dev tools to change these boundaries or submit whatever they want).
The result message is displayed in your span#result, otherwise you could use alert() too.
The important things here are the e parameter in the click function (it's the JavaScript event), calling e.preventDefault() (if you don't do this, the form will submit before finishing validation, as the default action for an input[type=submit] is to submit a form [go figure...]), returning false whenever the conditions aren't met, and returning true if it satisfies the validation. The return true; allows the form to follow its action parameter.
And a fiddle with this: https://jsfiddle.net/3tkms7vn/ (edit: forgot to mention, I commented out return true; and replaced it with a call to add a message to span#result just to prevent submission on jsfiddle.)
I got most of this form validation to work properly but the only issue is that when the form detects an error on submit and the user corrects the mistake, the error text won't go away. This can be confusing for the user but I can't seem to figure out a way to make the error text disappear with the way that I am doing this. Also I know I have the option of PHP validation but there is a few reasons why I want to use this front end validation. Here is the whole validation script for the form. The submit portion is at the bottom:
JavaScript/jQuery
var valid = 0;
function checkName(elem) {
//gather the calling elements value
var val = document.getElementById(elem.id).value;
//Check length
if (val.length<1) {
document.getElementById("errorName").innerHTML = "<span>Don't forget your name.</span>";
} else if (val.length>40){
document.getElementById("errorName").innerHTML = "<span>This doesn't look like a name.</span>";
//If valid input increment var valid.
} else {
document.getElementById("errorName").innerHTML = "";
valid++;
}
}
function checkEmail(elem) {
var val = document.getElementById(elem.id).value;
//Check email format validity
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!re.test(val)) {
document.getElementById("errorEmail").innerHTML = "<span>Please enter a valid email.</span>";
} else {
document.getElementById("errorEmail").innerHTML = "";
valid++;
}
}
function checkMessage(elem) {
var val = document.getElementById(elem.id).value;
if (val.length<1) {
document.getElementById("errorMessage").innerHTML = "<span>It looks like you forgot the message.</span>";
} else if (val.length>2000) {
document.getElementById("errorMessage").innerHTML = "<span>It looks like your message is too long.</span>";
} else {
document.getElementById("errorMessage").innerHTML = "";
valid++;
}
}
//Contact: jQuery check for null/empty/errors
$(document).ready(function() {
function checkSubmit() {
if (valid == 3) {
document.getElementById("errorSubmit").innerHTML = "";
}
}
//If errors when submitting display message
$('#form13').submit(function(submit) {
if ($.trim($("#name").val()) === "" || $.trim($("#email").val()) === "" || $.trim($("#message").val()) === "") {
document.getElementById("errorSubmit").innerHTML = "<span>Please fill out all the form fields.</span>";
submit.preventDefault();
} else if (valid < 3) {
document.getElementById("errorSubmit").innerHTML = "<span>Please check the errors above.</span>";
submit.preventDefault();
}
})
});
HTML Form
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="cform" id="contact-form">
<form id="form13" name="form13" role="form" class="contactForm" accept-charset="UTF-8" autocomplete="off" enctype="multipart/form-data" method="post" novalidate
action="https://Some3rdPartyPOSTService">
<div class="form-group">
<label for="name">Your Name</label>
<input type="text" name="Field1" class="form-control" id="name" placeholder="Tony Stark" onblur="checkName(this)"/>
<span id="errorName" style="margin-left:10px;"></span>
</div>
<div class="form-group">
<label for="email">Your Email</label>
<input type="email" class="form-control" name="Field4" id="email" placeholder="" data-rule="email" data-msg="Please enter a valid email" onblur="checkEmail(this)"/>
<span id="errorEmail" style="margin-left:10px;"></span>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea class="form-control" name="Field3" id="message" rows="5" data-rule="required" data-msg="Please write something here" onblur="checkMessage(this)"></textarea>
<span id="errorMessage" style="margin-left:10px;"></span>
</div>
<span id="errorSubmit" style="margin-left:10px;"></span>
<button type="submit" class="btn btn-theme pull-left">SEND MESSAGE</button>
</form>
</div>
</div>
<!-- ./span12 -->
</div>
</div>
</section>
Simply put your check on onChange event callback, if:
var x = getElementById("formid"); // then add a listener
x.addEventListener('change', function () {
callback with your code that examines the form
});
Or listen for a specific text box change event, that would be the simplest way, and look for a way to disable submit if the conditions aren't met.
Add an onchange event to your text inputs that will remove the error message.
Rather than making a count of valid fields, I would also check for the existence of error messages. This will make it easier to add more fields to your form.
function checkName(e) {
//gather the calling elements value
var val = $(e.target).val();
//Check length
if (val.length<1) {
document.getElementById("errorName").innerHTML = "<span class="errmsg">Don't forget your name.</span>";
} else if (val.length>40){
document.getElementById("errorName").innerHTML = "<span class='errmsg'>This doesn't look like a name.</span>";
//If valid input increment var valid.
} else {
document.getElementById("errorName").innerHTML = "";
}
}
function checkEmail(e) {
var val = $(e.target).val();
//Check email format validity
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!re.test(val)) {
document.getElementById("errorEmail").innerHTML = "<span class='errmsg'>Please enter a valid email.</span>";
} else {
document.getElementById("errorEmail").innerHTML = "";
}
}
function checkMessage(e) {
var val = $(e.target).val();
if (val.length<1) {
document.getElementById("errorMessage").innerHTML = "<span class='errmsg'>It looks like you forgot the message.</span>";
} else if (val.length>2000) {
document.getElementById("errorMessage").innerHTML = "<span class='errmsg'>It looks like your message is too long.</span>";
} else {
document.getElementById("errorMessage").innerHTML = "";
}
}
//Contact: jQuery check for null/empty/errors
$(document).ready(function() {
$('#name').change(checkName);
$('#email').change(checkEmail);
$('#message').change(checkMessage);
function checkSubmit() {
if ($('form .errmsg').length > 0) {
document.getElementById("errorSubmit").innerHTML = "";
}
}
}
/If errors when submitting display message
$('#form13').submit(function(submit) {
if ($.trim($("#name").val()) === "" || $.trim($("#email").val()) === "" || $.trim($("#message").val()) === "") {
document.getElementById("errorSubmit").innerHTML = "<span class='errmsg'>Please fill out all the form fields.</span>";
submit.preventDefault();
} else if ($('form .errmsg').length > 0) {
document.getElementById("errorSubmit").innerHTML = "<span class='errmsg'>Please check the errors above.</span>";
submit.preventDefault();
}
})
});
Since you were already using jQuery, I modified the code to use more of the jQuery functionality to make things easier. Now when a form field is modified and the element loses focus, the validation will occur immediately. We also no longer need to know how many error messages could potentially appear (though you never had a decrement operation for corrected values so the valid could become greater than 3). Instead we just make sure that there isn't more than 0 of them.
I've removed your onblur html attributes and replaced them by JavaScript keyup events. This will allow your script to check everything as soon as the user type something :
document.getElementById("message").addEventListener('keyup', function () {
checkMessage(this);
});
document.getElementById("email").addEventListener('keyup', function () {
checkEmail(this);
});
document.getElementById("name").addEventListener('keyup', function () {
checkName(this);
});
JSFIDDLE