XForms 1.2 Simplified Syntax Proposal

To summarize the XForms 1.2 Simplified Syntax Proposal (so far):

1) An "on the glass" syntax in which name attributes and UI hierarchy are 
used to imply an underlying data structure.

2) The implied data structure will mean that the data names are directly 
referenceable in calculations without an author having to understand any 
complicated XPath.  If the author must refer to something that is not at 
the same logical level in the UI hierarchy, then a simple slash-based 
addressing scheme suffices.  This is still not any complicated XPath to 
understand.  It means that someone could write a simple purchase order 
using syntax that looks like this:

<repeat name="row"> 
    <select1 name="Product"> ... 
    <input name="Price" type="decimal" default="0.00"> ... 
    <input name="Quantity" type="integer" default="0"> ... 
    <output name="LineTotal" calculate="Price * Quantity"/> 
</repeat> 
<output name="Subtotal" calculate="sum(row/LineTotal)"/> 
<output name="Tax" calculate="Subtotal * 0.07"/> 
<output name="Total" calculate="Subtotal + Tax"/> 

3) The name attributes and UI hierarchy will also imply a matching set of 
hierarchic "bind" elements is id and nodeset attributes whose values match 
the name.  The binds will be addressable in calculation expressions using 
a simple "variable" concept in which the name is preceded by a dollar 
sign.  It means that someone could also write the simple purchase order by 
doing this:

<repeat name="row"> 
    <select1 name="Product"> ... 
    <input name="Price"> ... 
    <input name="Quantity"> ... 
    <output name="LineTotal" calculate="$Price * $Quantity"/> 
</repeat> 
<output name="Subtotal" calculate="sum($LineTotal)"/> 
<output name="Tax" calculate="$Subtotal * 0.07"/> 
<output name="Total" calculate="$Subtotal + $Tax"/> 

4) The simplified syntax for triggering "insert row" and "delete row" are 
yet to be worked out, but I suspect from the HTML perspective, someone 
would add a button whose "onclick" would use the updated IDL interface we 
will be doing to call insert and delete and setvalue actions via script. 
In HTML, it might look something like this:

<button ... onclick="insert('row')" ... >
<button ... onclick="delete('row')" ... >

The simplicity here is coming from selection of the best defaults for 
insert and by also assuming that the occurrence of repeat will result in a 
template instance being created with an ID that is based on the repeat 
name.  So the defaults for insert should be position="after" 
at="index('row')" and origin="instance('row_template')" and context=".". 
Note that in all places where I used the word "row", substitute whatever 
the name attribute value from the repeat.

5) There are some XForms processing model updates that will be needed to 
allow the above to be seamlessly mapped to canonical XForms:

a) We need to add MIP child elements to bind that allow us to set the 
context to ".." and re-use the same expression as the simplified syntax. 
This is another way of saying that, for simplified syntax, the calculate 
style expressions take the in-scope eval context node and the context of 
the expression.

b) The nodesets of identified binds are available as variables to all 
XPath expressions *except* the nodeset attribute of bind elements.

c) The processing model for rebuild is defined to consist of a first pass 
to resolve all bind nodesets then a second pass to evaluate MIP 
expressions.

d) The nodeset associated with a variable reference is decided based on 
the variable name and the context node for the XPath expression.    This 
allows us to select the correct occurrence of an inner bind whose nodeset 
must be returned.  However, sometimes it will be the union of nodesets 
from multiple inner binds if the context node is associated with a 
containing ancestor bind.  Implementations should be able to cache these 
(name, context, nodeset) tuples between rebuilds.

e) MIP attributes at the UI level are converted to MIP statements within 
the generated binds. 

f) Aside from implying a data layer and bind layer, the name attributes in 
the UI components also imply UI bindings to the bind layer.  In the case 
of the name on repeat, an extra empty template instance is also implied 
for use by insert.

Based on these adjustments to the normal semantics of XForms, both 
simplified syntax lists above would correspond to the following 
"canonical" XForm:

<model> 
  <instance id="default"> 
    <data xmlns=""> 
      <row> 
         <Product>... 
         <Price>... 
         <Quantity>... 
         <LineTotal>... 
      </row> 
      <row> 
         <Product>... 
         <Price>... 
         <Quantity>... 
         <LineTotal>... 
      </row> 
      <Subtotal>... 
      <Tax>... 
      <LineTotal>... 
    </data> 
  </instance> 

  <instance id="row_template"> 
      <row xmlns=""> 
         <Product></Product> 
         <Price>0.00</Price> 
         <Quantity>0</Quantity> 
         <LineTotal></LineTotal> 
      </row> 
  </instance> 
 
  <bind id="row" nodeset="row"> 
    <bind id="Product" nodeset="Product"/> 
    <bind id="Price" nodeset="Price" type="decimal"/> 
    <bind id="Quantity" nodeset="Quantity" type="integer"/> 
    <bind id="LineTotal" nodeset="LineTotal">
       <calculate context=".." value="Price * Quantity" or "$Price * 
$Quantity"/> 
    </bind>
  </bind> 
  <bind id="Subtotal" nodeset="Subtotal">
     <calculate context=".." value="sum(row/LineTotal)" or 
"sum($LineTotal)"/> 
  </bind>
  <bind id="Tax" nodeset="Tax">
     <calculate context=".." value="Subtotal * 0.07" or "$Subtotal * 
0.07"/> 
  </bind>
  <bind id="Total" nodeset="Total">
     <calculate context=".." value="Subtotal + Tax" or "$Subtotal + 
$Tax"/> 
  </bind>
</model>

<repeat bind="row"> 
    <select1 bind="Product"> ... 
    <input bind="Price"> ... 
    <input bind="Quantity"> ... 
    <output bind="LineTotal"/> 
</repeat>
<output bind="Subtotal"/>
<output bind="Tax"/> 
<output bind="Total"/> 

<trigger>
    <label>...</label>
    <insert ev:event="DOMActivate" context="." bind="row" 
at="index('row')" position="after" origin="instance('row_template')"/>
</trigger>
<trigger>
   <label>...</label>
   <delete bind="row" at="index('row')"/>
</trigger>

6) The final piece is the submission, which we think is just implied from 
the HTML form element's attributes, except we need to talk about how to 
trigger XML submission versus tag-value pairs.  Still a bit more work 
needed here to nail it down at the same level of precision as the above.

Cheers,
John M. Boyer, Ph.D.
Senior Technical Staff Member
Lotus Forms Architect and Researcher
Chair, W3C Forms Working Group
Workplace, Portal and Collaboration Software
IBM Victoria Software Lab
E-Mail: boyerj@ca.ibm.com 

Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer
Blog RSS feed: 
http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw

Received on Thursday, 27 March 2008 23:52:21 UTC