Hello

A simple answer (...but complex on the long run)
---------------

1. PRE-PROCESSING

  // first row
  model.terrains[0].id        = my_first_id;
  model.terrains[0].terr_name = my_first_terr_name;
  model.terrains[0].terr_size = my_first_terr_size;
  model.terrains[0].select    = my_first_select;

  // second row
  model.terrains[1].id        = my_second_id;
  model.terrains[1].terr_name = my_second_terr_name;
  model.terrains[1].terr_size = my_second_terr_size;
  model.terrains[1].select    = my_second_select;

...you get the idea!


2. POST-PROCESSING

  // get the repeater widget
  var terrains = form.lookupWidget ("terrains");

  // loop through all the rows
  for (var i = 0; i < terrains.getSize(); i++) {
    my_ids[i]        = terrains.getWidget (i, "id");
    my_terr_names[i] = terrains.getWidget (i, "terr_name");
    my_terr_sizes[i] = terrains.getWidget (i, "terr_size");
    my_selects[i]    = terrains.getWidget (i, "select");
  }

...again, you get the idea!

A major drawback of this 'simple' approach is that you have to write your
own code if you wish to distinguish between rows which have been added,
modified or deleted (ie. by comparing the ids...)
This is an issue if for example you wish to persist your values in a
database!


A more complex answer (but simpler in the long run ;-)
---------------------

The above approach is impractical if you have a large number of repeaters,
and very especially if you have nested repeaters, as you will have to
hand-code a lot of stuff!


A better approach would be to use the CForms Binding Framework:

Assuming you would write a bean - let's name it 'Location' - with a
'title' attribute and a 'terrains' attribute.
The former is supposed to map to the 'title' field in your form.
The latter is supposed to be a collection of 'Terrain' beans, whose
attributes in turn map to the fields in your repeater.

All you would have to do then is write a binding file, which maps your
form fields to your bean attributes, and your PRE/POST-processing code
could then be reduced to the following:

  // create a new 'Location' object with an empty terrain
  var my_location = new Location();
  my_location.add (new Terrain());

  // pass the 'Location' object to the form, and display it
  form.load (my_location);
  form.showForm (...);

  // apply the changes made in the form to the 'my_location' object
  form.save (my_location);

If you got your binding right, then the 'my_location.terrains' collection
will be automatically populated with 'Terrain' objects - one for each
repeater row in the form.


If additionally, you are using an object-relational mapping tool like
Hibernate for instance, and you took care for mapping the terrains
collection there as well, then you could persist the my_location object,
including all its terrains, to the database using a single call:

  my_hibernate_session.saveOrUpdate(my_location);

No fuss with database inserts, updates or deletes ...just let Hibernate
handle that for you! (CForms repeaters map nicely to Hibernate
Collections!)

Of course the learning curve with a CForms Binding Framework/Hibernate
solution is pretty steep, but IMHO it is worth the trouble if you are
facing a complex project!


Hope it helps,
Fabrizio



> I need to be able to do some pre- and post- processing of values
> that will be contained in repeater rows in a CForm.
>
> The form defn will look something like:
>
> <fd:widgets>
>
>   <fd:field id="title" required="true">
>      <fd:label>Title</fd:label>
>     <fd:datatype base="string"/>
>   </fd:field>
>
>   <fd:repeater id="terrains">
>     <fd:widgets>
>       <fd:output id="id">
>         <fd:datatype base="integer"/>
>       </fd:output>
>       <fd:field id="terr_name">
>         <fd:datatype base="string"/>
>         <fd:label>Name</fd:label>
>       </fd:field>
>       <fd:field id="terr_size">
>         <fd:datatype base="integer"/>
>         <fd:label>Name</fd:label>
>       </fd:field>
>       <fd:booleanfield id="select">
>         <fd:label>Select</fd:label>
>       </fd:booleanfield>
>     </fd:widgets>
>   </fd:repeater>
>
>   <fd:repeater-action id="addterrain" action-command="add-row"
> repeater="terrains">
>     <fd:label>Add terrain</fd:label>
>   </fd:repeater-action>
>
>   <fd:repeater-action id="removeterrain" action-command="delete-rows"
> repeater="terrains" select="select">
>     <fd:label>Remove selected terrain</fd:label>
>   </fd:repeater-action>
>
> </fd:widgets>
>
> The form will be created as usual:
>
>   var editDataForm = new Form("view/forms/editForm_d.xml");
>   var model = editDataForm.getModel();
>
>
> 1. PRE-PROCESSING
>
> I then need to assign data to the various elements.
> For the single value field it is simple:
>
>   //assign data to the form/model
>   model.title = "Dummy";
>
> But - how to create the repeater rows and assign a set of values
> to them?
>
>
> 2. POST-PROCESSING
>
> When post-processing, I again need to process the repeater
> rows - bearing in mind the user could have added or deleted
> some/all of the rows...
>
> The value from the single value field is contained in the
>
>   model.title
>
> variable; but, again - how to know how many repeater values
> exist, and what their values are?
>
> I am sure this is not complex, but I have not been able to find
> any examples on the Cocoon site or in past messages.
>
> Thanks
> Derek


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]