Form Validation
CSCI 2910-001 In-Class Exercise

You should be able to...

This exercise has three purposes:

JavaScript Arrays

Up to this point, we've concentrated mostly on declaring variables in JavaScript. The var keyword can be used to declare a variable to hold a numbers or a string. From your programming classes, however, you should have learned about arrays. JavaScript can declare arrays too.

As you recall, an array is a list of objects. Each object within the array can be referenced using an index. In JavaScript, the first object in the list has the index 0. If the program language you're familiar with begins arrays with an index of 1, you will need to adjust for JavaScript starting its index with 0. For example, we may have an array names containing a list of peoples names, e.g., "Will", "Lori", "James", and "Beth".

In JavaScript, an array is an object, and is therefore declared using the keywords new Array. The keyword Array is followed by parenthesis containing arguments passed to the object constructor. These arguments can take one of two forms. First, the arguments may be a list of initial values. From this list, the interpreter knows how many index values to allocate to the array and what initial values to give each array element. For example, the above array names could be initialized with the code shown below.

var names = new Array("Will", "Lori", "James", "Beth");

You can also create a new array of a specific size without initializing the elements by using an integer as the argument of Array. For example, the following code creates an array called cars of size 4, i.e., it has index values 0, 1, 2, and 3.

cars = new Array(4);

The elements of the array act just like variables in that you can modify them or use them to define other elements. For example, if we wanted to change "Will" to "Bill", we would simply use the assignment operator.

names[0] = "Bill"

Later in this lesson, we will use arrays to point to a list of images.

Some Useful Properties and Methods of Arrays

There are a number of properties and methods of arrays that can be used when accessing or manipulating the data in an array.

length -- This property represents the length of the array. It is useful when it comes to looping through an array to process data. For example, the following code would output all of the elements of an array of strings.

for(i = 0; i < array_name.length; i++)
    document.writeln(array_name[i]);

concat(array_name0, array_name1, ...) -- This method allows the programmer to join two or more arrays.

join(separator) -- This method takes an array of strings and turns it into one long string. The separator is placed between each array element, the default being a comma. Take for example the following code:

var my_array = new Array("The", "dog", "chased", "the", "ball.");
var my_string = my_array.join(' ');

After executing this code, the variable my_string will contain the string "The dog chased the ball."

pop() -- This method removes and returns the last element of an array thereby shortening it by one.

push(element0, element1, ...) -- This method adds the elements passed to it as arguments and returns the new length of the array.

Rollovers

One of the most common JavaScript functions is to create image rollovers. Basically, an image rollover watches the events onMouseOver and onMouseOut for a specific XHTML element in order to change the source file of an image. In order to do this, the programmer must:

Let's begin this exercise by copying some images to your directory. There are a couple of image exercises in this lab, so let's copy all of the necessary images to your cscidbw folders. Right click on each of the images below and save them in a folder you've defined on your cscidbw account as cscidbw/zabc123/inclass/html/images. Each of the images is named image0?.jpg. Keep these names so that the exercises here will work.

Save to your image folder as image00.jpg Save to your image folder as image01.jpg Save to your image folder as image02.jpg
Save to your image folder as image03.jpg Save to your image folder as image04.jpg Save to your image folder as image05.jpg

Now create the XHTML file for this rollover exercise by opening your XHTML template and storing it in your cscidbw/zabc123/inclass/html folder under the file name "rollover.htm".

In the body you will need to add an image tag. Identify this image with the name and id attributes set to "my_image", give it a width of 200, a height of 100, and a border of 0. Last of all, set the src equal to the first image, i.e., images/image00.jpg.

For now, let's forgo the creation of a function and simply have the onMouseOver and onMouseOut events change the source of our image. Inside the image tag, add the event onMouseOver = "my_image.src='images/image01.jpg';" and onMouseOut = "my_image.src='images/image00.jpg';". Your image tag should now look something like:

<img src="images/image00.jpg" name="my_image" id="my_image" onMouseOver="document.my_image.src='images/image01.jpg';" onMouseOut="document.my_image.src='images/image00.jpg';" border="0" width="200" height="100" />

