XForms-Tiny Testbed - counting checkboxes

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 particular experiment demonstrates the use of author supplied functions in field calculations, along with a library function for counting all ticked checkboxes in a named fieldset. The price is determined by the size of the pizza and the number of toppings selected, where the price per topping varies according to the pizza size.

<input name="total" readonly="readonly"
   calculate="crustPrice(size)+toppingPrice(size)*count(toppings)"/>

Please view the xforms-tiny script for more details on how this works.

Create your own pizza!
Size

Crust

Toppings





Here is the markup for the above form:

<form name="form1">
<fieldset>
<legend>Create your own pizza!</legend>
<fieldset class="size">
<legend>Size</legend>
<input id="size12" name="size" type="radio" value="12"/>
<label for="size12">12 inch (6 slices)</label>
<br />
<input id="size14" name="size" type="radio" value="14"/>
<label for="size14">14 inch (8 slices)</label>
<br />
<input id="size18" name="size" type="radio" value="18"/>
<label for="size18">18 inch (12 slices)</label>
</fieldset>
<fieldset class="crust">
<legend>Crust</legend>
<input id="crust1" name="crust" type="radio" value="regular"/>
<label for="crust1">Regular</label>
<br />
<input id="crust2" name="crust" type="radio" value="thin"/>
<label for="crust2">Thin</label>
<br />
<input id="crust3" name="crust" type="radio" value="thick"/>
<label for="crust3">Thick</label>
</fieldset>
<fieldset class="toppings" name="toppings">
<legend>Toppings</legend>
<input id="topping1" name="cheese" type="checkbox" value="cheese"/>
<label for="topping1">Extra cheese</label>
<br />
<input id="topping2" name="peperoni" type="checkbox" value="peperoni"/>
<label for="topping2">Pepperoni</label>
<br/>
<input id="topping3" name="salami" type="checkbox" value="salami"/>
<label for="topping3">Salami</label>
<br />
<input id="topping4" name="sausage" type="checkbox" value="sausage"/>
<label for="topping4">Sausage</label>
<br />
<input id="topping5" name="jalapenos" type="checkbox" value="jalapenos"/>
<label for="topping5">Jalapenos</label>
<br />
<input id="topping6" name="peppers" type="checkbox" value="peppers"/>
<label for="topping6">Bell peppers</label>
<br />
<input id="topping7" name="onions" type="checkbox" value="onions"/>
<label for="topping7">Onions</label>
</fieldset>

<p><span class="right">
<button type="submit">Add to my order</button>
<button type="reset">Reset</button></span>
<label for="total">Total price</label>
<!-- crustPrice and toppingPrice defined by webpage author -->
<input name="total" readonly="readonly"
  calculate="crustPrice(size)+toppingPrice(size)*count(toppings)"/></p>
</fieldset>
</form>

Comments

If the price of each topping depended on its kind as well as the pizza size, then we would need a library function (countover) that applies a named function for each ticked checkbox in the fieldset and then sums the results. This is a little like the second order function (sumover) used to sum over all rows in a repeated fieldset. A better choice of names for these two functions is needed! A further point to note is that checkboxes evaluate as true or false and not as numeric values. Alternatively, they could evaluate to the string supplied with the value attribute or null if not ticked.

Unlike other browsers, IE doesn't raise the onchanged events immediately on radio buttons and checkboxes. A work around is to act on the change using the onclick event.

A more complete example would show a dynamically generated summary of the order and with a means to edit or delete items. An item might look like "12 inch (6 slices) regular crust with salami, and onions". Generating such summaries together with managing the order data is perhaps a little too ambitious for a forms library, and would need some additional application specific scripting.

Dave Raggett <dsr@w3.org>