Section J. Forms and the Level 0 DOM


J. Forms and the Level 0 DOM

Until now, we've discussed the W3C Level 1 DOM. All browsers, however, also support the Level 0 DOM, which is part of the de facto Netscape 3 standard. This DOM is more limited than the W3C Level 1 DOM, and it has been almost completely superseded by the newer one, which is far more versatile and generalized. There's one exception: the Level 0 DOM remains better equipped for working with forms and form fields than the W3C DOM.

Level 0 DOM nodeLists

The Level 0 DOM also works with nodeLists, but they differ from Level 1 DOM nodeLists in four important respects:

  • Level 0 DOM nodeLists are available only for a limited number of elements, most importantly form fields, images, and links.

  • Level 0 DOM nodeLists allow you to search for an element by name or ID, in addition to the index numbers we already discussed in 8I.

  • One Level 0 DOM nodeList, options[], allows you to create and remove option elements. It is effectively a read/write array.

  • The Level 0 DOM nodeList elements[] has no counterpart in the Level 1 DOM.

Take this HTML snippet:

<body> <img src="/books/1/521/1/html/2/someImg.gif" name="firstIMG" /> <img src="/books/1/521/1/html/2/someOtherImg.gif"  /> </body> 


The Level 1 DOM allows us to access these images by document.getElementsByTagName('img'). The Level 0 DOM allows the same through the document.images[] nodeList. document.images[0] is the same as document.getElementsByTagName('img')[0].

In addition, the Level 0 DOM allows document.images['firstIMG'] and document.images['secondIMG']. It searches for the image with the given name or ID. That can occasionally be quite useful, especially if you have to find a specific image and are not sure of the exact document structure (because other scripts might have changed it, for instance). Just as Level 1 DOM nodeLists do, document.images[] reflects all changes in the document, so it presents the same dangers.

document.images[] is nothing more than a convenient alternative to document.getElementsByTagName('img'). The other common Level 0 DOM nodeLists are somewhat more than that.

Document.FirstIMG

The Level 0 DOM even allows you to say document.firstIMG, i.e., to use the name of the image (or form field or whatever) as a property of document.

Even back in the Netscape 3 days I didn't like this syntax, because it obscures what you're doing. Take this: document.income. Is this an image, a form, a link, or what? Other JavaScript programmers who have to work with your scripts won't know right away, whereas document.forms['income'] is totally clear to everyone.

Therefore, I advise you not to use this syntax.


First of all, there are document.links[] and document.anchors[]. These contain all <a href> and <a name> tags in your pages, respectively. In contrast, document.getElementsByTagName('a') contains both kinds of tags. Although I've never needed them, it's still remotely possible that these old nodeLists may come in useful in a few situations.

Form fields

document.forms[] is equivalent to document.getElementsByTagName('form'). Apart from being able to access forms by name or id, there is little difference between these two nodeLists.

Every form has an elements[] nodeList. This is the one Level 0 DOM nodeList we still use often, because it has no counterpart in the Level 1 DOM and is so useful we cannot do without it.

document.forms[0].elements[] contains all form fields in the first form in the document. The trick is that these form fields can have different tag names (input, select, or textarea), so there is no single getElementsByTagName() call that delivers us all of them. Of course you can use three calls for the three tag names, but even then you don't get the form fields in the order they appear in the documentsomething that can be important in, for instance, form validation.

Once you have accessed form fields, you usually want to read out their values.

Form field properties

Every kind of form field has its own quirks, but before we discuss these we'll take a look at five properties any form field possesses: type, form, disabled, name, and value.

The type property of a form field gives its type: text, hidden, textarea, checkbox, radio, select-one, select-multiple, file, submit, or reset. It is possible to change the type of a form field, but this does not work in all browsers, and is counter-indicated.

Figure 8.20. Form fields.


The form property of a form field refers to its parent form, and because the <form> tag is usually not the parentNode of a form field, this simple property can be quite useful, as we'll see when we discuss radio buttons.

The disabled property contains a boolean that says whether the form field is disabled (true) or not (false). You can set disabled, and this will disable the form field so that the user cannot change it. Note, however, that a disabled form field is not sent back to the server, even if it contains a value.

The last two properties are rather obvious: they give the name and the value of the form field.

<input name="test" value="This is a test value" /> 


This form field has name "test" and value "This is a test value". Of course the value is also the text contained in the form field, and if the user types a new text, the value changes. It is also possible to set the value:

document.forms[0].elements['test'].value = 'Changed value!'; 


The text in the form field is immediately updated. Changing the name of a form field is not possible in all browsers, and I advise against it.

text, hidden, and textarea

When you access a text field, hidden field, or textarea, you usually want to read out its value, which is contained in the value property.

checkboxes

Checkboxes have a value, too, but usually you want to know if the user has checked the box. This information can be found in the checked property, which gives a boolean true (checked) or false (not checked).

radios

Radios have a checked property, too, and it works the same as with checkboxes. Nonetheless, radios are slightly more complicated than checkboxes, because you usually need to go through an entire array of radio buttons and see which one of them is checked.

