Приглашаем посетить
Писемский (pisemskiy.lit-info.ru)

HTML Forms

HTML Forms

The Form element is used to logically group related intrinsic controls. These controls can optionally submit their values back to a server or be processed entirely on the client. When the contents of a form are submitted, the name and value of each input control within the form are enumerated and sent back to the server. The server then processes the information and usually returns a new page. The following HTML document demonstrates a form that requests information about the user:

<HTML>
   <HEAD>
      <TITLE>User Information</TITLE>
   </HEAD>
   <BODY>
      <FORM NAME="UserInfo">
         <LABEL FOR="USER">User Name: </LABEL>
         <INPUT TYPE=TEXT NAME="USER" VALUE="User Name" ID="USER">
         <LABEL FOR="ADDRESS">Address: </LABEL>
         <TEXTAREA ROWS=2 COLS=50 NAME="ADDRESS" ID="ADDRESS">
            Enter Address
         </TEXTAREA>
         <INPUT TYPE=SUBMIT VALUE="Submit Information">
      </FORM>
   </BODY>
</HTML>

This section focuses on how data is packaged for submission and how you can manipulate the Form element and intrinsic controls on the client. A discussion of the actual processing of the form on the server side is beyond the scope of this book.

Scoping Forms

Each form defines a separate scope for the elements within it. In addition, every element outside of a form shares its scope with the document. This scoping of Input elements is important because a single page can contain any number of forms, each of which operates independently. The Form element should not be contained within other Form elements, so the scope of an element should always be unambiguous to someone looking at your code.

Scoping separates the name spaces available to the elements. For example, if two forms both contain an element named User, the two elements will operate independently. This is especially important for radio button groups in which grouping is determined by each element's name. Radio buttons provide the easiest way to demonstrate the separation of scopes. For example, if two forms on the same page have a radio button group named State, the radio buttons will be mutually exclusive only within their respective forms. The following document defines two separate radio button groups that share the same name:

<HTML>
   <HEAD>
      <TITLE>Radio Button Scoping Demonstration</TITLE>
   </HEAD>
   <BODY>
      <!-- Radio buttons outside the form are scoped together. -->
      <INPUT TYPE=RADIO NAME="State" VALUE="NJ">NJ
      <INPUT TYPE=RADIO NAME="State" VALUE="NY">NY
      <FORM STYLE="margin-left: 25pt">
         <!-- The two radio buttons are mutually exclusive
              and are independent of buttons outside this form. -->
         <INPUT TYPE=RADIO NAME="State" VALUE="WA">WA
         <INPUT TYPE=RADIO NAME="State" VALUE="CA">CA
      </FORM>
      <INPUT TYPE=RADIO NAME="State" VALUE="MA">MA
   </BODY>
</HTML>

In this example, all five radio buttons share the same name, State, but not the same scope. The first two radio buttons ("NJ", "NY") and the last radio button ("MA") are within the same global scope and are mutually exclusive. The two radio buttons inside the form ("WA", "CA") are in their own form scope and are mutually exclusive only of each other. Therefore, the user can select one value from within each radio button group.

Scripting the Form Element

Forms and the intrinsic controls within their scope have a rich programming model. Through the form object itself, you can submit and reset the form, as well as access and manipulate the individual controls.

The forms Collection

Forms in a document are exposed through the all collection and the forms collection. In addition, named forms have a special relationship with the document and can be accessed directly as properties of the document itself. The following code demonstrates a few of the ways to access Form elements using the object model. The comments show what will be displayed by the Alert dialog boxes.

<HTML>
   <HEAD>
      <TITLE>Forms in the Object Model</TITLE>
   </HEAD>
   <BODY>
      <FORM NAME="form1">
      </FORM>
      <FORM NAME="form2">
      </FORM>
      <SCRIPT LANGUAGE="JavaScript">
         alert(document.forms.length);        // 2
         alert(document.forms[0].name);       // form1
         alert(document.forms.form2.name);    // form2
         alert(document.form1.name);          // form1
         alert(document.all.form2.name);      // form2
         alert(document.forms["form1"].name); // form1
      </SCRIPT>
   </BODY>
</HTML>

The elements Collection

A special relationship is maintained between the form and its intrinsic controls. All the intrinsic controls contained within a form are exposed through properties of the form object as well as through an elements collection, which allows direct access to any intrinsic control that exists on a form. The elements collection of the form object works similarly to the frames collection of the window object, in which the collection is exposed simply to enhance code readability. As with the frames collection, the elements collection actually returns a reference to the form object. For example, the following two lines of code are the same:

document.forms[0].length // Number of elements on the first form
document.forms[0].elements.length

And the following three references are equivalent:

document.forms[0]
document.forms[0].elements
document.forms[0].elements.elements

The elements collection works like all other collections in the object model and provides access to the individual intrinsic controls on the form. The elements collection also contains all the images within the scope of the form.

The rules presented in Chapter 7, "Document Element Collections," can be used to access the contents of the elements collection of the form object. If any elements within a form share the same name, they are exposed as a subcollection. The tags and item methods are also available. For example, the following code can be used to quickly access all the Button elements in the first form and to access the third element in the collection:

