Web Forms 2.0 - calculated fields

This is part of a suite of test forms for Web Forms 2.0 for a set of shared examples with XForms Transitional. See the corresponding XForms Transitional example. This demo will only work on a Web Forms 2.0 compliant browser (e.g. Opera 9).

Simple calculation

Here is the markup for the above form:

<script type="text/javascript">
function update()
{
  var form = document.forms[0];
  var sum = eval(form.x.value) + eval(form.y.value);
  form.sum.value = isNaN(sum) ? "" : sum;
}
</script>

<form name="form1" onsubmit="false">
<fieldset>
<legend>Simple calculation</legend>
<label for="f1">X</label>
<input id="f1" name="x" type="number" onchange="update()">
<label for="f2">Y</label>
<input id="f2" name="y" type="number" onchange="update()">
<label for="f3">X + Y</label>
<input id="f3" name="sum" readonly="readonly">
</fieldset>
</form>

I chose to use a read only input element on aesthetic grounds, but an output element would also have been fine. In principle, I could have defined an inline handler for onforminput on the element used to display the result. However, I wanted to avoid displaying NaN if either of the two entry fields were blank or weren't valid numbers. I chose to use eval to parse the numbers and isNaN() to test if the result was a number. This is rather too long for my taste to be included within an attribute value, and I therefore defined it as a function within a script element. This is a lot more complicated than XForms Transitional's calculate="x+y" and would be hard to analyse by machine. The onforminput event is raised on every keystroke without waiting for the input focus to be removed. This is nice, but could create performance problems for forms with large numbers of dependent calculated fields. Excel spreadsheets wait for the focus to move away before updating the spreadsheet.

I wasn't able to get the input fields to change color when you enter something that isn't a valid number, e.g. "abc". I tried styling invalid fields using the :invalid psuedo class using the following CSS rule:

input:invalid { background-color: rgb(255,230,245); color: red }

I also noticed that Opera 9 ignores the readonly attribute when type="number". Opera also ignores the background color for numeric input elements, e.g. as set with the following style rule:

input[readonly] { color: blue;  background-color: rgb(245,240,245) }

Here was an intermediate attempt at the form using the output element and the onforminput attribute:

<form name="form1" onsubmit="false">
<fieldset>
<legend>Simple calculation</legend>
<label for="f1">X</label>
<input id="f1" name="x" type="number">
<label for="f2">Y</label>
<input id="f2" name="y" type="number" onchange="update()">
<label for="f3">X + Y</label>
<output id="f3" name="sum"
onforminput="value = eval(x.value) + eval(y.value)"></output>
</fieldset>
</form>

which you can try out just below here:

Simple calculation

The eval calls convert the values into numbers, and without them the result is the concatenated string values. The next problem is that the output element displays NaN if only one of the two input fields has a number. This requires testing for NaN and substituting an empty string. That gets rather long winded when expressed inline.

Note that the output element's width is zero until it has some content. This is true even if you try to set the CSS width property. I have drawn a border around the output element via CSS to make the width of the output element visible.

Please let me know if you can see any errors in the above, or ways of improving it.

By way of contrast the XForms Transitional markup for this example is the following:

<form name="form1" onsubmit="false">
<fieldset>
<legend>Simple calculation</legend>
<label for="f1">X</label>
<input id="f1" name="x" type="number"/>
<label for="f2">Y</label>
<input id="f2" name="y" type="number"/>
<label for="f3">X + Y</label>
<input id="f3" name="sum" calculate="x+y"
  type="number" readonly="readonly"/>
</fieldset>
</form>
Dave Raggett <dsr@w3.org>