HTML supports a variety of form elements, including single-line and mutiline text boxes, password fields, radio buttons, checkboxes, pull-down menus, scrolled lists, hidden fields, and numerous types of buttons. This section presents a short review of each of these tags and shows how JavaScript can be used to access and modify their properties.
All <<input>> tags are represented in the DOM as HTMLInputElement objects. These objects share a number of properties related to their functionality as form fields, as well as the (X)HTML standard properties you would expect (id, title, lang, and so on.). The properties common to all objects representing <<input>> tags are shown in Table 14-2. Specific types of input elements—for example, <<input type="image" />>—have additional properties and methods specific to the type of input they handle. For example, input with type equal to "image" defines an src attribute, which is undefined with other type values.
Property |
Description |
---|---|
AccessKey |
String holding the accelerator key that gives the element focus as set by the accesskey attribute. Note the case difference. |
defaultValue |
String holding the contents of the value attribute when the page loaded. |
Disabled |
Boolean value indicating whether the user can interact with this field. This can be set by the disabled (X)HTML attribute. |
form |
Read-only reference to the Form containing this field. |
name |
String containing the name of the field as defined by the name attribute. The id attribute and corresponding id property are also used. |
Size |
Commonly used for <input> type set "text" or "password", in which case it specifies the width in characters. So type values like "radio" or "checkbox" do not support this attribute while image may define size in pixels. |
TabIndex |
Integer indicating the field's position in the document's tabbing order as defined by the tabindex atribute. |
type |
String indicating what kind of form input field the element represents. Valid values are "text", "password", "button", "image", "submit", "reset", "radio", "checkbox", "hidden", and "file". |
Blur() |
Causes the field to lose focus. |
focus() |
Brings the field into focus for user input. |
A few properties do require some brief discussion. First, the form property references the Form object that element is enclosed within. So, given
<<form name="myform" id="myform">> <<input type="text" name="field1" id="field1" />> <</form>>
the value of document.myform.field1.form is the Form object named myform. Of course, you might wonder about the usefulness of this, since we knew the form name to access the property. In short, it is most useful when a function or object is given some generic form field object without any indication of the form it is enclosed within.
The next property that should be discussed is defaultValue. This property holds the string set by the value attribute in the original HTML file. So, given <<input type="text" name="testfield" value="First value" />> within the form named testform, the value of document .testform..testfield.defaultValue would be the string "First value." This will also be held in the property document.testform.testfield.value at first. However, as the user changes the contents of the field, the value property will change to reflect the user’s modifications, while the defaultValue property will remain constant. In fact, executing reset() on the form sets all the form’s elements’ values to their defaultValues. Interestingly, while it is obvious that value is changeable both by the user and by script, it turns out that defaultValue is also defined to be settable by script, though the value of this is not as obvious.
In traditional JavaScript as well as under DOM Level 1, all forms of text fields support the blur() and focus() methods. The text input fields also support select() methods. So given these methods, onblur, onfocus, and onselect are of course supported. Other event handlers are more focused on user activities so many fields also support onchange, which is fired once a field’s content has changed and the field has lost focus. Also supported are a variety of keyboard-related events, such as onkeypress, onkeyup, and onkeydown. We’ll show examples of the use of each of these properties and methods in more detail as we explore how the different kinds of form fields are used.
There are three basic types of buttons in HTML: submit, reset, and generic buttons. A fourth type is the image button, and a fifth is a generalized button element. The last two types are slightly different from the basic types, and will be discussed separately.
All three of the basic button types are defined with (X)HTML’s versatile <<input>> tag. You use <<input type="submit" />> to create a Submit button, <<input type="reset" />> to create a Reset button, and <<input type="button" />> to create a generic button. To specify the text appearing on the button, set the value attribute—for example, <<input type="button" value="Click me please!" />>.
These common attributes should not be overlooked; we can use them to improve the look and usability of a button, as demonstrated here:
<<form>> <<input type="button" value="Click me" name="button1" id="button1" title="Please click me, pretty please!" style="background-color: red; color: white;" accesskey="c" />> <</form>>
The default behavior of a Submit button is to send the form fields to the server for processing. Not surprisingly, the Reset button causes all form fields to revert to their original state, the state they were in when the page loaded. The generic button has no default action; to make use of it you generally attach an onclick event handler that causes something useful to happen when the button is clicked.
The method these buttons have in addition to the properties and methods common to all input elements is shown in Table 14-3. You can force a "click" of a button by invoking its click() method. Similarly, like all input elements, you can focus a button using its focus() method and move away from it using blur(). Often a browser will highlight a button in some fashion when it has focus—for example, under Internet Explorer a dotted line is placed around its edge.
Method |
Description |
---|---|
click() |
Simulates a click on the button, firing its default action |
The following simple example shows many of the methods and events for buttons in action.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html>> <<head>> <<title>>Button Tester<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<form action="http://www.javascriptref.com" method="get" name="testform" id="testform" onreset="return confirm('Clear fields?');" onsubmit="return confirm('Send form?');">> <<label>>Test Field: <<input type="text" value="test information" />><</label>> <<br />><<br />> <<label>>Test Field 2: <<input type="text" />><</label>> <<br />><<br />> <<input type="reset" value="clear fields" onclick="alert('clicked');" />> <<input type="submit" value="submit" name="thesubmit" id="thesubmit" onclick="alert('clicked');" />> <<input type="button" value="regular button" onclick="alert('clicked');" />> <<input type="button" value="Focus submit button" onclick="document.testform.thesubmit.focus();" />> <<input type="button" value="Blur submit button" onclick="document.testform.thesubmit.blur();" />> <<input type="button" value="Click the submit button" onclick="document.testform.thesubmit.click();" />> <</form>> <</body>> <</html>>
Remember that these buttons (indeed, all form elements) can only appear within a <<form>> tag. While Internet Explorer may let you get away with using form elements anywhere in a document, browsers enforcing standards will not render form field elements outside a <<form>> tag.
The simple gray appearance provided by standard (X)HTML Submit, Reset, and generic buttons is often not desirable. A good approach to livening up your buttons is to apply CSS to them. However, some designers instead use image buttons. There are a few ways to create image buttons in markup. The first is simply to wrap an <<img />> tag within a link and trigger some JavaScript, for example,
<<a href="javascript:document.myform.submit();">><<img src="images/submit.gif" width="55" height="21" border="0" alt="Submit" />><</a>>
Alternatively, you can use the <<input type="image" />> form field. Under (X)HTML, such fields are used to create graphical Submit buttons. For example, to create a submission button consisting of an image, you might use
<<input type="image" name="testbutton" id="testbutton" src="../images/button.gif" alt="Submit" />>
The unique properties of image buttons are discussed in Table 14-4. In particular, notice that image maps can be used with image buttons via the usemap attribute. Yet, interestingly, regardless of the use of a usemap attribute, image-based Submit buttons always send an x and y value in during submission, indicating the pixel coordinates of the image clicked.
Property |
Description |
---|---|
Alt |
Text alternative of the button for non-visual browsers |
Src |
URL of the image to display as a button |
UseMap |
Indicates the button is a client-side image map |
Note |
Despite being defined since HTML 4, the image button is often not supported by older browsers. Even relatively recent browsers such as Internet Explorer 5 do not properly recognize it. |
HTML 4 and XHTML support the <<button>> tag, which is much more flexible than <<input>> and provides the possibility of visually richer buttons. The basic syntax of the <<button>> tag is presented here:
<<button type="button | reset | submit" id="button name" name="button name" value="button value during submission">> Button content <</button>>
Two examples of <<button>> in use are shown here:
<<button type="submit" name="mybutton" id="mybutton">> <<em>>Yes sir, I am a submit button!<</em>> <</button>> <<button type="button" name="mybutton2" id="mybutton2">> <<img src="button.gif" border="0" alt="button!" />> <</button>>
Renderings unfortunately might not be as expected:
Supporting the basic syntax and previous example, DOM Level 1 defines the expected properties for the HTMLButtonElement object shown in Table 14-5.
Property |
Description |
---|---|
accessKey |
Holds the accelerator key string |
disabled |
Boolean value indicating if field is disabled or not |
form |
Reference to the enclosing Form object |
name |
Name of the field (also uses id) |
tabIndex |
Numeric position in the tabbing order as defined by the tabindex attribute |
type |
Indicates the type of the button: "button," "reset," or "submit" |
value |
The value sent to the server if the form is submitted |
Focus and blur events can be caught as usual with onfocus and onblur event handlers. Click events and methods are also typically supported in browsers. However, despite its inclusion in W3C standards, the <<button>> tag is inconsistently rendered by older browsers (notably Netscape 4), so designers might instead opt to use common <<input type="submit" />>, <<input type="reset" />>, and <<input type="button" />> tags or even fake the operation of form buttons using links and images (as discussed earlier).
There are three kinds of text input fields: single-line text entries, password fields, and multiline text fields called text areas. A single-line text field is defined by <<input type="text" />>, while a password field is defined by <<input type="password" />>. Under traditional HTML, both of these forms of the <<input>> element support the same attributes, as summarized here:
<<input type="text or password" name="unique alphanumeric name for field" id="unique alphanumeric name for field" maxlength="maximum number of characters that can be entered" size="display width of field in characters" value="default value for the field" />>
The properties and methods "text" and "password" fields have in addition to those common to all input elements are shown in Table 14-6.
Property |
Description |
---|---|
maxLength |
The maximum number of characters that can be entered into the field |
readOnly |
Boolean indicating if the user may modify the contents of the field |
select() |
Selects the contents of the field, for example, in preparation for replacement or copying to the clipboard |
The following example shows the use of text fields and their properties and methods, including both reading and setting values.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html>> <<head>> <<title>>Textfield Test<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<h2 align="center">>Test Form<</h2>> <<form name="testform" id="testform" action="http://www.javascriptref.com" method="get">> <<label>>Text Field 1: <<input type="text" name="text1" id="text1" size="20" value="Original Value" />><</label>> <<br />> <<label>>Text Field 2: <<input type="text" name="text2" id="text2" size="20" maxlength="20" />><</label>> <<br />> <<input type="button" value="Check Value" onclick="alert(document.testform.text1.value);" />> <<input type="button" value="Set Value" onclick="document.testform.text1.value=document.testform.text2.value;" />> <<input type="button" value="Toggle Disabled" onclick="document.testform.text1.disabled=!(document.testform.text1.disabled );" />> <<input type="button" value="Toggle Readonly" onclick="document.testform.text1.readOnly=!(document.testform.text1.readOnly );" />> <<input type="button" value="Focus" onclick="document.testform.text1.focus();" />> <<input type="button" value="Blur" onclick="document.testform.text1.blur();" />> <<input type="button" value="Select" onclick="document.testform.text1.select();" />> <</form>> <<hr />> <<h2 align="center">>Common Field Properties<</h2>> <<script type="text/javascript">> <<!-- document.write("defaultValue: " + document.testform.text1.defaultValue+"<<br />>"); document.write("form: "+document.testform.text1.form+"<<br />>"); document.write("form.name: " + document.testform.text1.form.name+ "<<br />>"); document.write("name: "+document.testform.text1.name+"<<br />>"); document.write("type: "+document.testform.text1.type+"<<br />>"); document.write("value: "+document.testform.text1.value+"<<br />>"); //-->> <</script>> <</body>> <</html>>
A rendering of this example is shown in Figure 14-2.
Closely related to inputs of type "text" are <<textarea>> tags, multiline text entry fields. The basic syntax for <<textarea>> is
<<textarea name="field name" id="field name" rows="number of rows" cols="number of columns">> Default text for the field <</textarea>>
Even though it is not, strictly speaking, an <<input>> tag, the HTMLTextAreaElement has all the properties and methods of inputs of type "text", plus those listed in Table 14-7. It does not, however, have a maxLength property.
Property |
Description |
---|---|
cols |
Width of the input area in characters |
rows |
Height of the input area in characters |
Using a <<textarea>> in JavaScript is pretty much the same approach as using a standard single-line text field or password field, the main differences of course being the rows and columns to change the size of the region. Yet the value and defaultValue may be slightly different since a <<textarea>> may have return characters or other things that are escaped in JavaScript. Finally, the type property will report the field as a textarea rather than text. This brief example demonstrates basic use of JavaScript and a <<textarea>>.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html>> <<head>> <<title>>Textarea Test<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<h2 align="center">>Test Form<</h2>> <<form name="testform" id="testform" action="http://www.javascriptref.com" method="get">> <<label>>Textarea 1: <<textarea name="field1" id="field1" rows="5" cols="40">> This is some default text <</textarea>><</label>> <<br />><<br />> <<input type="button" value="Check Value" onclick="alert(document.testform.field1.value);" />> <<input type="button" value="Set Value" onclick="document.testform.field1.value='this is a \n\n\n\t\t test!';" />> <<br />> <<input type="button" value="Change Rows" onclick="document.testform.field1.rows=document.testform.rowsField.value;" />> <<input type="text" name="rowsField" id="rowsField" value="2" size="2" maxlength="2" />> <<br />> <<input type="button" value="Change Cols" onclick="document.testform.field1.cols=document.testform.colsField.value;" />> <<input type="text" name="colsField" id="colsField" value="10" size="2" maxlength="2" />> <<br />> <</form>> <<hr />> <<h2 align="center">>Common Field Properties<</h2>> <<script type="text/javascript">> <<!-- document.write("defaultValue: " + document.testform.field1.defaultValue+"<<br />>"); document.write("form: "+document.testform.field1.form+"<<br />>"); document.write("form.name: " + document.testform.field1.form.name+ "<<br />>"); document.write("name: "+document.testform.field1.name+"<<br />>"); document.write("rows: "+document.testform.field1.rows+"<<br />>"); document.write("cols: "+document.testform.field1.cols+"<<br />>"); document.write("type: "+document.testform.field1.type+"<<br />>"); document.write("value: "+document.testform.field1.value+"<<br />>"); //-->> <</script>> <</body>> <</html>>
One interesting aspect of the <<textarea>> tag that bears some discussion is that there is no obvious way to set the maximum amount of content that can be entered in the field. For browsers that support all the core events, such as onkeypress, we could easily limit the field using script, as shown here:
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html>> <<head>> <<title>>Limited Text Area<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<form name="myform" id="myform" action="#" method="get">> <<label>>Comments:<<br />> <<textarea name="comments" id="comments" rows="4" cols="40" onkeypress="return (document.myform.comments.value.length << 100);">> Will be limited to 100 characters in a compliant browser. <</textarea>> <</label>> <</form>> <</body>> <</html>>
Of course, the preceding script will not work in many older browsers because they do not support the onkeypress event. A possible workaround to deal with the unlimited field length is to examine length of the field’s value when its contents change (or at submit time) and reduce it to the proper number of characters. The example here illustrates one possible approach to this problem:
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html>> <<head>> <<title>>Limited Text Area Take 2<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <<script type="text/javascript">> <<!-- function checkLimit(field, limit) { if (field.value.length >> limit) { alert("Field limited to "+limit+" characters"); // Truncate at the limit var revertField = field.value.slice(0, limit-1); field.value = revertField; field.focus(); } } //-->> <</script>> <</head>> <<body>> <<form id="myform" name="myform" action="#" method="get">> <<label>>Comments:<<br />> <<textarea id="comments" name="comments" rows="8" cols="40" onchange="checkLimit(this, 100);">> Try entering 10 more characters to surpass the 100 character limit on this field, then click outside the textarea. <</textarea>> <</label>> <</form>> <</body>> <</html>>
Note |
A troublesome aspect of the <<textarea>> tag is that the wrapping of text is not supported in a standard way between browsers. The nonstandard wrap attribute can be set to a value too “soft” to enforce word wrapping in most browsers. Oddly, HTML 4.0 and the DOM do not address this issue, but most browser JavaScript object models typically support access to this HTML property. If word wrapping behavior is critical to your application, you will have to address the issue on a browser-by-browser basis. |
Checkboxes and radio buttons (“radios,” for short) have much more limited functionality than a text field, and thus there is less to manipulate via JavaScript. In terms of (X)HTML syntax, checkboxes and radio buttons are very similar, and both use the <<input>> tag. The basic HTML syntax for checkboxes and radios follows here:
<<input type="checkbox or radio" name="field name" id="field name" value="value for submission" checked="true or false" />>
The JavaScript objects corresponding to these elements have all the properties of normal input elements, plus those listed in Table 14-8.
Property |
Description |
---|---|
checked |
Boolean indicating the state of the field |
defaultChecked |
Boolean indicating whether the field was checked when the page loaded |
Two attributes of checkboxes and radios require some extra discussion. First is the checked attribute, which simply sets the field to be checked by default when the page loads or is reset (it is reflected in the corresponding object as the checked and defaultChecked properties). Second, the content of the value attribute is sent to a server-side program upon form submission if the field is checked. For example, given <<input type="checkbox" name="testbox" id="testbox" value="green" />>, the name-value pair testbox=green is transmitted when the field is checked. However, if no value attribute is provided, a value of on is transmitted instead, resulting in the pair testbox=on.
Like other <<input>> fields, you can of course invoke the blur() and focus() methods for checkboxes as well as radios. These fields also support the click() method to change the state of the control. Given these methods, the events onblur, onclick, and onfocus are supported. The event onchange is also very useful with these fields.
An important consideration with checkboxes and radios is how they are named. Typically, checkboxes are named differently and have their own values, as shown here:
<<form name="testform" id="testform">> Mustard: <<input type="checkbox" name="mustard" id="mustard" />> Ketchup: <<input type="checkbox" name="ketchup" id="ketchup" />> <</form>>
Given that each checkbox has its own name, access to them is similar to other form elements. In the previous example, you would access the two checkboxes via document .testform.mustard and document.testform.ketchup. However, if checkboxes share the same name, or in the case of radio buttons where they must be the same, you will have a very different approach to accessing the fields from JavaScript.
Checkboxes and radio buttons with the same name are accessible as a JavaScript collection by the name they share. For example, given the following,
<<form name="testform" id="testform">> Mustard: <<input type="checkbox" name="condiments" id="check1" value="mustard" />><<br />> Ketchup: <<input type="checkbox" name="condiments" id="check2" value="ketchup" />><<br />> Mayo: <<input type="checkbox" name="condiments" id="check3" value="mayo" />><<br />> <</form>>
we would find that document.testform.condiments is a collection containing the individual checkboxes. We can find the length of the collection through document.testform .condiments.length and even move through elements using array syntax like document .testform.condiments[1].
Radio buttons must be named this way because radios are used to select one item out of many. So the following
Yes: <<input type="radio" name="myradiogroup" id="radio1" value="yes" />> No: <<input type="radio" name="myradiogroup" id="radio2" value="no" />> Maybe: <<input type="radio" name="myradiogroup" id="radio3" value="maybe" />>
is correct and works properly, while the following
Yes: <<input type="radio" name="myradiogroup" id="radio1" value="yes" />> No: <<input type="radio" name="myradiogroup2" id="radio2" value="no" />> Maybe: <<input type="radio" name="myradiogroup3" id="radio3" value="maybe">>
does not, as it fails to preserve the expected “one of many selection” of radio buttons.
Note |
In the case of grouped items like radios, you may notice that the name and id values do not match up. This is a small variation in XHTML where the id for an element must be unique whereas the name value should not be. Be careful, you really do need to know your markup to take full advantage of JavaScript. |
Given that with radio or checkbox groups you will generally have an array of identically named items, you might have to loop through the collection in order to figure out which item was selected. A complete example showing this as well as other radio and checkbox features is presented here; its rendering appears in Figure 14-3.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html>> <<head>> <<title>>radio/checkbox test<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <<script type="text/javascript">> <<!-- function showradiovalue(radiogroup) { var numradios = radiogroup.length; for (var i = 0; i << numradios; i++) if (radiogroup[i].checked) alert('radio '+i+' with value of '+radiogroup[i].value); } //-->> <</script>> <</head>> <<body>> <<h2 align="center">>Test Form<</h2>> <<form name="testform" id="testform" action="#" method="get">> <<em>>Checkbox: <</em>> <<input type="checkbox" name="check1" id="check1" value="testvalue" />> <<br />><<br />> <<em>>radio buttons: <</em>> yes: <<input type="radio" name="radiogroup1" id="radio1" value="yes" />> no: <<input type="radio" name="radiogroup1" id="radio2" value="no" />> maybe: <<input type="radio" name="radiogroup1" id="radio3" value="maybe" />> <<br />><<br />> <<input type="button" value="Click checkbox" onclick="document.testform.check1.click();" />> <<input type="button" value="Click radio" onclick="document.testform.radiogroup1[0].click();" />> <<input type="button" value="Focus checkbox" onclick="document.testform.check1.focus();" />> <<input type="button" value="Blur checkbox" onclick="document.testform.check1.blur();" />> <<input type="button" value="Checkbox state" onclick="alert('checked?'+document.testform.check1.checked);" />> <<input type="button" value="Radio state" onclick="showradiovalue(document.testform.radiogroup1);" />> <</form>> <<hr />> <<h2 align="center">>Field Properties<</h2>> <<script type="text/javascript">> <<!-- with (document) { write("checked: " + document.testform.check1.checked+"<<br />>"); write("defaultchecked: "+document.testform.check1.defaultChecked+ "<<br />>"); write("form: " + document.testform.check1.form+"<<br />>"); write("form.name: " + document.testform.check1.form.name+"<<br />>"); write("name: " + document.testform.check1.name+"<<br />>"); write("type: " + document.testform.check1.type+"<<br />>"); write("value: " + document.testform.check1.value+"<<br />><<br />>"); write("radiogroup array:" + document.testform.radiogroup1+"<<br />>"); write("radiogroup array length:" + document.testform.radiogroup1.length+"<<br />>"); for (var i=0; i << document.testform.radiogroup1.length; i++) write("radiogroup["+i+"].value:" + document.testform.radiogroup1[i].value+"<<br />>"); } //-->> <</script>> <</body>> <</html>>
Hidden form fields are defined using <<input type="hidden" />>. They’re used to keep control of state information for server-side programs. Hidden form elements will never render onscreen, though their name-value pair will be sent during form submission. Because it is non-visual and non-interactive, the XHTML syntax of a hidden field is essentially the following:
<<input type="hidden" name="fieldname" id="fieldname" value="fieldvalue" />>
The JavaScript properties useful for manipulation of hidden fields are simply disabled, form, id, name, and value (which have been discussed for text fields previously). Hidden fields may not seem terribly useful to some readers, but for many state-preservation tasks, they are often hard to replace. We’ll see some interesting possibilities for this form field when discussing form validation later in the chapter.
Note |
Hidden fields have a dangerous downside when used for state control information—they are easily viewable and changeable by curious or malicious end users. |
The final type of the <<input>> is the file upload control as defined by <<input type="file" />>. The basic XHTML syntax for the field is
<<input type="file" id="field name" name="field name" size="field width in characters" accept="MIME types allowed for upload" />>
The tag creates a file upload field similar to this one in supporting browsers.
File upload fields have one extra property shown in Table 14-9 in addition to those provided by the HTMLInputElement. The accept attribute is used to define the MIME types the user may upload. Unfortunately, given the lack of browser support for this attribute, it is useless.
Property |
Description |
---|---|
accept |
Comma-separated list of MIME types of files the user is permitted to upload |
Note |
A common oversight with file upload fields is that in order to work, the form must have method="POST ", and the enctype attribute must be set to “multipart/form-data”. |
In (X)HTML, the <<select>> tag is used to create two different kinds of pull-down menus. The first and most common is a single-choice menu, often simply called a pull-down. The second form of the menu allows for multiple choices to be made and is generally referred to as a scrolled list. Under JavaScript, we traditionally refer to both tags through one object, simply termed the Select object. Under the DOM Level 1, this combination is preserved, but the object is correctly known as the HTMLSelectElement.
To begin the discussion, we first present an example of both the common single-item pull-down and the multiple-choice item in XHTML:
<<strong>>Single Robot Choice:<</strong>> <<select name="robot" id="robot">> <<option>>Security<</option>> <<option>>Trainer<</option>> <<option>>Friend<</option>> <<option>>Cook<</option>> <</select>> <<br />><<br />> <<strong>>Multiple Robot Choice:<</strong>> <<select name="robotMulti" id="robotMulti" size="4" multiple="multiple">> <<option>>Security<</option>> <<option>>Trainer<</option>> <<option>>Friend<</option>> <<option>>Cook<</option>> <</select>>
An HTMLSelectElement has the properties and methods common to other form fields (name, disabled, size, tabIndex, form, focus(), and blur()) as well as the additional properties and methods shown in Table 14-10. A few of these require some discussion. First is multiple, the presence of which indicates the menu to be a multiple-select menu. The size attribute is used to indicate the number of choices that are shown in the field; by default, the value for this attribute is 1.
Property |
Description |
---|---|
length |
Number of <option>s this element contains (the length of the options[] collection). |
multiple |
Boolean indicating whether the user can select more than one of the options. |
SelectedIndex |
Index of the currently selected option in the options[] collection. If multiple is true, only the first selected choice will be held in this property. |
Size |
Number of options visible at once (1 for a pull-down, more than 1 for scrolled list). |
options[] |
Collection of Options contained by the <select>. |
value |
String holding the value attribute of the currently selected option. If multiple is true, only the value of the first selected option is present. |
add(element, before) |
Inserts the new Option element before the Option before. |
remove(index) |
Deletes the Option at position index in the options[] collection. |
Note |
The value property of the Select object is not widely supported in old browsers. Avoid using it for this reason. Instead, use the selectedIndex in conjunction with the options[] collection to extract the selected value manually. |
Many of the similar event handlers like onfocus are available for the object, but the most useful event handler for <<select>> is onchange, which is fired whenever the user selects a different option in the menu.
The key to scripting a select menu, be it a single- or multiple-choice menu, is an awareness of how to examine the options[] collection for the currently selected value. Given a single-choice menu, the currently selected option is held in the selectedIndex property and is easily obtained. For example, given a <<select>> called testselect in a form called testform, document.testform.testselect.selectedIndex would reference the particular option in question. To see the value of the selected option, you would have to use a fairly long statement like alert(document.testform.testselect.options[document.testform.testselect .selectedIndex].value). As you can see, that becomes unwieldy very quickly, so often the this shorthand form is used with <<select>>, as demonstrated here:
<<form>> <<select onchange="alert(this.options[this.selectedIndex].value);">> <<option value="value one">>Option 1<</option>> <<option value="value two">>Option 2<</option>> <<option value="value three">>Option 3<</option>> <</select>> <</form>>
However, when the multiple attribute is true you will need to loop through the options[] collection to find all the selected items:
<<script type="text/javascript">> <<!-- function showSelected(menu) { var i, msg=""; for (i=0; i << menu.options.length; i++) if (menu.options[i].selected) msg += "option "+i+" selected\n"; if (msg.length == 0) msg = "no options selected"; alert(msg); } //-->> <</script>> <<form name="myform" id="myform">> <<select name="myselect" id="myselect" multiple="true">> <<option value="Value 1" selected="true">>Option 1<</option>> <<option value="Value 2">>Option 2<</option>> <<option value="Value 3" selected="true">>Option 3<</option>> <<option value="Value 4">>Option 4<</option>> <<option value="Value 5">>Option 5<</option>> <</select>> <<br />> <<input type="button" value="Show Selected" onclick="showSelected(document.myform.myselect);" />> <</form>>
Now that we’ve covered how to access options in a select menu, let’s take a look at the properties of the Option element itself. These objects have most of the attributes and methods of other form elements, plus those listed in Table 14-11.
Property |
Description |
---|---|
defaultSelected |
Boolean indicating if this option is selected by default (i.e., whether the <option> tag had attribute selected). |
Number indicating the slot at which this option can be found in its containing Select's options[] collection. |
|
selected |
Boolean indicating if this option is currently selected. |
Text |
String holding the text found enclosed by the opening and closing <option> tags. This is often confused with value; since the text enclosed by the <option> tags is sent to the server, its value is not specified. |
value |
String holding the text of the value attribute, which will be sent to the server if the option is selected at submission time. |
The fact that form fields are scriptable means that you can affect the appearance or content of one element in response to actions users perform on another. We’ll see this technique several times later in this chapter, but perhaps the most common application is with select menus.
Related select menus provide the ability to present a large number of options very quickly to the user. The key to building such menus in JavaScript is understanding how to edit or even add new <<option>>s to a menu on the fly. The traditional way to do this in JavaScript is to use the new operator on the Option() constructor, and then insert the resulting option into the menu.
The Option constructor syntax is
var newOption = new Option(optionText, optionvalue);
where optionText is a string holding the text enclosed by the opening and closing <<option>> tags and optionValue is a string specifying the element’s value attribute.
Once created, Option objects can be inserted into the options[] collection for a select menu. You can delete any unused entries by setting their values to null. The following simple example provides two menus, one with a country and another with a list of cities. The city menu will change dynamically when the user chooses a country.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html>> <<head>> <<title>>Related Select Test<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <<script type="text/javascript">> <<!-- // Create an array to hold the cities for each country var cities = new Array(4); cities["Australia"] = ["Sydney", "Melbourne", "Canberra", "Perth", "Brisbane"]; cities["France"] = ["Paris", "Lyons", "Nice", "Dijon"]; cities["Japan"] = ["Tokyo", "Kyoto", "Osaka", "Nara"]; cities["New Zealand"] = ["Auckland", "Wellington", "Christchurch", "Dunedin", "Queenstown"]; function removeOptions(optionMenu) { for (var i=0; i << optionMenu.options.length; i++) optionMenu.options[i] = null; } function addOptions(optionList, optionMenu) { removeOptions(optionMenu); // clear out the options for (var i=0; i << optionList.length; i++) optionMenu[i] = new Option(optionList[i], optionList[i]); } //-->> <</script>> <</head>> <<body>> <<h2>>Vacation Chooser<</h2>> <<form name="testform" id="testform" action="#" method="get">> Country: <<select name="country" id="country" onchange="addOptions(cities[this.options[this.selectedIndex].text], document.testform.city);">> <<option selected="selected">>Australia<</option>> <<option>>France<</option>> <<option>>Japan<</option>> <<option>>New Zealand<</option>> <</select>> City: <<select name="city" id="city">> <<option>>Sydney<</option>> <<option>>Melbourne<</option>> <<option>>Canberra<</option>> <<option>>Perth<</option>> <<option>>Brisbane<</option>> <</select>> <</form>> <</body>> <</html>>
The previous example illustrated the traditional approach to dynamic manipulation of select menus. Internet Explorer as well as DOM Level 1–compliant browsers support the add(element,before) and remove(index) methods to more easily work with the list of options in a <<select>> menu. The remove() method works the same in Internet Explorer as it does in the DOM, but the add() method can be tricky. In the case of the DOM, add() expects the before parameter to indicate a particular HTMLOptionElement object, while, traditionally, in Internet Explorer, an index value was passed.
A relatively unknown and often poorly supported tag for menus called <<optgroup>> can be used to segment option choices or even to create submenus. For example, consider the markup shown here:
<<select name="robotchooser" id="robotchooser">> <<option>>Choose your robot<</option>> <<option>>-------------------------<</option>> <<option>>Butler<</option>> <<optgroup label="Security Models">> <<option>>Man<</option>> <<option>>K-9<</option>> <</optgroup>> <<optgroup label="Friend Models">> <<option>>Female<</option>> <<option>>Male<</option>> <</optgroup>> <<option>>Trainer<</option>> <</select>>
In a standards-support browser such as Netscape 6 or later, you would probably see something like that shown on the right.
The DOM provides only two properties to manipulate this element via the HTMLOptGroupElement object beyond those standard to any (X)HTML element, and they are shown in Table 14-12. Strangely, unlike with select elements, the DOM does not provide shortcut methods to manipulate the options enclosed by the <<optgroup>> tags, nor are the form or similar properties defined.
Property |
Description |
---|---|
disabled |
Boolean indicating whether the user may interact with this option group |
label |
String holding the text of this option group's label |
HTML supports a few other tags for forms that are primarily related to accessibility improvements and style sheets. For example, the <<label>> tag applies a label to the form fields it encloses for both improved usability and non-visual user agents. The following are two examples of the use of the <<label>> tag:
<<form action="#" method="get">> <<label>>Username: <<input type="text" id="username" name="username" />> <</label>><<br />> <<label for="userpassword">>Password: <</label>> <<input type="password" id="userpassword" name="userpassword" />> <</form>>
The properties supported by the HTMLLabelElement object beyond the standard DOM properties and methods for (X)HTML elements are shown in Table 14-13. Notice the use of htmlFor to represent the for attribute, in view of the fact that, under JavaScript, for is a reserved keyword. We’ll see another use of <<label>> later in the chapter to improve form usability.
Property |
Description |
---|---|
accessKey |
String holding the accelerator key giving focus to this element as defined by the accesskey attribute |
form |
Reference to the Form object containing this element |
htmlFor |
String containing the value of the name or id attribute of the element to which this label applies |
The <<fieldset>> tag is used to define a grouping of a set of elements. The <<legend>> tag is used within <<fieldset>> to create a label for the grouping. Here is an example of the usage of the two tags.
<<form action="#" method="get">> <<fieldset>> <<legend>>Login Info<</legend>> <<label>>Username: <<input type="text" id="username" name="username" />> <</label>><<br />> <<label for="userpassword">>Password: <</label>> <<input type="password" id="userpassword" name="userpassword" />> <</fieldset>> <</form>>
Generally, a browser will render elements within a <<fieldset>> within a box, as shown here.
There is very limited control over <<fieldset>> and <<legend>> from JavaScript, even when the DOM is supported. The properties over and above the core (X)HTML properties supported by the HTMLFieldSetElement and the HTMLLegendElement objects are shown in Tables 14-14 and 14-15, respectively. As you can see, there is really little that can be done with these tags interactively.
Property |
Description |
---|---|
form |
Reference to the form containing the element the object represents. |
Property |
Description |
---|---|
accessKey |
String containing the accelerator key giving focus to the element as defined by the accesskey attribute |
align |
String indicating alignment of the element ("top", "bottom", "right", or "left") |
form |
Reference to the form containing the element the object represents |
Now that we have reviewed how to access all types of (X)HTML form elements from JavaScript, it is time to put our knowledge to work by improving form usage through validation, usability improvements, and dynamic forms.