XHTML Module: Extensions to Form Controls

Opera Working Draft, September 2003

Editor:
Ian Hickson, Opera Software, ian@hixie.ch

Abstract

[abstract]

Status of this Document

This is a work in progress! This document is changing on a daily if not hourly basis in response to comments and as a general part of its development process. Comments are very welcome, please send them to htmlforms@damowmow.com and cc w3c-archive@w3.org. Thank you.

It is very wrong to cite this as anything other than a work in progress. Do not implement this in a production product. It is not ready yet! At all!

Table of Contents


1. Introduction

The following features are considered requirements for this proposal:

1.1. Relationship to XForms

XForms is a large and unwieldy specification that is not backwards compatible with existing, widely deployed, HTML forms user agents. By splitting traditional HTML forms into three parts — XForms model, instance data, and user interface — it separates logically related parts, complicates reuse, allows external data typing — increasing the number of round-trips to the server — as well as increasing the device requirements and reducing the ability for authors familiar with scripting to reuse their knowledge.

XForms is not a free-standing document type, but nonetheless introduces yet another namespace into the W3C fold, further increasing its the complexity for authors.

This proposal attempts to add the functionality of XForms with a minimum impact on the existing, widely implemented model. Where appropriate, backwards compatiblity, ease of authoring, and ease of implementation have been given priority over theoretical purity.

The following features of XForms have not been addressed:

The majority of the features that XForms supports using declarative syntax are, in this proposal, handled by using scripting. Some new interfaces are introduced to simplify some of the more tedious tasks.

1.2. Conformance Requirements

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

Diagrams, examples, and notes are non-normative. All other content in this specification is intended to be normative.

2. Extensions to Form Control Elements

HTML input elements use the type attribute to specify the data type. In HTML4, the types are:

text
A freeform text input, nominally free of line breaks.
password
A freeform text input for sensitive information, nominally free of line breaks.
checkbox
A set of zero or more values from a predefined list (in the limiting case of the list only containing one value, this is equivalent to a boolean).
radio
An enumerated value.
submit
An enumerated value, with the extra semantic that it must be the last value selected and initiates form submission.
file
An arbitrary file with a MIME type and optionally a file name.
image
A coordinate, relative to a particular image's size.

Three other types, reset, hidden, and button, are also available, but are either not real data types, or not modifiable by the user, and so are not considered here.

In addition, HTML also provides a few alternate elements that convey typing semantics similar to the above types, but use different data models:

select
An enumerated value, much like the radio type.
select multiple
A set of zero or more values from a predefined list, much like the checkbox type.
textarea
A freeform text input, nominally with no line break restrictions.

These types are useful, but limited. This section expands the list to cover more specific data types, and introduces attributes that are designed to constrain data entry or other aspects of the UA's behaviour.

In addition to the attributes described below, some changes are made to the content model of HTML form elements to take into account scripting needs. Specifically, the form, legend, select, and optgroup elements may now be empty (in HTML4, those elements always required at least one element child, or, in the case of legend, at least one character of text).

2.1. Extensions to the input element

Several new types are introduced for the type attribute. Like as with the older types, UAs are encouraged to show specialised widgets for these types, instead of requiring that the user enter the data into a text field.

datetime
A date and time encoded according to [ISO8601] with the time zone set to UTC, e.g.: 1995-12-31T23:59:59Z. User agents are expected to show an appropriate widget.

For example, a UA could show a text field with editable sections for each value, with a button to pop up a dialog showing a calendar or clock.

