Hi all,
what about calculated fields? In a cocoon form I have a repeater, in the repeater there are some numeric fields, and i need to show the sum of values in these fields at the bottom of the page. This can be done with fd:value-changed and some javascript or custom classes, but actually since they are mentioned on Jira in the roadmap ( http://issues.apache.org/jira/browse/COCOON-941 ), I need them, and they are a good idea, I was wandering how to implement them.

I tried prototyping something, and basically arrived to this :

.. inside the repeater ..

<fd:field id="items" required="true">
 <fd:label>Items</fd:label>
 <fd:datatype base="integer"/>
</fd:field>
<fd:field id="price" required="true">
 <fd:label>Price</fd:label>
 <fd:datatype base="double"/>
</fd:field>

<fd:calculatedfield id="subtotal" required="true" state="output">
 <fd:label>Sub total</fd:label>
 <fd:datatype base="double">
    <fd:convertor type="formatting" variant="currency"/>
 </fd:datatype>
 <fd:algorithm type="arithmetic" operation="multiplicate">
   <fd:triggers>items,price</fd:triggers>
 </fd:algorithm>
</fd:calculatedfield>

.... outside the repeater ...

<fd:calculatedfield id="totalitems" state="output" required="true">
 <fd:label>Total items</fd:label>
 <fd:datatype base="integer"/>
 <fd:algorithm type="arithmetic" operation="sum">
   <fd:triggers>/articles/*/items</fd:triggers>
 </fd:algorithm>
</fd:calculatedfield>

<fd:calculatedfield id="totalitemscost" state="output" required="true">
 <fd:label>Total cost</fd:label>
 <fd:datatype base="double">
   <fd:convertor type="formatting" variant="currency"/>
 </fd:datatype>
 <fd:algorithm type="arithmetic" operation="sum">
   <fd:triggers>/articles/*/subtotal</fd:triggers>
 </fd:algorithm>
</fd:calculatedfield>
CalculatedField is a subclass of Field, that gets an Algortihm. The Algorithm is a simple interface, responsible for calculating the value and return a list of triggers. Triggers are widgets that will trigger the re-calculation.

Calculated fields add value change listeners on all triggers to know when a recalculation is needed, and also to make it update gracefully in ajax. Using triggers you don't have to disseminate the form with value changed listeners to trigger recalculations, and also for simple algorithms (like the arithmetic one I implemented) triggers are the operands on which it operates. This IMMO minimizes mistakes.

My calculated field prototype calls algorithm.calculate() in readFromRequest(). Is there a better place? I'm also trying to make them editable (if editable="true" specified in the definition), so that if the user wants to "fine tune" the result of a calculation he can modify the calculated value. Obviously, once the calculated field has been modified by the user it will behave like a common field, maybe until the user erases the value bringing the field back to it's calculated nature?

I tried something to make them also client side, but I don't think it's a good idea. With such a good AJAX support, client side support is rarely useful. Also, it poses a lot of limitations and a lot more work on it : all algorithms should be able to generate a client side counterpart, triggers should be rendered as client side calls to "calculateXXX" functions. There is no tidy way to do this, and some algorithms would be very difficult to port client side. Also, on client side there is no way of apply proper field formatting, so every form using calculated fields with a format different from plain will end up being a mess.

WDYT?

Simone

--
Simone Gianni