DHTML
Using JavaScript
JavaScript and Forms
Although most people get more excited about window trickery and fancy image swaps, one of JavaScript's most important uses is the good old HTML form. From checking to see if you have supplied all the required fields, to scripts that validate things like email addresses and credit cards, scripts can be written to accomplish all this and more.
Using the Form Object
When you have a form on your page, you have a form object. You should keep in mind that if you do not have any forms on your page, then you can't use a form object.
The form object must always be preceded by the document object, as it is part of the document.
In JavaScript, we don't use the word "form" itself, because that would (sometimes) give
an error. Usually, the form is given a name in the HTML <form> tag like so:
<form action="somescript.cgi" method="post" name="my_form">
So, to reference the above form, you reference it by its name. So you would write it like this:
document.my_form
There is another way to reference a form, even if it is not named. The JavaScript form object is similar to many other objects in that it is also part of an internal array. In this case, we can use the word "forms" to specify the pages forms array. If there is only one form, it can be referenced like so:
document.forms[0]
We recommend however, that you name your forms with meaningful names so that you can easily reference them.
Form Elements
We are going to look at some of the individual form elements as we go in this lecture. Before that however, we should mention that the various elements of the form object (checkboxes, radio buttons, selects, inputs, etc) are all part of another array, the form elements array.
Any element of a form can be accessed by specifying its array index number.
For example, if your form (named my_form)had an input box, then a check box, then
the checkbox could be accessed using the following statement:
document.my_form.elements[1].
Note: Don't try to run any scripts that act on forms if they will run before form loads.
In other words, if you were to try to reference a form or element in the <head>
of the document outside of a function, you would get an error. The best way to work with forms (as we will see) is to
put the script that will act on the form into a function. That way, the script won't try to run
before the form loads.
Focus and Blur
We have already talked about how the focus() and blur() methods of
the window object work, but JavaScript form elements are another thing that can be focused or
blurred. Here's a quick example:
Notice how the cursor switches to Input 1, or Input 2, depending on which link you click. The code for this is very simple:
<p><a href="#" onclick="document.focusform.input1.focus(); return false;">Focus Input 1</a></p>
<p><a href="#" onclick="document.focusform.input2.focus(); return false;">Focus Input 2</a></p>
The form is named "focusform", and the inputs are named "input1", and "input2".
Another way to focus a form element is to click inside it.
Let's have some more fun with this simple little form. You can use event handlers in form elements
too. Here, we will use the onfocus() event handler for these inputs. Click inside
the first form field.
What we did here, is put an onfocus() event handler into the first text input tag like
so:
<input type="text" name="input1" onfocus="alert('Ouch, that smarts!');" />
Now, click inside Input 2. What happens now, is that we placed another onfocus() in the second input tag, setting up another alert. Then we set the focus back to Input 1 again. This kind of thing could be useful for making a user fill in forms in order.
<input type="text" name="input2" onfocus="alert('This is Input 2, Hi there!'); />
You may be wondering why we didn't try to use the onblur() event handler in
that example. The reason is, onblurs can be a little dangerous because if you were to click anywhere
else on the page, you would blur the form, causing the alert box to pop up. While this could be
useful later on for forcing a user to enter information into a field, it is a little harsh. So
take case not to needlessly annoy your users when using onblur().
Validating Forms
Now that forms and the form.elements[] array have been discussed, the best way to learn about JavaScript and forms is by jumping right into some fun stuff. Let's start with a simple script that checks to see if a user has filled in all the required form fields.
Let's say you have a simple form, and all the fields in the form are required. This is the easiest type of form to validate. You just need to loop through the form's elements array, and check to make sure none of them are empty.
function checkForm(the_form) {
for (i = 0; i < the_form.elements.length; i++) {
if (the_form.elements[i].value == "") {
alert('You have not filled in all the required fields');
return false;
}
}
return true;
}
The event handler that called this function would be contained in the <form> tag itself, and would be an onsubmit() event handler:
<form name="example_form" method="post" action="somescript.cgi" onsubmit="return checkForm(this);">
Let's start with the onsubmit() event handler. This event handler is activated when the user clicks the "Submit" button in the form.
You may be wondering what this is. You can think of the this statement as pointing to yourself and saying "this is me". When you use this in any JavaScript statement, you are saying that you want to refer to whatever object you are inside of. Therefore, since this is inside the form tag, this would refer to the form. Words like this are referred to as keywords.
By using return, you are telling the function to return a true or false value. Let's move on to the function.
Inside the function, all we do is take the value passed to the function from the event handler,
(In this case, it would contain document.example_form.) and set up a simple loop to check through
all the form elements. When it finds a value that is equal to nothing (""), then it
returns false, which breaks the loop and stops the form from submitting.
So what happens when you want to do the same validation, but only 3 of the 4 fields are required? Then you can't use the same looping trick. In this case, we need to get a little more creative.
function checkForm(the_form) {
var first = the_form.f_name.value;
var last = the_form.l_name.value;
var address = the_form.address.value;
if (first == "") {
alert('Please enter your first name');
return false;
}
if (last == "") {
alert('Please enter your last name');
return false;
}
if (address == "") {
alert('Please enter an address');
return false;
}
}
Although is takes a lot more typing, this method gives you a little more control over the feedback that the user receives when he/she forgets to fill in a particular field.
Here's an example of this field checking script.
Another major thing that we can do with forms is validate the actual input. The last script was very simple in that it only checked to see if the specified fields were empty. The next validations we will do are to work with what is actually entered into the field to see if the information is correct.
Let's start with a simple email address validation. In our last version of this, we simply checked to see whether or not the @ character exists in the entered string. This time, we will do a little more.
Note: We are not going to check every single possible invalid email address that a user could enter, that would take a lot of script. We are just going to check for some of the more common invalid email addresses that people enter. Namely, the existence and position of the @ symbol (It should not be in the first or last position), the existence and position of the dot (.) in the address. (It should not be in the first, last, or second last position.)
Check out the example of the script first.
Ok, get ready, this is a long script.
function checkForm(the_form) {
var required_array = new Array();
required_array[0] = the_form.f_name.value;
required_array[1] = the_form.l_name.value;
required_array[2] = the_form.address.value;
required_array[3] = the_form.e_mail.value;
for (i = 0; i < required_array.length; i++) {
if (required_array[i] == "") {
alert('You have not filled in all the required fields');
return false;
}
}
var isvalidemail = checkEmail(the_form.e_mail.value);
if (!isvalidemail){
return false;
}
}
function checkEmail(addy) {
var msg = "That is not a valid email address. Please re-type it.";
// Check to see if the @ symbol is in the address, or
// check to make sure the @ symbol is not in the first or last position.
if ((addy.indexOf('@') == -1)||(addy.charAt(0) == '@')||(addy.charAt(addy.length-1) == '@')) {
alert(msg);
return false;
}
// Check to see if a dot exists, or
// make sure that the dot is not in the first, last or second last position.
if ((addy.indexOf('.') == -1)||(addy.charAt(0) == '.')||(addy.charAt(addy.length-1) == '.')||(addy.charAt(addy.length-2) == '.')) {
alert(msg);
return false;
}
return true;
}
FIrst, we have taken the opportunity here to fix up the old version of the previous checkForm function. We took the all the required fields, made an array out of them, then used a loop to check them one at a time to make sure they aren't empty. The old way would have worked fine, but as we add more fields to our form, it would have gotten pretty cumbersome. This way is much more compact.
We added the email checking script as its own function. (checkEmail) This function is called at the end of the checkForm function, after all the fields are checked. In the interest of flexibility, we pass the email address on from here.
Before we start explaining this script to you, we should introduce you to a new method: charAt(). This is a method of the string object, and it works kind of like the reverse of indexOf(). Instead of giving you the position of a given character, it tells you which character is at a given position.
- Once the function is called, it is passed the value of the email input text field.
- We set up a variable to contain the standard alert text, and name it
msg. - Now, we set up a conditional to test for 3 things. This is a rather complicated conditional. It consists of 3 individual conditionals separated by boolean OR (
||) operators. This conditional is saying: If the @ symbol is nonexistent (addy.indexOf('@') == -1) OR if it is at the beginning of the string (addy.charAt(0) == '@') OR if it is at the end of the string (addy.charAt(addy.length-1) == '@'). (In case you were wondering why we haveaddy.length-1instead ofaddy.length, although a string's first position is 0, the length of a string is the amount of characters it contains. The string "hello" contains 5 characters, but its last position is 4. Keep this in mind whenever doing an operation that requires you to get the last character of a string.) - If any of the previous conditions are found, then we alert the user, and have the function return a
falsevalue, which exits the function. - If the @ symbol checks out, we move on to the next function, which basically does the same three conditionals on the dot (.) character this time, then adds another (
addy.charAt(addy.length-2) == "."). You might have already guessed that this last conditional simply looks for the dot in the second last position. (There's no such thing as a one character top level domain name.) - Again, if these conditions are true, then we alert the user, and return a
falsevalue. - If none of the conditions are true, the we move on to the only other statement in the function, which returns a value of
true.
As was stated earlier, this is by far not a fool-proof form, but it does do a couple of quick checks for the more obvious errors, and prevents the form from being submitted if it finds any.
Working with Form Elements
As you have seen, JavaScript can take information entered into form fields, then work with that information. Another thing that JavaScript can do with forms is fill out form fields. Here is an example of what we mean.
The script that accomplished this is actually quite simple.
function fillForm() {
var firstname = prompt('Please type in your first name.',' ');
document.focusform3.first_name.value = firstname;
var lastname = prompt('Please type in your last name.',' ');
document.focusform3.last_name.value = lastname;
}
We know that we can get value from form fields, but we can set them in much the same way. The above script simply gathers your text input into a variable, then sets the specified input text field to that variable.
Advanced Forms
Forms That Calculate
Now that we have shown you some simple form techniques, let's move on to the good stuff. This next form is rather complicated. We have basically added on to our previous form, but with some price calculation functionality. While it might look rather simple, there is quite a lot going on here. We will take a look at how this works bit by bit.
But first, before we go any farther, we will introduce some of the newer concepts presented here.
parseFloat()- Another global function,parseFloat()works much like theparseInt()function you saw earlier, but instead of converting the data to an integer, it converts to a floating decimal point number.Math.round()- TheMathobject is another built-in object that is independent of the DOM. Theround()method of theMathobject takes the number or expression in the brackets, and rounds it off.Math.round()always rounds a number off to the nearest integer.onchange()- This event handler is usually used with a form field or select box. It is activated whenever the user changes the contents of the object.
The first script we will look at is the subCalc() function. It is called whenever the user checks one of the check boxes, changes the quantity number, or presses the "Calculate Total" button. So it is called in three different ways:
With an onclick() on the checkbox (where the variable passed is the name of the form):
<input type="checkbox" name="fishtank" value="yes" onclick="subCalc(document.example_form);" />
With an onchange() event handler in the quantity field:
<input name="fishtank_quant" type="text" id="fishtank_quant" size="3" maxlength="4" onchange="subCalc(document.example_form);" />
From inside the totalCalc() function, that is called when the user clicks the "Calculate Total" button.
Let's look at the subCalc() function. The purpose of this function is to check to see if an item is selected (checked), then multiply the price of the item by the quantity (set to 1 by default) and display the subtotal.
function subCalc(the_form) {
var subtotal = 0;
var subtemp = 0;
// put the prices and form fields into parallel arrays.
var price_array = new Array();
price_array[0] = 54.80;
price_array[1] = 20.00;
price_array[2] = 15.00;
price_array[3] = 28.99;
var item_array = new Array();
item_array[0] = the_form.fishtank;
item_array[1] = the_form.doorstop;
item_array[2] = the_form.paperw;
item_array[3] = the_form.anchorw;
var quant_array = new Array();
quant_array[0] = the_form.fishtank_quant;
quant_array[1] = the_form.doorstop_quant;
quant_array[2] = the_form.paper_quant;
quant_array[3] = the_form.anchorw_quant;
var sub_array = new Array();
sub_array[0] = the_form.sub0;
sub_array[1] = the_form.sub1;
sub_array[2] = the_form.sub2;
sub_array[3] = the_form.sub3;
for(i = 0; i < price_array.length; i++) {
if (item_array[i].checked) {
// If there is no quantity selected, make the quantity 1.
if(quant_array[i].value < 1) {
quant_array[i].value = 1;
}
// Give subtemp the value or the price times the quantity.
subtemp = (price_array[i] * quant_array[i].value);
// Put the converted string into the form field.
sub_array[i].value = checkAmount(subtemp);
// Add the converted number value to subtotal.
subtotal += roundFloat(subtemp);
}
// If the item isn't checked, put nothing into the subtotal field.
else if(!item_array.checked) {
sub_array[i].value = '';
}
}
return subtotal;
}
The above code is fairly well commented out, (as we have said, that's a good thing) so there is not too much more we can say about it. Read the comments to get an idea of what is happening.
You may notice that other functions are being called here, namely checkAmount() and roundFloat(). The reason we need to use these functions is that we are dealing with two different kinds of numbers here. One is a string value that needs to be presented in the form as a nicely formatted dollar and cents amount. (54.80 vs 54.8) The other is the actual number (not a string) that will be added together. Both types of number have to be rounded off.
Let's look at the function that converts a number and keeps it a number, roundFloat().
function roundFloat(num) {
num = parseFloat(num);
num = Math.round(100*num)/100;
return num;
}
We didn't need to comment this one out, as it is quite straightforward and simple.
- This function takes the number that is passed to it (
num), and converts it to a floating point number (just to be sure), with the global functionparseFloat(num). - The second line takes the number, multiplies it by one hundred, rounds that number off, then divides by 100 again. (Remember,
Math.round()rounds a number to its nearest integer value, and we want a floating point value.) - Once done that, it spits the number back out with
return num.
The other called function needs to turn the number into the nicely formatted dollars and cents amount.
function checkAmount(num) {
// Convert into a floating point number.
num = parseFloat(num);
// Round the number off.
num = Math.round(100*num)/100;
// Turn into a string.
num = String(num);
// Look for a decimal point. If none, add it and two zeros.
if (num.indexOf(".") == -1) {
num = num + ".00";
}
// If the decimal point is the second last position, add a zero
if (num.indexOf(".") == num.length -2) {
num = num + "0";
}
// Return the converted string.
return num;
}
Once again, this code is nicely commented. This function contains the exact same two lines of the last one (yes, we could have just called that function here). Then we take that amount, turn it into a string, check to see if it has a decimal point, and add one if it doesn't (20 = 20.00). If the string contains the decimal point (dot) at the second last position, it will add a zero to the end of the string. (54.8 = 54.80). Then it spits out the formatted string.
Once the user has made all the selections, he/she can click the "Calculate Total" button, which calls the totalCalc() function.
function totalCalc() {
var form;
var subtotal;
var pst;
var gst
var total;
form = document.example_form;
// get the value of subtotal from totalCalc.
subtotal = subCalc(form);
// Get 7% of the subtotal.
pst = subtotal * .07;
// Convert and round off as a number.
pst = roundFloat(pst);
// Convert and round off as a string, then put into the PST form field.
form.pst.value = checkAmount(pst);
// Do the same for PST.
gst = subtotal * .07;
gst = roundFloat(gst);
form.gst.value = checkAmount(gst);
// Add the NUMBER values of pst and gst and subtotal.
total = subtotal + gst + pst;
// Convert this number into a string and display.
form.total.value = checkAmount(total);
}
This code is once again well commented, so reading the comments will tell you a lot about what is happening. We don't need any conditionals here, as we aren't checking for anything. Once again, we are using two different numbers, one that gets formatted as dollars and cents, and the other that gets rounded off and is kept as a number for adding or multiplying with other numbers.
You may have noticed that throughout these last scripts, we have been re-using the same variables across functions. We can get away with this because each variable is contained only within that function. Therefore, subtotal in the totalCalc() function is a completely different variable than subtotal in the subCalc() function. We have been using them to display the same values though. (subtotal gets passed between functions and is given the same name, for simplicity's sake.)
Try to make the form display numbers with dollar signs ($).
A Simple Navigation Menu
So far, the one form element we haven't touched on is the select, or drop down menu. These can
also contain an onchange() event handler that gets activated when the user makes a selection.
The select object is also contains a built-in array of all its options. The selectedIndex of
the select object is the option that is selected. Any of the options of a select object can by
accessed like so:
document.the_form.the_menu.options[0].value
If you wanted to get the value of of the option that is selected, you can use selectedIndex as the array number:
document.the_form.the_menu.options[the_menu.selectedIndex].value
We can use this information to create for ourselves a simple, easy JavaScript navigation menu that will jump to another page as soon as the user picks an option.
In the past, similar menus were implemented using a CGI script on the server. This menu required a "Go" button or its equivalent. With the JavaScript menu, no CGI script, or a button is required.
Here is an example of the navigation menu.
Our function will be called from the select itself, in an onchange() event handler.
<form name="example_form" id="example_form" method="post" action="">
<select name="jumpmenu" onchange="goPage(this.form.jumpmenu);">
<option selected="">Select an example page to go to.</option>
<option value="lecture4_1.html">Example1</option>
<option value="lecture4_2.html">Example2</option>
<option value="lecture4_3.html">Example3</option>
</select>
</form>
Here is the function that gets called.
function goPage(gomenu) {
newloc = gomenu.options[gomenu.selectedIndex].value;
if (newloc != '') {
window.location = newloc;
}
}
Here is another script that can be used over and over again. It works by taking the name of the
form and select from the onchange event handler, then it simply puts the value of the option that is selected
into a variable, newloc. The conditional in this function simply checks to make sure that the
value isn't empty. (As the first selection would be.)
One problem with this script is that if the user clicks the browser's back button, the select will still be showing whatever the user had previously picked. It is quite easy to fix this though. Just put an onload() event handler in the <body> tag of the document that sets the select menu back to the first option.
<body onload="document.example_form.jumpmenu.selectedIndex=0">
Another trick you can do here is to put the old "Go" submit button that calls the musty old CGI script into a pair of <noscript></noscript> tags. All you need to do here is to put the action attribute into the <form> tag. If JavaScript is enabled, then the user will never see the "Go" submit button, so there is no way for them to submit the form. If they don't have JavaScript, you are providing them with the same functionality as your JavaScript menu.
<noscript>
<input type="submit" value="Go">
</noscript>
JavaScript and Forms Summary
- The form object in JavaScript is a property of the document object.
- Although you can access a form with the built-in array (
document.forms[x]), it is a good idea to give your forms meaningful names. - Like most objects in JavaScript, your named form can be referenced by its name.
- All of a form's elements are part of another built-in array,
your_form.elements[x]. - You should not let your scripts act on a form before it is loaded into the page. It is best to put form scripts into a function.
- The
focus()method puts the cursor into the specified form element. - The
blur()method is the opposite of thefocus()method. - The
onfocus()andonblur()event handlers are activated when an element is focused or blurred, respectively. - You can easily have JavaScript loop through and check every field to see if it is empty or not.
- To check specific fields, you need conditionals or conditionals and arrays.
- The
thiskeyword refers to the current object (the object it is located in). - You can also use JavaScript to validate the contents of entered data.
- The
charAt()method of the string object gives the character that is contained at the position specified. - When checking for the last character of a string, you use
string.length-1because first position of the string is always 0. - JavaScript can put information into form fields.
- The
parseFloat()global function converts data into a floating point number. - The
round()method of theMathobject rounds a number off to its nearest integer. - The
onchange()event handler is activated when the user changes the data in the form field. - You can refer to any of the options of a select menu by using its internal array. (
your_form.your_select.options[x].value) - You can find out which select option is selected using the
selectedIndexobject. (your_form.your_select.selectedIndex)
DHTML - TOC - Introduction - Books -
Using JavaScript - Links - Questions -
1 - 2 - 3 - 4 - [ 5 ] - 6 -
