This page will show you some ways of checking that the user has entered valid information into a form.
The basic principle is that in the onsubmit event-handler of a form
you return either true or false to let the form submit or not (respectively).
So if the user has not entered valid data you return false to stop the form submitting
(usually accompanied by an alert box telling the user of their mistake).
Generally you will want to make up a function that will check the form's data, and only return true if all is OK. So it could look something like this:
function validateForm(formElement) {
//Check formElement's data here, and return false on error...
//Function will only get this far if there is no error
return true;
}
Obviously that is missing all the actual validation code (which we will get to in a minute), but here is an example of how you would call it in your HTML:
<form action="some_page.php" onsubmit="return validateForm(this);">
So when the user submits the form, it will go through the validateForm
function and check for errors. One common mistake that a lot of people make is to have the
validation function occur when the user clicks the submit button like so:
<input type="submit" onclick="return validateForm(this.form);" />
This is incorrect as that method will only validate the form when the user clicks the submit button.
What happens when the user presses enter in a text-box? The validation routine will not be called,
and your code will be wasted! So just make sure you use the onsubmit
event-handler of the form rather than the onclick handler of the submit button.
A common thing to validate is the length of text, e.g. to make sure have 5 or more characters for a password.
This is fairly simple, as every String object has the length
attribute, which tells you (unsurprisingly) its length.
So let us assume that we have the following form and text-box:
<form action="some_page.php" onsubmit="return validateForm(this);"><p>
<input name="pass" type="password" />
</p></form>
In out validation routine we could check the length something like this:
if (formElement.pass.length < 5) {
alert('Please enter a password that is at least 5 characters long');
return false;
}
So in this example formElement is the form that is calling this function
(remember we passed it into the function with this line of code:
).
Then we refer to the password text-box (return validateForm(this);
) and then its length.
If it is less than 5 then we tell the user and return false which stops the form from submitting.pass
You could also check that the length of the text is not too big:
if (formElement.pass.length > 10) {
alert('Please enter a password that is less than 10 characters long');
return false;
}
Or we could even check that it is between to values:
if (formElement.pass.length < 5 ||
formElement.pass.length > 10) {
alert('Please enter a password that is between 5 and 10 characters long');
return false;
}
The double bar (
) means ||logical or
;
So if the password is less than 5, or greater than 10 then tell the user.
If you just want to make sure that the user has entered a value you could use a simpler method, as shown below:
if (formElement.pass.value == '')
When you are checking for equality you have to use the double equals sign (==).
So the above statement says if the pass field is equal to an empty string (
.''), then do the following…
Sometimes you will want to make sure that the user has entered a valid e-mail address. Well there is some code that you can use to check this, which is listed below:
function validEmail(email) {
var emailRE = new RegExp(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/);
return emailRE.test(email);
}
Then you can test if a text box has a valid e-mail address:
if (validEmail(formElement.email) == false) {
//Tell user to enter a valid e-mail address...
}
Thanks go to Tom Howells for this code.
select listsWith lists we may want to make sure the user has not selected an unwanted value. The way we can find the value of the selected item is:
form.select.options[form.select.selectedIndex].value
So if we had a form like this:
<form action="some_page.php" onsubmit="return validateForm(this);"><p>
<select name="country">
<option value="none">Please choose your country</option>
<option value="United Kingdom">United Kingdom</option>
<option value="Russia">Russia</option>
<option value=""India">India</option>
<option value=""Africa">Africa</option>
</select>
</p></form>
…and we wanted to make sure the value was not none
,
we could do something like this:
if (formElement.country.options[formElement.country.selectedIndex].value == 'none') {
alert('Please choose a country');
return false;
}
We could also do something like this if we omitted a value for the first option
(<option>Please choose your country</option>) like so:
if (formElement.country.options[formElement.country.selectedIndex].value.length == 0) {
alert('Please choose a country');
return false;
}
Select boxes do not always limit the user to selecting only one option.
With the multiple attribute present, the user may select several items.
So if we wanted to check the following list to make sure it has at least one selected option…
<form action="some_page.php" multiple="multiple"
size="5" onsubmit="return validateForm(this);"><p>
Tell us what we need more of on our site:
<select name="need_content">
<option value="nothing">Nothing, your site is perfect!</option>
<option value="news">News</option>
<option value="downloads">Downloads</option>
<option value="pictures">Pictures</option>
<option value="games">Games</option>
</select>
</p></form>
…we could check for it like this:
if (formElement.country.options[formElement.country.selectedIndex].value == -1) {
alert('Please select at least one thing we need more of on our site.');
return false;
}
You can find out if check-boxes and radio buttons are selected (or checked)
by using the checked property:
form.checkbox.checked
Which will return true if it is selected, and false if not. For more details on making sure at least one checkbox or radio button is selected, please see the example form/script below.
confirmBefore I finish with this tutorial and show and example form/script,
I would just like to show you about the confirm prompt.
When you use confirm it presents the user with a message box,
that has OK
and Cancel
buttons. When the user chooses OK
it returns true, and false for Cancel
.
So you can, for example, return a value based on the user's choice:
<form action="some_page.php"
onreset="return confirm('Are you sure you want to reset this form?');"
onsubmit="return confirm('Are you sure you want to continue?');"><p>
<input value="Change this default text, then hit reset or submit." />
<input type="submit" />
<input type="reset" />
</p></form>
You may have noticed in that example there there is also an
event-handler, which is called when the user resets the form.
Try out the above example for an idea of how onresetconfirm works.
So you have learnt how to validate various form elements, but you have not seen a finished example.
Well here is an example, including a function that will focus and select an invalid element
(focusElement) that will help cut down the amount of code you need
(not to mention easier to change in the future):
<script defer="defer" type="text/javascript"><!--
/*Start of form validation:*/
function validateForm(formElement) {
//Check user name is at least 2 characters long
if (formElement.user_name.value.length < 2)
return focusElement(formElement.user_name,
'Please enter a name that is at least 2 characters long.');
//Check password is at least 5 characters long
if (formElement.pass.value.length < 5)
return focusElement(formElement.pass,
'Please enter a password that is at least 5 characters long.');
//Check for valid e-mail address
if (validEmail(formElement.email.value) == false)
return focusElement(formElement.email,
'Please enter a valid e-mail address.');
//Make sure a location is selected
if (formElement.location.selectedIndex == 0)
return focusElement(formElement.location,
'Please select your country.');
//Make sure a location is selected
if (countSelectedOptions(formElement.interests) < 2)
return focusElement(formElement.interests,
'Please select at least 2 of your interests.');
//Make sure we have an action
if (countSelected(formElement, 'radio', 'action') == 0) {
alert('Please choose the action for this submission.');
return false;
}
//Make sure there is at least one of the how did you find out about us
check boxes selected
if (countSelected(formElement, 'checkbox', 'how') == 0) {
alert('Please select how you found out about us.');
return false;
}
//If all is OK, return true and let the form submit
return true;
}
/*End of form validation.*/
/*Below are various functions that can be
re-used in your own validation scripts:*/
function focusElement(element, errorMessage) {
//Tell the user an error has been made
alert((errorMessage.length > 0) ? errorMessage :
'You did not enter valid data; Please try again');
//Select the text in the input box, and focus it (if possible)
if (element.select) element.select();
if (element.focus) element.focus();
return false;
}
function countSelected(formElement, inputType, inputName) {
//If there is no input type, make it checkbox
if (inputType == null) inputType = 'checkbox';
var returnValue = 0;
//Loop for all elements in this form
for (var loopCounter = 0; loopCounter < formElement.length; loopCounter++) {
//If this element is the wanted type
var element = formElement.elements[loopCounter];
if (element.type == inputType && element.checked == true) {
//If we have the correct control name, increment the count
if (inputName.length > 0)
if (element.name == inputName)
returnValue++;
else
returnValue++
}
}
//Return the count
return returnValue;
}
function countSelectedOptions(selectElement) {
var returnValue = 0;
//Loop for all options
for (var loopCounter = 0; loopCounter < selectElement.options.length; loopCounter++)
if (selectElement.options[loopCounter].selected == true)
returnValue++;
return returnValue;
}
function validEmail(email) {
var emailRE = new RegExp(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/);
return emailRE.test(email);
}
/*End of functions.*/
//--></script>
Just in case you are wondering, the
attribute simply tells the
browser not to bother reading through the script until the page has finished loading.
It is not necessary, but if the enclosed script does not have any output
(e.g. no deferdocument.write())
you may as well use it, so that it can help some browsers load the page a little quicker.
And here is the HTML form that works in conjunction with the above script. Just place the script in the same document as this form and it should all work fine.
<form action="some_page.php" onsubmit="return validateForm(this);"
onreset="return confirm('Are you sure that you want to reset this form?');">
<fieldset><legend>Questions:</legend><table
summary="This table holds a questionnaire about our site.">
<caption>Questionnaire</caption>
<colgroup><col /><col /></colgroup>
<tr>
<th><label for="user_name">Name</label></th>
<td><input id="user_name" name="user_name" type="text" /></td>
</tr>
<tr>
<th><label for="pass">Password</label></th>
<td><input id="pass" name="pass" type="password" /></td>
</tr>
<tr>
<th><label for="email"><acronym title="Electronic">E</acronym>-mail</label></th>
<td><input id="email" name="email" type="text" /></td>
</tr>
<tr>
<th><label for="location">Location</label></th>
<td><select id="location" name="location">
<option>Please select your country</option>
<option value="Europe">Europe</option>
<option value="Africa">Africa</option>
<option value="Asia">Asia</option>
<option value="Americas">Americas</option>
<option value="Other">Other</option>
</select></td>
</tr>
<tr>
<th><label for="interests">Your interests</label></th>
<td><select id="interests" multiple="multiple" name="interests" size="5">
<option value="music">Music</option>
<option value="tech">technology</option>
<option value="sci">Science</option>
<option value="sport">Sport</option>
</select></td>
</tr>
<tr>
<th>Action</th>
<td>
<input id="action_email" name="action" type="radio" value="email" />
<label for="action_email"><acronym>E</acronym>-mail to me</label>
<input id="action_board" name="action" type="radio" value="message_board" />
<label for="action_board">Add to message board</label><br />
</td>
</tr>
<tr>
<th>How did you hear about this site?</th>
<td>
<input id="how_friend" name="how" type="checkbox" value="friend" />
<label for="how_friend">from a friend</label><br />
<input id="how_site" name="how" type="checkbox" value="site" />
<label for="how_site">another site</label><br />
<input id="how_search" name="how" type="checkbox" value="search engine" />
<label for="how_search">search engine</label><br />
<input id="how_other" name="how" type="checkbox" value="other" />
<label for="how_other">other</label>
</td>
</tr>
</table></fieldset>
<p><input type="submit" /><input type="reset" /></p>
</form>
You do not need to do all of your validation on the form's onsubmit
event-handler; Most HTML elements have some event,
some of which maybe more appropriate for what you are doing.
For example onblur is called when the element had the focus,
and the user changed to another control (which is usually an indication that they
have finished with the current input field). So we could do something like this for example:
<input name="pass" type="password" onblur="if (this.value.length < 5) { alert('Please enter a value that is at least 5 characters long.'); this.focus(); }"
Another useful event is onchange. This event occurs when an input's
value is changed and has lost focus (one exception to this rule is for the select box,
whose event occurs as soon as you click one of its options):
<select onchange="if (this.options[this.selectedIndex].value == '') alert('Please select a valid option.');">
<option>Select from the list below</option>
<option value="value1">Option 1</option>
<option value="value2">Option 2</option>
</select>
The onclick event can also be handy for elements such as check boxes
and radio-buttons, which is called when their value changes.
keep your validation routines as simple as possible. It is quite easy to get carried away with complex routines, but the more complex your script is the more likely it is to break in other browsers. Always look for the simplest route.