JavaScript, DOM, and the Humble FORM
Use standard DOM methods and properties to interact with HTML forms.
This is a basic tutorial on using JavaScript to interact with forms on a Web page. It covers two methods. The first method is very common, but was first implemented in old browsers. The second method uses standard Document Object Model methods and properties, and is considered best practice.
Using document.forms to Get DOM References to FORMs
Old browsers polluted the document
object with multiple, redundant references to FORM tags. The document.forms
array actually contains two parts. First, it is an integer-indexed array of references to FORM tags, and secondly it is an associative array. Let's take the following HTML as an example:
Example 1
<form name="establishment_form"> ... </form> <form> ... </form>
In our pretend HTML document, we've got two forms. The first form is given a name and the second form is not given a name. You can access the Document Object Model nodes that represent those FORM tags like this:
Example 2: Getting DOM node references to the two forms in Example 1
var form1 = document.forms["establishment_form"]; var form1 = document.forms.establishment_form; var form1 = document.forms[0]; var form2 = document.forms[1];
You'll notice that the first form on the page, which was given a name, can be accessed in three ways: document.forms["establishment_form"]
, document.forms.establishment_form
, and document.forms[0]
. They all represent the same Document Object Model node and the same HTML tag.
The second form on the page was not given a name, and can only be accessed using document.forms[1]
. Also remember that integer-indexed arrays start with zero, so an index of zero is the first form, and an index of 1 is the second form.
One more wrench is thrown into this cog wheel since the first form was given a name: It can also be accessed via document.establishment_form
. So a quick recap of how to get a node reference to the first form tag in our HTML example above (example 1).
Example 3: Getting a DOM node reference to the first form in Example 1
var form1 = document.establishment_form; var form1 = document.forms["establishment_form"]; var form1 = document.forms.establishment_form; var form1 = document.forms[0];
Yuck. Writing JavaScript for older browsers basically sucks. All of these different methods existed because browser developers couldn't agree on the best way to do things. Now enter Web Standards.
Standard Methods for Getting DOM Node References to FORMs
There are three main ways of getting a reference to a form tag using standard methods. Let's use our HTML code from example 1 again, slightly modified.
Example 4.
<form id="establishment_form"> ... </form> <form> ... </form>
An Id is used instead of the name attribute. Using an Id is best because it identifies one element on the page. Names can be applied to more than one element, thus the document.forms.form_name method might reference a different form than you think. Having more than one form with the same name will cause JavaScript to return a reference to the first instance of a form with the given name. Furthermore, if you use Cascading Style Sheets, giving Ids to all of your FORMs allows you to easily style forms individually.
Example 5: Standard DOM methods to get references to FORM
tags
var form1 = document.getElementById("establishment_form"); var form1 = document.getElementsByTagName("form")[0]; var form2 = document.getElementsByTagName("form")[1];
We still have more than one way to grab a reference to the first FORM in Example 4. The advantage of using document.getElementById
over document.getElementsByTagName
is if you ever add a FORM to that page, the index number at which the establishment_form FORM
tag is referenced may change. Using document.getElementById
allows you to physically place that FORM tag anywhere in the HTML document and still be able to grab a reference to that FORM tag without changing your JavaScript. The document.getElementById
method is recommended for grabbing DOM node references to FORM
tags. Now that we have a node reference to our FORM tag, we need node references to the form fields.
Getting Node References To Fields Within A Form
We'll keep using the HTML from Example 4, and yet again we will expand it.
Example 5: Adding some form fields
<form id="establishment_form"> <input type="text" name="title"> <textarea cols="50" rows="5" name="description"></textarea> <input type="submit" value="Add Establishment"> </form>
We'll forgo the labels for each form field, as they aren't important for this tutorial. Right now we have two form fields and one button. The form fields are given a name, and the button is given no name. Let's see how we can access those form fields with JavaScript. First, let's get a node reference to our form:
var form = document.getElementById("establishment_form");
Now that we have a node reference to our FORM tag, let's grab references to each form field using the deprecated methods first implemented by older browsers:
Example 6: Get DOM node references to form fields the old way
// Get a reference to the FORM tag var form = document.getElementById("establishment_form"); // Use old method of getting references to fields var title = form.title; var description = form.description;
That wasn't too difficult. When you give a form field a name, the FORM tag gets a property named the same thing as the form field. This is fine and well, but an inherent property of a FORM tag is also called title
. This would be the value of the title attribute of the FORM tag. We have a form field named title, which then overwrites the FORM tag's title
property with a node reference to the form field. That's not so good. Suddenly we have a problem. The name space of the FORM tag is quickly polluted with references to the form fields inside. There is a better way.
Example 7: Get DOM node references to form fields the standard way
// Get a reference to the FORM tag var form = document.getElementById("establishment_form"); // Use standard method for getting references to fields var title = form.elements["title"]; var description = form.elements["description"];
Each FORM tag has a handy property called elements
which holds references to all the form fields. This is a two part property. It contains an integer-indexed array of references to all the form fields, and an associative array of references. Using the elements
property, you can get a reference to the "title" form field in three ways:
var title = form.elements["title"]; var title = form.elements.title; var title = form.elements[0];
You can supply the name of the form field or the index at which it appears in the FORM tag HTML source code. Since the "title" INPUT tag is the first field in the source code, it resides at form.elements[0]
. Now think about the future. Maybe you rearrange the form somewhere down the line, and the "title" INPUT tag is no longer the first form field. You can no longer access that field in JavaScript with form.elements[0]
, so it's always safest to use the form.elements["field_name"]
syntax for the same reason it's best to use document.getElementById
. It is considered best practice to use form.elements["field_name"]
.
The table below outlines the properties in the form.elements
property.
Property | Type | Description |
---|---|---|
0 | object | The "title" form field |
1 | object | The "description" form field |
2 | object | The submit button |
length | number | The number of form fields or elements in this form |
title | object | The "title" form field |
description | object | The "description" form field |
Now let's add form fields with the same name: a group of radio buttons.
Example 9: Adding more than one field with the same name
<form id="establishment_form"> <input type="text" name="title"> <textarea cols="50" rows="5" name="description"></textarea> <input type="radio" name="estab_type" value="General"> <input type="radio" name="estab_type" value="Restaurant"> <input type="radio" name="estab_type" value="Government"> <input type="submit" value="Add Establishment"> </form>
We've added a group of radio buttons, all named "estab_type". This changes the object model of the FORM tag.
Property | Type | Description |
---|---|---|
0 | object | The "title" form field |
1 | object | The first "estab_type" radio button |
2 | object | The second "estab_type" radio button |
3 | object | The third "estab_type" radio button |
4 | object | The "description" form field |
5 | object | The submit button |
length | number | The number of form fields or elements in this form (includes all non named elements like buttons) |
title | object | The "title" form field |
estab_type | array[] | Integer-indexed array of references to each radio button. |
description | object | The "description" form field |
Now you can see why using the form.elements[n]
syntax isn't the best. The order in which the form field appears in the HTML source determines the index number in the form.elements
array at which a form field resides. The "description" text field went from index 1 to index 4. If you had used form.elements["description"]
to get a reference to the "description" text field, this change to the FORM markup wouldn't have affected your JavaScript.
Now we've run into another unique case. The form.elements["estab_type"]
property is an array, not a reference to a form field. Remember that we had three radio buttons named "estab_type". The browser accounts for this by mashing references to all three radio buttons in form.elements["estab_type"]
. Let's take a look at the contents of this array.
Property | Type | Description |
---|---|---|
0 | object | Reference to first "estab_type" radio button |
1 | object | Reference to second "estab_type" radio button |
2 | object | Reference to third "estab_type" radio button |
length | number | Number of items in this array. |
The object model of the form.elements
property then looks like this:
Example 12: Breakdown of the form.elements object model
form.elements[0] // "title" INPUT form.elements[1] // "estab_type" radio 1 form.elements[2] // "estab_type" radio 2 form.elements[3] // "estab_type" radio 3 form.elements[4] // "description" TEXTAREA form.elements[5] // submit INPUT form.elements.length // Number of form elements form.elements.title // "title" INPUT form.elements.estab_type[0] // "estab_type" radio 1 form.elements.estab_type[1] // "estab_type" radio 2 form.elements.estab_type[2] // "estab_type" radio 3 form.elements.estab_type.length // Number of radio buttons form.elements.description // "description" TEXTAREA // Note: form.elements.estab_type is the same as // form.elements["estab_type"]
Since we can reference form fields by their name and by an index number, we can do bulk processing on a form using JavaScript. It's easy to loop through all the fields in a form.
Example 13: Looping through all the form fields
// Get a DOM reference to our form var form = document.getElementById("establishment_form"); // Loop through all the form fields for (var i = 0; i < form.elements.length; i++) { alert(form.elements[i]); }
Also recall that our "estab_type" radio buttons formed an array in form.elements["estab_type"]
. We can also loop through this with JavaScript:
Example 14: Looping through an array of form fields with the same name
// Get a DOM reference to our form var form = document.getElementById("establishment_form"); // Loop through all the "estab_type" radio buttons for (var i = 0; i < form.elements["estab_type"].length; i++) { alert(form.elements["estab_type"].value); }
A Quick Recap
We've covered how to get a DOM node reference to a FORM tag, and also how to get references to the form fields inside of it. There were two basic methods. One used the API of older browsers, which included document.forms
, and form.field_name
, and the other utilized standard Document Object Model functions and properties like document.getElementById
and form.elements
. Using the standard DOM properties allows you to change and rearrange your FORM markup down the road with little fear of breaking your JavaScript, and since you are using standard functions and properties, your script will be supported for many years to come.
Standard Method (Best Practice) | Old Method (Deprecated) |
---|---|
document.getElementById("form_id") | document.forms.form_name |
document.getElementById("form_id") | document.form_name |
document.getElementsByTagName("form")[n] | document.forms[n] |
form.elements["description"] | form.description |
form.elements.description | form.description |
Additional References
-
document
Object Reference at W3Schools.com -
document.forms
Object Reference at W3Schools.com - Form DOM Reference at W3Schools.com