UAs may display the time in whatever time zone is appropriate for the user, but should be clear that the time is globally defined, not time-zone dependent.
date
A date encoded according to [ISO8601], e.g.: 1995-12-31. User agents are expected to show an appropriate widget, such as a calendar.
expdate
A date consisting of a year and a month encoded according to [ISO8601], e.g.: 2003-08. This type is used most frequently for credit card expiry dates.
time
A time encoded according to [ISO8601] with no time zone, e.g.: 23:59:59. User agents are expected to show an appropriate widget, such as a clock. UAs should make it clear to the user that the time does not carry any time zone information.
number
An arbitrary precision real number, written out with an optional minus sign ("-"), a decimal integer, a decimal point (".") and a decimal fractional part, together forming a number representing the base, followed by the lowercase literal letter "e", another optional minus sign, and a decimal integer exponent representing the index of a power of ten with which to multiply the base to get the resulting number. For example, negative-root-two, to 32 significant figures, would be -1.4142135623730950488016887242097e0, while the radius of the earth given in furlongs would be 3.17053408e4. This format is designed to be compatible with scanf(3)'s %f format and similar parsers while being easier to parse than required by some other floating point syntaxes. Note that 0, 0e+0, +0e0 are invalid numbers (the exponent is not optional, and the minus sign cannot be replaced by a plus sign for positive numbers, it must simply be dropped) and UAs must therefore not serialize numbers in those formats.
integer
An integer, written as a series of decimal digits optionally prefixed by a minus sign ("-").
email
An e-mail address, as defined by [RFC822] (the mailbox token, defined in section RFC822 6.1).

To limit the range of values allowed by the above types, two new attributes are introduced, which apply to the date-related, time-related, and numeric types:

minimum
Gives the minimum value (inclusive) of the field, in the format specified for the relevant type. If absent, or if the value is not in the expected format, this should be treated as negative infinity (or the equivalent for the relevant type).
maximum
Gives the maximum value (inclusive) of the field, in the format specified for the relevant type. If absent, or if the value is not in the expected format, this should be treated as positive infinity (or the equivalent for the relevant type).

UAs must not submit forms that contain fields whose values do not match their types (ERROR_TYPE_MISMATCH) or whose values are outside the allowed range (ERROR_RANGE_UNDERFLOW, ERROR_RANGE_OVERFLOW).

Note that fields may have no value, in which case they aren't "successful", do not take part in submission, and therefore do not need to have their values match their types (unless they are required fields).

The following form uses some of the types described above:

<form action="..." method="post" onsubmit="verify(event)">
 <p>
  <label>
   Quantity:
   <input name="count" type="integer" minimum="0" maximum="99" value="1" />
  </label>
 </p>
 <p>
  <label for="time1"> Preferred delivery time: </label>
  <input id="time1" name="time1" type="time" minimum="08:00:00" maximum="17:00:00" value="08:00:00" /> —
  <input id="time2" name="time2" type="time" minimum="08:00:00" maximum="17:00:00" value="17:00:00" />
 </p>
 <script type="text/javascript">
  function verify(event) {
    // check that time1 is smaller than time2, otherwise, swap them
    if (event.target.time1 &gt;= event.target.time2) { // ISO8601 times are string-comparison safe.
      var time2 = event.target.time2;
      event.target.time2 = event.target.time1;
      event.target.time1 = time2;
    }
  }
 </script>
</form>

Servers should still perform type checking on submitted data, as malicious users or rogue user agents might submit data intended to bypass this client-side type checking.

The size attribute of the input element is deprecated in favour of using CSS to specify the layout of the form.

2.2. Extensions to the select element

In addition to the new types above, the select element is extended to allow for a free-form input control which has author-specified auto-completion values.

editable
This attribute specifies that the select element's value can be one other than those specified in the list of option elements.

For example, a Web page may wish to ask a user to enter a filename, offering some suggested names but allowing the user to enter other names as well:

<select name="filename" editable="editable">
  <option>My First Holiday</option>
  <option>untitled1.txt</option>
</select>

When this attribute is specified, the DOM type attribute has the value "edit-one".

If both editable and multiple are specified, the UA must allow the user to enter multiple free-form values. This kind of interface is sometimes seen in mail user agents for their "To:" fields, for instance.

When both these attributes are specified, the DOM type attribute has the value "edit-multiple". The DOM HTMLSelectElement interface is extended to have a new attribute values of type DOMStringList that represents the currently selected or entered values.

In documents conforming to this module, select elements need not have any option elements.

2.3. Extensions to the textarea element