// Return a collection of buttons in the first form.
document.forms[0].elements.tags("BUTTON") 
// Access the third intrinsic control on the form.
document.forms[0].elements[2]

In addition, all the intrinsic controls on the form expose a form property that returns the form they belong to. This fact is useful if you need to access the parent form from a generic intrinsic control during an event handler, as shown in the following code.

<FORM NAME="User">
  <!-- Pass the current form to the event handler. The this 
       property references the intrinsic control, and the form 
       property references the form the control is scoped to. -->
  <INPUT TYPE=TEXT ONCHANGE="doClick(this.form);">
</FORM>


NOTE: If an intrinsic control is outside the scope of a form, the form property returns null.

Submitting a Form's Contents

As mentioned, forms can be used for client-side processing or to submit data back to the server. When a form is submitted to the server, the name and value of each of the form's controls are appended onto a single string and submitted to the server. The string is created as an escaped ampersand-delimited string of name-value pairs. All elements scoped within the form are enumerated, and the string is built by concatenating the name and value of all elements that have a name. For example, for the user information form at the beginning of this chapter, the submitted string would be the following:

?USER=SCOTT+ISAACS&ADDRESS=1+Somewhere+Street+WA

The submitted string is fully escaped, so spaces are represented by a plus sign (+).

Button Values

Buttons are submitted in a slightly different way from the standard text controls. The following table lists the rules for the different types of buttons.


Button Type Description
Radio Only the value of the selected button in a radio button group is submitted with the form. If no value is specified, the value defaults to ON.
Check box Check boxes submit their name-value pairs only when they are checked. If no value is specified, the value defaults to ON.
Submit More than one Submit button can be specified on a form. If the Submit button has a name, its name-value pair is submitted with the form.

Shared Element Names

The rules for determining what is submitted with a form are simple: the intrinsic control must have a name, and for buttons the button must be checked. Because only one radio button in a group can be checked at a time, only a single radio button value is submitted for each group. There is no restriction that the names in the submitted string be unique, however. For example, if multiple check boxes share the same name, the name-value pairs of all the checked check boxes with that name are submitted. And in multiple-select list boxes, a name-value pair is submitted for each selected item.

Submit command buttons also follow this rule. However, because only one command button can be selected at a time, only the Submit button that is selected is submitted. This technique can be useful for distinguishing between multiple Submit buttons on a single form. Most of the time, however, submitting a value for the Submit button is not necessary and a name need not be assigned to the button.

Disabled and Read-Only Elements

Elements can be disabled either through script or through HTML. Disabled elements cannot receive the focus, and they appear grayed in the Microsoft Internet Explorer window. Because a disabled element is not considered applicable to the current context of the form, its value is omitted during a form submission.

The contents of read-only elements cannot be edited. By default, buttons are read-only, and all other intrinsic controls are editable. Although there is no way to make a button editable, the other intrinsic controls can be made uneditable using the HTML readOnly attribute or the corresponding object model property. Unlike disabled elements, read-only elements are included in the form submission.

Object Values

Internet Explorer 4.0 supports submitting an Object element with the form if the object is given a name and has a default value that can be submitted. This allows applets or ActiveX controls to take part in the form's submission just as intrinsic controls do.

Where Do Form Submissions Go?

By default, the submitted string is sent back to the current URL. Two methods for submitting data are available: GET and POST. You specify which method to use by setting the method property of the form. The default is GET, which causes the submit string to be appended to the URL and then opened as though the resulting string were a new anchor. The submit method that should be used depends on the particular application being run on the server.

Instead of submitting the form back to the URL of the page, you can specify a custom location for the form using the action property of the form. The action property holds the URL of the server program that accepts the data sent by the form. This property can be dynamically changed through a script to conditionally submit data to different locations.

Where Do Form Results Return To?

While the action property defines the server destination for the data, the target property defines the client destination for any returned information. The target property works the same as the target property of the Anchor element and is used to specify what frame or window the contents are to be displayed in. This property can be used to create a clean user interface in which the entire screen is not constantly updated. For example, if two frames are displayed, one frame can request information from the user and the other frame can display the returned result.

Canceling a Form Submission

Scripts can be used to dynamically force a submission or to prevent a submission from occurring. You can prevent a form submission by returning false to the onsubmit event handler. To do so, either set the returnValue property of the event object to false or return false directly to the event. A common mistake when returning the value to the event handler is to return the value only to a line of code in the event handler rather than to the event handler itself, as shown here:

<HTML>
   <HEAD>
      <TITLE>Canceling Form Submission--Wrong Way</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function doSubmit(f) {
            return false;
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <!-- The form's submission is NOT canceled. -->
      <FORM ONSUBMIT="doSubmit(this);">
         <INPUT TYPE=CHECKBOX NAME="Info">
         <INPUT TYPE=SUBMIT>
      </FORM>
   </BODY>
</HTML>

In this example, the form submission is not canceled even though false is returned by the called function because the return value is not subsequently returned to the onsubmit event handler.

The correct way to cancel the form submission is to return the value returned by the called function. Here is the correct way to define the <FORM> tag:

<FORM ONSUBMIT="return doSubmit(this);">

Now when the onsubmit event handler executes, the value returned by the function is correctly returned to the event handler.

Forcing a Form Submission

The form object exposes a submit method that results in the form's data being submitted. Calling the submit method does not fire an onsubmit event. Therefore, if validation is necessary, the onsubmit's event handler must be manually invoked before the submit method is called, as shown in the following code. When you use this technique, the return value of the onsubmit event handler should always be checked.

<HTML>
   <HEAD>
      <TITLE>Manual Form Submission</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function doSubmit(f) {
            // Write conditional code that determines
            // whether to submit.
            return f.Info.checked;
         }
  
         function manualSubmit(f) {
            var isSubmit = f.onsubmit();
            // Submit if no value or true is returned.
            if ((isSubmit) || (null==isSubmit))
               f.submit();  // Submit the form.
         }
      </SCRIPT>
   </HEAD>
   <BODY>
      <FORM ONSUBMIT="return doSubmit(this)
         // Must return the value of the event handler.">
         <INPUT TYPE=CHECKBOX NAME="Info">
         <INPUT TYPE=BUTTON ONCLICK="manualSubmit(this.form)"
            VALUE="Submit">
      </FORM>
  </BODY>
</HTML>

Resetting a Form's Contents

When a page is first loaded, the initial settings of the controls are cached in special default properties. For text controls, the default property is defaultValue; for command buttons or radio buttons, the default property is defaultChecked; and for the list controls, the default property for each item is defaultSelected. When the form is reset, the values from these properties are copied back into the values of the controls.

The Reset button provides a built-in way for a user to reset a form to the original values. The same action can be simulated on the form by calling the reset method on the form itself. Similar to the form's submit method, the onreset event is not fired when the reset method is invoked. The technique demonstrated in the preceding section for the submit method can also be used to force the reset method after first calling the onreset event handler.

Determining Whether to Use a Form Element

The Form element is generally required when the user is expected to submit results to the server. With Dynamic HTML, controls can be used solely for client-side interactions. In this case, the Form element is optional and the controls can be embedded directly on the page.

Using the Form element for client-side manipulation has no adverse effects and offers a number of benefits. Using a Form element provides Input element grouping within the elements collection and name space scoping for radio buttons. Also, with Netscape Navigator, controls are displayed and accessible from scripts only when they are contained within a form block. If compatibility with Netscape Navigator is required, the controls must always be contained within a Form element.

Hiding and Showing Intrinsic Controls

Dynamic HTML supports a special type of intrinsic control that is always hidden. Because this control cannot be accessed or manipulated by the user, it is used primarily as a placeholder for a calculated value that is to be submitted with the form. An Input element with its TYPE attribute set to HIDDEN cannot be made visible. Therefore, if you need to dynamically manipulate the visibility of a control, you should use a standard intrinsic control with its CSS (Cascading Style Sheets) display property set to none or its visibility property set to hidden. Later, by changing the visibility or display property, the control can be displayed. Like a HIDDEN Input element, invisible intrinsic controls are submitted with the form's contents. The following code makes an initially invisible control visible. If the intrinsic control was a HIDDEN Input element, the display property would have no effect on it.

<INPUT TYPE=TEXT STYLE="display:none" ID="myTextbox">
<SCRIPT LANGUAGE="JavaScript">
   // Make the text box visible.
   document.all.myTextbox.style.display = "";
</SCRIPT>


Using HIDDEN Input Elements

HIDDEN Input elements are useful mostly for submitting calculated data with a form. Another use of HIDDEN Input elements is to work around a shortcoming in Netscape Navigator that causes script variables to be reinitialized every time the window is resized—by storing the variables in hidden fields, you don't have to worry about the user resizing the window. A hidden field exposes the same object model as the text box without the events related to user interactions.


Interacting with Disabled Intrinsic Controls

Disabled elements appear grayed. However, if a disabled text box contains no contents, the user might not easily recognize that the element is disabled. By checking whether the user interacts with a disabled control using event bubbling, you can provide an explanation to users when they try to click on a disabled control.

Disabled elements do not themselves fire events. Instead, events are fired on the first parent element that is enabled. The following code demonstrates adding a special "disabledError" message to an intrinsic control and then generically testing for it:

<HTML>
   <HEAD>
      <TITLE>Disabled Demonstration</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function checkControl() {
            /* If the user clicks on a disabled control, this code
               displays an error message if one exists. */
            var el = event.srcElement;
            if (el.disabled) {
               var msg = el.getAttribute("disabledError");
               if (null != msg) 
                  alert(msg);
               else
                  alert("You clicked on a disabled element.");
            }
         }
      </SCRIPT>
   </HEAD>
   <BODY ONCLICK="checkControl()">
      <INPUT TYPE=BUTTON DISABLED VALUE="Demo"
         disabledError = "This element is disabled because...">
   </BODY>
</HTML>


NOTE: Early HTML drafts proposed an ERROR attribute for the intrinsic controls. You should avoid adding a custom attribute named error to ensure that no conflict arises if this attribute becomes part of the HTML recommendation in the future.

[Содержание]