Save your page and test it. Does the glass/pen image get replaced with the sunset picture when the mouse goes across the image and the switch back when the mouse comes off?

Since a page with rollovers usually has many of them, we should make a function to handle the image swapping. This function should take as its arguments the name/id of the image so as to identify which img tag is getting its source changed and the URL of the image to take the place of the previous one. The code below suggests a prototype for such a function. Place it between script tags in the head of your page.

function swapImage(image_to_change_id, src_of_new_image)
{

}

The image name/id is not quite a complete reference to the img object. We need to build the rest of the object identification by showing that it is part of this document. The JavaScript function eval(string) is used to evaluate or execute JavaScript code or operations found in the argument "string" and return the result. Therefore, we can use eval to combine the string "window.document." with the image's name/id to come up with a reference to the image.

var image_to_change = eval("window.document." + image_to_change_id);

Now that we have a reference to the image that will have its source changed, it is now just a matter of flipping it.

image_to_change.src = src_of_new_image;

Placing both of these lines of code within the function brackets should give us a generic rollover function. Add these two lines to your function.

Now that we have a function, let's replace the onMouseOver and onMouseOut events in our image tag with function calls.

<img src="images/image00.jpg" name="my_image" id="my_image" onMouseOver="swapImage('my_image', 'images/image01.jpg');" onMouseOut="swapImage('my_image', 'images/image00.jpg');" border="0" width="200" height="100" />

Slide Show

Now that we know how to load an image and change its source, we have the tools to create a slide show. A slide show needs two additional features over that of a rollover:

Start this part of the exercise by saving your "rollover.htm" file as "slides.htm". Now let's create an array. Remember from the array discussion at the beginning of this exercise that we must declare an array using the "new Array" statement. We will start by declaring a generic array. Do this between the script tags inside the head, but before the function declaration, i.e., we're going to make this array a global variable.

var image_srcs = new Array();

Now that we have an array declared, let's populate it with the URLs of the images that you downloaded earlier. The array is going to be an array of image objects. Therefore, let's initialize the first element of the array by making it a new Image. Immediately after the array declaration, add the line:

image_srcs[0] = new Image(200,100);

This will make the first element of the array an image object with a width of 200 pixels and a height of 100 pixels. Now let's define the image's source URL. Remember that an earlier step had you storing a bunch of images in your images folder. We are going to use the first one as the source file for the first image object in the array.

image_srcs[0].src = "images/image00.jpg";

We are going to repeat this for each of the six images you stored to your directory. The final code should look like this:

var image_srcs = new Array();
image_srcs[0] = new Image(200,100);
image_srcs[0].src = "images/image00.jpg";
image_srcs[1] = new Image(200,100);
image_srcs[1].src = "images/image01.jpg";
image_srcs[2] = new Image(200,100);
image_srcs[2].src = "images/image02.jpg";
image_srcs[3] = new Image(200,100);
image_srcs[3].src = "images/image03.jpg";
image_srcs[4] = new Image(200,100);
image_srcs[4].src = "images/image04.jpg";
image_srcs[5] = new Image(200,100);
image_srcs[5].src = "images/image05.jpg";

Now we should have six images we can put into our my_image image location, but we don't have a way to swap them. Let's create a form with two buttons: one to increment through the images and one to decrement. To support these buttons, let's create two functions, one to load the next image and one to load the previous image. We begin by creating a global variable, i.e., one that's declared outside of the functions, and initialize it to the first index of our array.

var current_image=0;

Next, loadNextImage() will increment current_image up to the end of the array, and swap the image currently displayed in my_image with the new one. loadPreviousImage() will do the same thing except by decrementing the current_image value.

function loadNextImage()
{
    current_image++;
    if(current_image == image_srcs.length) current_image = 0;
    swapImage("my_image", image_srcs[current_image].src);
}

function loadPreviousImage()
{
    if(current_image == 0) current_image = (image_srcs.length - 1);
    else current_image--;
    swapImage("my_image", image_srcs[current_image].src);
}

This should give us the functionality that we need. The only thing left to do is remove the onMouseOver and onMouseOut events and add the form with the buttons. The form should have one button that calls loadNextImage() and a second button to call loadPreviousImage().