The rows and cols attributes of the textarea element are no longer required attributes. When unspecified, CSS-compliant browsers should lay the element out as specified by CSS, and non-CSS UAs may use UA-specific defaults, such as, for visual UAs, using the width of the display device and a height suitable for the device.

The textarea element may have a wrap attribute specified. This attribute controls the wrapping behaviour of submitted text.

soft
This is the default value. The text is submitted without line breaks other than explicitly entered line breaks. (In other words, the submitted text is exactly as found in the DOM.)
hard
The text is submitted with explicit line breaks, and in addition, line breaks added to wrap the text at the width given by the cols attribute. (These additional line breaks can't be seen in the DOM.)

Authors should always specify a cols attribute when the wrap attribute is set to hard. When wrap="hard" is specified without a cols attribute, user agents should use the display width when wrapping the text for submission. This will typically mean that different users submit text at different wrapping widths, defeating much of the purpose of client-side wrapping.

CSS UAs should render textarea elements as specified by the 'white-space' property, although UAs may have rules in their UA stylesheet that key the default 'white-space' property values based on the wrap element for textarea elements.

2.4. Extensions to existing attributes

In addition to the new attributes given in this section, some existing attributes from HTML4 are clarified:

accept
The file upload control (<input type="file">) uses the accept attribute to specify a comma-separated list of content types that a server processing the form will handle correctly. In this module, this attribute is extended as follows:
disabled
The disabled attribute applies to all control types, including fieldset (in HTML4 the disabled attribute did not apply to the fieldset element).

maxlength
This attribute only applies to text and password input types. In particular, it does not apply to the date-related, time-related, and numeric field types, nor to the email type. When this attribute is specified, the server must not submit a form with the control having more than the specified number of characters (ERROR_TOO_LONG).
readonly
This attribute only applies to text, password, email, date-related, time-related, and numeric input types, as well as the textarea element. Specifically, it does not apply to radio buttons, check boxes, file upload fields, select elements (editable or not), or any of the button types; the interface concept of "readonly" values does not apply to button-like interfaces. (The DOM readonly attribute obviously applies to the same set of types as the HTML attribute.)

Other attributes not listed here retain the same semantics as in HTML4.

2.5. The pattern attribute

For the text type of the input element, the select element when it has the new editable attribute set, and the textarea element, a new attribute, pattern, is introduced to specify patterns that the strings must match.

When specified, the pattern attribute contains a regular expression that the field's value must match before the form may be submitted (ERROR_PATTERN_MISMATCH).

<label> Credit Card Number:
 <input type="text" pattern="^[0-9]{10}$" name="cc" />
</label>

The regular expression language used for this attribute is the same as that defined in [ECMA262].

UAs must refuse to submit forms that contain fields whose values do not match their patterns.

2.6. The required attribute

Form controls can have the required attribute specified, to indicate that the user must enter a value into the form control before submitting the form.

For check boxes, those with the type hidden, and disabled controls, the attribute has no effect. The required attribute applies to all other form controls. It can be used on controls with the readonly attribute set; this may be useful in scripted environments.

User agents must not submit forms that have form controls marked as required that do not have values (ERROR_REQUIRED). For radio buttons, exactly one radio button from each set must be checked.

Here is a form fragment showing two required fields and one optional field. A user agent would not allow the user to submit the form until the "name" and "team" fields were filled in.

<ul>
  <li>Name: <input type="text" name="name" required="required" /></li>
  <li>Team:
    <select name="team" required="required">
      <option value="fox">The Foxes</option>
      <option value="ferrets">The Ferrets</option>
      <option value="kittens">The Kittens</option>
    </select>
  <li>Comment: <input type="text" name="comment" /></li>
  </li>
</ul>

2.7. The form attribute

All form controls can have the form attribute specified. The form attribute gives the ID of the form element the form control should be associated with, and overrides the relationship between the form control and any ancestor form element.

An element with a form attribute pointing to a non-existent form is treated like an element with no form element ancestor (even if it has such an ancestor). Setting the form attribute to the empty string (as in form="") disassociates the form control from its form.

When set on a fieldset element, this also changes the association of any descendant form controls, unless they have form attributes of their own.

When forms are submitted, reset, or have their form controls enumerated through the DOM, only those controls associated with the form are taken into account. A control can only be associated with one form at a time.

In this example, each row contains one form, even though it would not normally be possible to have more than one form per table if any of them span cells.

<table>
 <thead>
  <tr>
   <th>Name</th>
   <th>Value</th>
   <th>Action</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>
    <form id="edit1" action="/edit" method="post">
     <input type="hidden" name="id" value="1"/>
     <input type="text" name="name" value="First Row"/>
    </form>
   </td>
   <td>
    <input form="edit1" type="text" name="value"/>
   </td>
   <td>
    <input form="edit1" type="submit" name="Edit"/>
   </td>
  </tr>
  <tr>
   <td>
    <form id="edit2" action="/edit" method="post">
     <input type="hidden" name="id" value="2"/>
     <input type="text" name="name" value="Second Row"/>
    </form>
   </td>
   <td>
    <input form="edit2" type="text" name="value"/>
   </td>
   <td>
    <input form="edit2" type="submit" name="Edit"/>
   </td>
  </tr>
 </tbody>
</table>

2.8. The autocomplete attribute

All form controls except the various push button controls and hidden controls, can have the autocomplete attribute set. The attribute takes two values, true and false. The default, when the attribute is not specified, is true.

A true value means the UA is allowed to store the value entered by the user so that if the user returns to the page, the UA can prefill the form. A false value means that the UA must not remember that field's value.

Banks frequently do not want UAs to prefill login information:

<p>Account: <input type="text" name="ac" autocomplete="false" /></li>
<p>PIN: <input type="text" name="pin" autocomplete="false" /></li>

2.9. The inputmode attribute

The inputmode attribute applies to the input element when it has a type attribute of text, password, or email, to the select element when it has a the editable attribute set, and to the textarea element.

This attribute is defined to be exactly equivalent to the inputmode attribute defined in the XForms PR Draft.

2.10. The help attribute

Any form control can have a help attribute specified. This attribute contains a URI that the UA may use to provide help information regarding the active field.

This specification does not specify how help information should be used, but for example, the UA could show a small popup window if the user focusses such a control and pressed the F1 key, or could show the help information in a sidebar while the relevant control is focussed.

This attribute is added mainly because XForms has it, to show that it would be trivial to add to HTML as well. However, there is some doubt that it is actually a useful feature.

3. Form Validation

With the introduction of the various type checking mechanisms, some way for scripting authors to hook into the type checking process is required. This is provided by the FormError event (formerror), of type FormEvent.

When a form is submitted, each control in that form, in document order, is checked for validity. For each control that fails to comply with its constraints, a formerror event should be fired on the control.

The onformerror attribute (on input elements) can be used to write handlers for this event.

/* Similar to the UIEvent interface */
interface FormEvent : Event {
  const unsigned short      ERROR_TYPE_MISMATCH            = 1;
  const unsigned short      ERROR_RANGE_UNDERFLOW          = 2;
  const unsigned short      ERROR_RANGE_OVERFLOW           = 3;
  const unsigned short      ERROR_TOO_LONG                 = 4;
  const unsigned short      ERROR_PATTERN_MISMATCH         = 5;
  const unsigned short      ERROR_REQUIRED                 = 6;
  const unsigned short      ERROR_USER_DEFINED             = 256;

  readonly attribute long             validationError;
  void               initFormEvent(in DOMString typeArg, 
                                   in boolean canBubbleArg, 
                                   in boolean cancelableArg, 
                                   in long validationErrorArg);
};

The FormError event has contextual information, given by the validationError attribute. It's value is one of the ERROR_XXX constants.

ERROR_TYPE_MISMATCH
The data entered does not match the type of the control. For example, if the UA allows uninterpreted arbitrary text entry for expdate fields, and the user has entered SEP02, then this error code would be used. This code is also used when the selected file in a file upload control does not have an appropriate MIME type.
ERROR_RANGE_UNDERFLOW
The numeric, date, or time value of a field with a minimum attribute is lower than the minimum.
ERROR_RANGE_OVERFLOW
The numeric, date, or time value of a field with a maximum attribute is higher than the maximum.
ERROR_TOO_LONG
The value of a field with a maxlength attribute is longer than the attribute allows.
ERROR_PATTERN_MISMATCH
The value of the field with a pattern attribute doesn't match the pattern.
ERROR_REQUIRED
The field has the required attribute set but has no value.
ERROR_USER_DEFINED
The field was marked invalid from script.

When the definitions above refer to elements that have an attribute set on them, they do not refer to elements on which that attribute is defined not to apply. For example, the ERROR_REQUIRED code cannot be sent to an <input type="checkbox"> element, even if that element has the required attribute set, since required doesn't apply to check boxes.

The FormError event bubbles. If a formerror event is targetted at, or bubbles into, a form control with a form attribute pointing to a valid form, it continues bubbling not at the node's parent, but at the specified form element.

The FormError event is cancellable. The default behaviour is UA-specific, but is expected to consist of focussing the element, and alerting the user that the entered value is unacceptable, in the user's native language, and along with explanatory text saying why the value is currently invalid. UAs would typically only do this for the first form control found to be invalid; while the event is dispatched to all invalid controls, it is simpler for the user to deal with one error at a time.

On-the-fly validation hooks will be provided as part of a CSS or DOM module on Dynamic UI.

4. XML Submission

This section defines the expected behaviour for step 3, "Step three: Encode the form data set", of the submission algorithm described in HTML4, for the form content type application/x-form-submission+xml. The rest of the form submission process progresses as described in the HTML specification.

When the form's enctype attribute is set to this value, the method attribute must specify a method that expects a message entity (i.e., not 'GET'). If an unsuitable method is given, or if no method is specified, the method is assumed to be 'POST'.

The message entity is an XML 1.0 document, encoded as UTF-8, which has a root element named "submission" in no namespace. UA may include an XML declaration but this is not necessary as it would be redundant (the MIME type and version must not be changed from the above values, and submission documents have no document type and therefore are always standalone.).

Generally, for each successful control, in the order that the controls are to be found in the original document, an element field in no namespace is inserted, with an attribute name having the name of the form control, and with the element content being the value of the form control. Form controls with multiple values result in multiple field elements being inserted into the output, one for each value.

File controls are submitted using a file element instead of a field element. The file element has three attributes, name, filename, and type. The name attribute contains the name of the file control. The filename attribute is optional and may contain the name of the file. The type attribute is not optional and must contain the MIME type of the file. The contents of the file are base64 encoded and then included literally as content directly inside the file element. As base64 data is whitespace-clean, UAs may introduce whitespace into the file element to ensure the submitted data has reasonable line lengths. This is, however, completely optional. (It is primarily intended to make it possible to write readable examples of submission output.)

UAs may use either CDATA blocks, entities, or both in escaping the contents of attributes and elements, as appropriate. The resulting XML must be a well-formed XML instance.

Whitespace may be inserted around elements that are children of the submission element in order to make the submitted data easier to scan by eye. However, this is optional. Processors should not be affected by such whitespace, or whitespace inside file elements, when reading the submitted data back from the XML instance. (Whitespace inside field elements is significant, however.)

The following example illustrates application/x-form-submission+xml encoding. Suppose we have the following form:

 <form action="http://server.com/cgi/handle"
       enctype="application/x-form-submission+xml"
       method="post">
   <p>
    <label> What is your name? <input type="text" name="submit-name"/> </label>
    <label> What files are you sending? <input type="file" name="files"/> </label>
    <label> When were they written? <input type="date" name="stamp"/> </label>
   <input type="submit" value="Send"> <input type="reset"/>
 </form>

If the user enters "Larry" in the text input, selects the text file "file1.txt", and picks an arbitrary date, the user agent might send back the following data:

   Content-Type: application/x-form-submission+xml

   <submission>
    <field name="submit-name">Larry</field>
    <file name="files" filename="file1.txt" type="text/plain;charset=iso-8859-1">
     Y29udGVudHMgb2YgZmlsZTEudHh0
    </file>
    <field name="stamp">1979-04-13</field>
   </submission>

If the user selected a second (image) file "file2.png", and changes the date, the user agent might construct the entity as follows:

   Content-Type: application/x-form-submission+xml

   <submission>
    <field name="submit-name">Larry</field>
    <file name="files" filename="file1.txt" type="text/plain;charset=iso-8859-1">
     Y29udGVudHMgb2YgZmlsZTEudHh0
    </file>
    <file name="files" filename="file2.png" type="image/png"$gt;
     iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAABGdBTUEAAK
     /INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwA
     AAAGUExURQD/AAAAAG8DfkMAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAA
     AASUVORK5CYII=
    </file>
    <field name="stamp">1979-12-27</field>
   </submission>

Note how the content of the plain text attached file is base64-encoded, despite being a plain text file. This preserves the integrity of the file in cases where the MIME type is incorrect. It also means that files with malformed content, for example a file encoded as UTF-8 with stray continuation bytes, will be transmitted faithfully instead of being re-encoded by the UA.

[after the document has been created, an onXMLSubmit event is fired on the form with a mutable version of the document node of the submission document as its context information. this could be passed to an XSLT processor to turn the submision XML into a new format.]

5. Dynamic Form Manipulation

There are several aspects of XForms that have been traditionally achieved using scripts. This section gives some samples that show how to use existing DOM interfaces and scripting to replicate some of this XForms functionality.

The intent is that a future version of this specification will change this section from giving examples to specifying a formal interface that turns the most frequently used blocks of code into standardised functions.

5.1. Repeating a block of form controls

The following example shows how to use scripting to dynamically add more rows to a form in a table.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
 <head>
  <title>Form Repeat Demo</title>
  <script type="text/javascript" src="library.js"></script>
  <script type="text/javascript">
   var count = 1;
   var template;
   function init() {
     template = repeatFormControlBlock(document.getElementById('row_1'), 'template');
   }
   function addRow(event) {
     document.getElementById('data').appendChild(repeatFormControlBlock(template, ++count));
   }
   function deleteRow(event) {
     row = event.target.parentNode.parentNode;
     row.parentNode.removeChild(row);
   }
  </script>
 </head>
 <body onload="init()">
  <form action="http://software.hixie.ch/utilities/cgi/test-tools/echo" method="post" enctype="multipart/form-data">
   <table>
    <thead>
     <tr>
      <th>Name</th>
      <th>Count</th>
      <th></th>
     </tr>
    </thead>
    <tbody id="data">
     <tr id="row_1">
      <td><input type="text" name="name_1" value=""></td>
      <td><input type="text" name="count_1" value="1"></td>
      <td><input type="button" value="Delete Row" onclick="deleteRow(event)"></td>
     </tr>
    </tbody>
   </table>
   <p>
    <input type="button" onclick="addRow(event)" value="Add Row">
   </p>
  </form>
 </body>
</html>

The above example assumes the following functions are available, for example in an external script library.

/* repeatFormControlBlock (Element, String) : Element */
/* Takes a DOM element, clones it, resets any form controls within the
 * cloned content to their initial values, changes their name and ID
 * attributes by stripping everything from the last underscore to the
 * end of the name and replacing it with the second argument, and
 * returns the new element. */
/* Callers are expected to take the return value and insert it into
 * the parent of the first argument. */
/* This implementation is specific to the HTML DOM and would not work
 * for XHTML documents. It would be relatively simple to extend this
 * function to cope with other cases such as that, as well as handling
 * UA-specific requirements. Doing so is left as an exercise to the
 * reader. */
function repeatFormControlBlock(template, newID) {
  // clone the node.
  var newNode = template.cloneNode(true);
  // walk the node, resetting form controls.
  var node = newNode;
  while (true) {
    // reset the node
    if (node instanceof HTMLOptionElement) {
      node.selected = node.defaultSelected;
    } else if (node instanceof HTMLInputElement) {
      node.checked = node.defaultChecked;
      node.value = node.defaultValue;
    } else if (node instanceof HTMLTextAreaElement) {
      node.value = node.defaultValue;
    }
    if (node instanceof HTMLSelectElement ||
        node instanceof HTMLInputElement ||
        node instanceof HTMLTextAreaElement ||
        node instanceof HTMLButtonElement) {
      node.name = _rename(node.name, '_', newID);
    }
    if (node instanceof HTMLElement) {
      node.id = _rename(node.id, '_', newID);
    }
    // crawl
    if (node.firstChild) {
      node = node.firstChild;
    } else {
      while (!node.nextSibling) {
        node = node.parentNode;
        if (node == newNode) {
          return newNode;
        }
      }
      node = node.nextSibling;
    }
  }
}

function _rename(name, separator, suffix) {
  // strip the current suffix if there is one
  var pos = name.lastIndexOf(separator);
  if (pos >= 0)
    name = name.substring(0, pos);
  // add the new suffix and return it
  return name + separator + suffix;
}

5.2. Displaying alternative sections dynamically

[...]

5.3. Keeping form controls synchronised

[...]

6. Extensions to the HTML Level 2 DOM interfaces

[...]

[.validate() method to force the form control to be validated and have onFormError events sent to it if appropriate]

[.selectedItems attribute for select elements]

[.markValid() and .markInvalid() methods to override the automatic type checking]

A. XHTML Module Definition

The Forms Extensions Module provides all of the forms features found in HTML 4.0, plus the extensions described above. Specifically, the Forms Extensions Module supports:

Elements Attributes Minimal Content Model
form Common, accept (ContentTypes), accept-charset (Charsets), action* (URI), method ("get"* | "post"), enctype (ContentType) (Heading | List | Block - form | fieldset)*
input Common, accept (ContentTypes), accesskey (Character), alt (Text), autocomplete ("true"* | "false"), checked ("checked"), disabled ("disabled"), form (IDREF), help (URI), inputmode (CDATA), maxlength (Number), minimum (CDATA), maximum (CDATA), name (CDATA), pattern (CDATA), readonly ("readonly"), required ("required"), size (Number), src (URI), tabindex (Number), type ("text"* | "password" | "checkbox" | "radio" | "button" | "submit" | "reset" | "file" | "hidden" | "image" | "datetime" | "date" | "expdate" | "time" | "number" | "integer" | "email"), value (CDATA), EMPTY
select Common, autocomplete ("true"* | "false"), disabled ("disabled"), editable ("editable"), form (IDREF), help (URI), inputmode (CDATA), multiple ("multiple"), name (CDATA), pattern (CDATA), required ("required"), size (Number), tabindex (Number) (optgroup | option)*
option Common, disabled ("disabled"), label (Text), selected ("selected"), value (CDATA) PCDATA
textarea Common, accesskey (Character), autocomplete ("true"* | "false"), cols (Number), disabled ("disabled"), form (IDREF), help (URI), inputmode (CDATA), name (CDATA), readonly ("readonly"), required ("required"), rows (Number), tabindex (Number), wrap ("soft"* | "hard") PCDATA
button Common, accesskey (Character), disabled ("disabled"), form (IDREF), help (URI), name (CDATA), tabindex (Number), type ("button" | "submit"* | "reset"), value (CDATA) (PCDATA | Heading | List | Block - Form | Inline - Formctrl)*
fieldset Common, disabled ("disabled"), help (URI), (PCDATA | legend | Flow)*
label Common, accesskey (Character), for (IDREF) (PCDATA | Inline - label)*
legend Common, accesskey (Character) (PCDATA | Inline)*
optgroup Common, disabled ("disabled"), label* (Text) option*

This module defines two content sets:

Form
form | fieldset
Formctrl
input | select | textarea | label | button

When this module is used, it adds the Form content set to the Block content set and it adds the Formctrl content set to the Inline content set as these are defined in the Text Module.

The Forms Extensions Module is a superset of the Forms and Basic Forms modules. These modules may not be used together in a single document type.

B. Attribute Summary

The input element takes a large number of attributes that do not always apply. The following table summarizes which attributes apply to which input types.

type text password checkbox radio button submit reset file hidden image datetime date expdate time number integer email
accept - - - - - - - Yes - - - - - - - - -
accesskey Yes Yes Yes Yes Yes Yes Yes Yes - Yes Yes Yes Yes Yes Yes Yes Yes
alt - - - - - - - - - Yes - - - - - - -
autocomplete Yes Yes Yes Yes - - - Yes - - Yes Yes Yes Yes Yes Yes Yes
checked - - Yes Yes - - - - - - - - - - - - -
disabled Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
form Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
help Yes Yes Yes Yes Yes Yes Yes Yes - Yes Yes Yes Yes Yes Yes Yes Yes
inputmode Yes Yes - - - - - - - - - - - - - - Yes
maxlength Yes Yes - - - - - - - - - - - - - - -
minimum - - - - - - - - - - Yes Yes Yes Yes Yes Yes -
maximum - - - - - - - - - - Yes Yes Yes Yes Yes Yes -
name Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
pattern Yes Yes - - - - - - - - - - - - - - -
readonly Yes Yes - - - - - - - - Yes Yes Yes Yes Yes Yes Yes
required Yes Yes - Yes - - - Yes - - Yes Yes Yes Yes Yes Yes Yes
size Yes Yes - - - - - - - - - - - - - - Yes
src - - - - - - - - - Yes - - - - - - -
tabindex Yes Yes Yes Yes Yes Yes Yes Yes - Yes Yes Yes Yes Yes Yes Yes Yes
value Yes Yes Yes Yes Yes Yes Yes - Yes - Yes Yes Yes Yes Yes Yes Yes

C. Relation to the CSS3 User Interface module

CSS3 introduces a number of pseudo-classes for form controls. Their relationship to the form controls described in this specification is described here.

:enabled
Matches form control elements that do not have the disabled attribute set.
:disabled
Matches form control elements that do have the disabled attribute set.
:checked
Matches radio and check box form control elements that are checked.
:indeterminate
Matches no HTML form control elements.
:default
Matches the button (if any) that will be selected if the user presses the enter key (or some equivalent behavior on less typical systems).
:valid
Matches form control elements that would not have the formerror event fired at them if the form was submitted.
:invalid
Matches form control elements that would have the formerror event fired at them if the form was submitted.
:in-range
Matches numeric, date-related, or time-related form control elements when the current value is type-correct, greater than or equal to the minimum (if any), and less than or equal to the maximum (if any).
:out-of-range
Matches numeric, date-related, or time-related form control elements when the current value is type-correct, but either less than the minimum or greater than the maximum.
:required
Matches form control elements that have the required attribute set.
:optional
Matches form control elements that do not have the required attribute set.
:read-only
Matches form control elements that have the readonly attribute set.
:read-write
Matches form control elements that do not have the readonly attribute set (including password fields, although technically they should be called "writeonly").

When the definitions above refer to elements that have an attribute set on them, they do not refer to elements on which that attribute is defined not to apply. For example, the :read-only attribute cannot apply to a <input type="radio"> element, even if that element has the readonly attribute set, since readonly doesn't apply to radio buttons.

D. References

[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997. RFC2119 is available at http://www.ietf.org/rfc/rfc2119
[RFC822]
Standard for the Format of ARPA Internet Text Messages, David H. Crocker. IETF, August 1982. RFC822 is available at http://www.ietf.org/rfc/rfc822
[ISO8601]
ISO8602:2000 Data elements and interchange formats -- Information interchange -- Representation of dates and times. ISO, December 2000. ISO8601 is available for purchase at http://www.iso.ch/
[EMCA262]
ECMAScript Language Specification, Third Edition. European Computer Manufacturers Association, December 1999. This version of the ECMAScript Language is available at http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM

E. Acknowledgements

Thanks to Håkon Wium Lie, Maciej Stachowiak, David Hyatt, Peter N Stark, and John Keiser for their comments.

Thanks to the XForms working group for unintentionally giving the incentive to develop this module.