In order to work properly, all radio buttons that belong together should have the same name attribute. The Level 0 DOM conveniently creates a nodeList keyed to this name so that you can easily access a group of radio buttons.

Take this group:

<input type="radio" name="income" value="10" />&euro; 10 or lower<br /> <input type="radio" name="income" value="100" />&euro; 11-100<br /> <input type="radio" name="income" value="1000" />&euro; 101-1000<br /> <input type="radio" name="income" value="10000" />&euro; 1001-10000<br /> 


They are accessible through this DOM call:

var radios = document.forms[0].elements['income']; 


Now radios is a nodeList that contains all radio buttons with name="income" and you can loop through them to see if one of them is checked:

var radios = document.forms[0].elements['income']; for (var i=0;i<radios.length;i++) {     if (radios[i].checked)            // do something } 


It's when you work with radio buttons that the form property of all form fields is very useful. Suppose you catch all click events on radio buttons and you want to go through all other radio buttons in the same group, just as we did above. Before you can do that, you have to gather the relevant radios:

function handleEvent(e) {     if (!e) var e = window.event;     var tg = e.target || e.srcElement;     var allRadios = tg.form[tg.name];     for (var i=0;i<allRadios.length;i++) {            // do something with all radio buttons     } } 


First we determine which radio button is the event target, as discussed in 7F. Then we take all radio buttons in the same group by going to the form property of the target, i.e., the form it's part of (tg.form), and taking the radio button nodeList (tg.form[]) that's keyed to the name of the target (tg.form[tg.name]).

Multiple Selects

From the very beginning, HTML has had multiple select boxes, which allow users to select more than one option. Also since the very beginning, everybody has ignored these form fields, since they just don't work for users.


selects and options

Remember that common select boxes have type 'select-one', not 'select'. This serves to distinguish them from multiple selects, which are never used.

Selects also have a value property, which takes the value of the selected option. Furthermore, they have a selectedIndex property that contains the number of the option the user has selected. Finally, they have an options[] nodeList that contains all options of the select.

options[] is a unique nodeList because you're allowed to add or remove elements, and these options are added to or removed from the visible select box. Therefore, options[] is not equal to getElementsByTagName('option'), which is a normal read-only Level 1 DOM nodeList.

Select Value in Older Browsers

Selects didn't have a value attribute in older browsers. Instead, to find the value of the selected option, you had to do this:

var sel = [the select box];

var value = sel.options[sel.selectedIndex].value;

You often see this syntax in older scripts, but nowadays it's not necessary.


In order to remove an option, simply set the correct element of the options[] nodeList to null:

var x = [a select box]; x.options[1] = null; 


Now the second option is removed from the select box, and of course all other options move one step up to accommodate this change. Therefore, a new x.options[1] is immediately available: this is the old x.options[2].

Adding an option is slightly more complicated. You must first create a new option object and add that to the options[] array:

var newOpt = new Option('text','value'); x.options[1] = newOpt; 


Note that the new option requires two arguments: the text and the value. Once it's created, you insert it in the options[] array, and of course the old x.options[1] now becomes x.options[2], etc.

File uploads

File-upload fields are protected by JavaScript security. No script is allowed to enter a value in a file upload, since that could lead to a serious security risk:

   fileUploadField.value = '/my/password/file.txt';    fileUploadField.form.submit(); 


No Createelement(), No Add()/Remove()

Options should not be created by using createElement(), because Explorer doesn't support that. Explorer 5.0 even crashes when you try it.

The W3C DOM defines two methods, add() and remove(), to add and remove options, but since they work differently in different browsers you should avoid them.


If this were allowed, malicious site owners could easily download your password files or other system-critical files. Therefore, the only thing you can do with a file upload is read out its value.

Submit and reset

Submit and reset buttons that are <input> tags also have a value, which represents the text that's on the button:

<input type="submit" value="Submit form" /> <input type="reset" value="Reset form" /> 


<button> tags work differently: they contain a bit of text, and obviously this text is a separate text node as far as the W3C DOM is concerned. It is not accessible through the Level 0 DOM:

<button >Submit form</button> 


Example script

This script from Form Validation determines whether the user has entered anything in a required form field:

[Form Validation, lines 15-32]

function isRequired(obj) {     switch (obj.type) {            case 'text':            case 'textarea':            case 'select-one':                   if (obj.value)                          return true;                   return false;            case 'radio':                   var radios = obj.form[obj.name];                   for (var i=0;i<radios.length;i++) {                          if (radios[i].checked) return true;                   }                   return false;            case 'checkbox':                   return obj.checked;     } } 


The script uses a switch() statement (see 5H) that uses the type of the field to determine which bit of code should be executed. If the required field is a text field, textarea, or select box, it must have a value. If it doesn't, the script returns false: required field not filled out.

Required checkboxes should be checked, while one radio of a required group should be checked. For checkboxes, the script simply returns the checked property, since that's true or false anyway. For radios, it goes through all radios in the same group (obj.form[obj.name]), and if one of them is checked it returns true, otherwise false.



ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net