XForms-Transitional Testbed - selection fields

This is part of a series of cross-platform experiments in incremental extensions to HTML4 forms that provide a stepping stone towards the much richer capabilities in XForms. This experiment shows how a field can be calculated based upon a selection control. Price per unit is a calculated field whose value is mapping from the product name.

Try selecting some products and setting the number purchased. The total price should be updated as the focus leaves the changed field. Please view the XForms-Transitional script for more details on how this works.

Repeating groups of fields

Here is the markup for the above form:

<script type="text/javascript">
  var price = {"hammer":7.99, "screwdriver":6.99,
      "spanner":5.99, "saw":20.99, "drill":25.99};
</script>

<form name="form1">
<fieldset name="lineItem" repeat-number="4">
<legend>Repeating groups of fields</legend>
<label for="item">Product Name</label>
<label for="quantity">Number Purchased</label>
<label for="unitprice">Price Per Unit</label>
<select name="item">
<option></option>
<option value="hammer">Hammer</option>
<option value="screwdriver">Screwdriver</option>
<option value="spanner">Spanner</option>
</select>
<input name="quantity" datatype="number" title="number purchased"/>
<input name="unitprice" datatype="number" title="price per unit"
calculate="price[item]" readonly="readonly"/>
</fieldset>

<p><label for="total">Total price</label>
<input name="total" readonly="readonly"
 calculate="sumover(lineItem, quantity*unitprice)"/>
<button type="submit">Submit</button>
<button type="reset">Reset</button></p>
</form>

Comments

The mapping from product name to price is represented here using a JavaScript associative array, but script free alternative would be to use an attribute on the option element used for each of the product names. A predefined function could then be used to extract the value of such attributes. A convenient syntactic short cut for the common case would be to treat "$foo" as equivalent to the value of the price attribute of field "foo".

It isn't practical to replace the select element in a repeating field set with a set of radio buttons due to the way radio buttons are managed as part of the HTML4 forms DOM. A workaround would be to introduce a repeat-index (or row) attribute and to combine that with the name attribute to distinguish radio buttons with the same name but on different rows. The script library could in principle create an input element to carry the value, and rename the input elements for the radio buttons by concatenating the name and the row number, and disabling them just prior to submission, to prevent them from appearing in the submitted data. A much simpler solution is to simply replace the radio buttons via select element.

The library expects a set of fields and matching labels. This is transformed into a table with the number of rows taken from the repeat-number attribute on the fieldset element. This ensures that the labels are aligned with the corresponding columns. Note that there must be a label for each field in the template. A name attribute may be given with the fieldset for use in mapping the form data into an XML data model.

The library currently only supports a fixed number of rows, but in principle, there could be methods to append a new row and to delete an existing row. This assumes a user interface for invoking these functions. It might be simpler to automatically add a new row when the last row is filled out.

An open question is how to initialize repeating field sets when the page is first loaded. One approach is to include markup for all of the fields within the fieldset element. Another approach is to use an attribute on the form element to provide a URI that is used with Ajax to load the form data as XML or JSON. Both approaches will be implemented as further extensions to the forms-lite testbed.

A related issue is how to initialize the data after a "back" or "reload" operation. This isn't a problem if the data is included in the page's markup, and only occurs when the fields are generated automatically. Ideally, there would be a way for web page scripts to access the history state for the current page as this would allow the script to restore the state for dynamically generated markup.

Dave Raggett <dsr@w3.org>