<form>
    <input type="button" onClick = "javascript:loadPreviousImage()" value="Previous">
    <input type="button" onClick = "javascript:loadNextImage()" value="Next">
</form>

Preloading Images

If your page requires a number of images to be loaded for rollovers or slide shows, you may want to think about preloading your images. Preloading images is nothing more than telling the browser that an image is needed for download before the rollover script or slide show script requires it. This is important because if an image isn't preloaded, then the browser may not begin its download until after the rollover script is executed. This will force the user to sit through an awkward download delay before the rollover appears to work properly.

In the rollover example where the onMouseOver and onMouseOut events execute a script which becomes the first reference to the image, this could be a problem. In the slide show example, however, the initialization of the array informs the browser of the images and their respective sources. This should preload the images for you.

In general, all you should have to do to preload an image is to create an image object and initialize its source.

my_image = new Image();
my_image.src="http://www.my_domain.com/the_image.jpg";

In some cases, a browser may not support the image object. We can test for this with the following code:

if (document.images)
{
    my_image = new Image();
    my_image.src="http://www.my_domain.com/the_image.jpg";
}

Form Validation

In this exercise, you will be taking an existing form and creating a script that will be used to verify that the user has entered all of the required data and that the data is valid. Your form validation script should verify the following:

  • the e-mail has the '@' symbol
  • at least one period exists after the '@' symbol
  • the user has entered a valid month between 1 and 12 inclusive
  • the day does not exceed the allowable value for any month (Be sure to account for 29 days in February on a leap year. See below for description of included isLeapYear() function.)
  • the user has entered a year between 1800 and 2999
  • the user has entered text for the city
  • the user has selected a state, i.e., not left the default blank
  • zip code is integer from 0 to 99999 (don't worry about 9-digit zip codes or insuring that there are exactly 5 digits)

For each error, please use a window.alert() function to tell the user how to properly enter the incorrect value.

To perform this task, copy the file validation.htm to your inclass/html folder. Somewhere on the page, be sure to enter your name. Within the validation.htm file, I have added the <script>...</script> tags in the head along with the function prototype function validateForm() where you will insert your form validation code. The following is a short list of suggestions for validating the data on your form:

  • For all of the form's fields, you should be able to use the value property to retrieve the data that the user entered. For example, to retrieve the value the user entered for the name, use the document.personal_info.name_text.value object/property identification.
  • For the e-mail address, you are asked to identify characters and positions. Use the indexOf() method for strings. Remember that this method returns a -1 if the character is not found in the string.
  • In some cases, you will need to verify that you have received a number. In those cases, you can uses the function isNaN() before you begin checking for ranges and such.
  • Remember too that the values returned from these form fields will be strings. parseInt() will convert these strings to numbers so that you can do things like comparisons and such.

Please complete this form validation exercise as homework by Tuesday, February 13th. Don't worry about loading it to your dropbox; I will pull it directly from your cscidbw account. Be sure it is in the correct folder.

isLeapYear() Function

In order to make your work go quicker, I have included a short function to determine whether an integer value representing a year is a leap year or not. In general, leap years occur when the year is divisible by 4, i.e., year modulo 4 equals 0. This is always true except for some cases when the year is divisible by 100. In those cases a leap year is skipped. Of course, there is an exception to that rule too. Years divisible by 400 do not skip the leap year.

Okay, all of that aside, I have added a function called isLeapYear(). It initializes a return value to true, then sets it to false if the year is not divisible by 4, i.e., (year % 4) != 0. It also sets the return value to false if the year is divisible by 100 but not 400, i.e., (((year % 100) == 0) & ((year % 400) != 0)). The code is shown below:

function isLeapYear(year)
{
    var return_value=true;

// There is no leap year if the year is not divisible by 4
    if ((year % 4) != 0)
        return_value = false;

// There is no leap year if the year is divisible by 100 but not 400
    else if (((year % 100) == 0) & ((year % 400) != 0))
        return_value = false;

    return return_value;
}

Feel free to use this function. If the function returns a false, then February should only have 28 days. A true means February should have all 29 days.