cocoon-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Derek Hohls" <dho...@csir.co.za>
Subject Re: Processing of repeater row values in flowscript
Date Wed, 14 Dec 2005 14:23:43 GMT
Fabrizio
 
Thanks for the long and detailed reply - much appreciated!
 
Quick response _ I have to take the simple approach now .. I have 
looked at Hibernate before and the leaning curve is too complex
to manage for this project (never mind I have to learn JavaBeans
as well!).  Perhaps next year, in another project.
 
Two questions:
 
1.  Do I have to somehow instantiate the model.terrains[] array;
or can I just start up a loop and create elements on the fly?
 
2.   You also say:
 
"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...)"
 
I do need to persist the changes back to the database, so I was wondering
how this code would work?  Must I store all the IDs in a separate array
before they go to the form, and then compare with the new values coming 
back??  And how does the form "generate" new IDs if, for example, the user
is adding back to a table with auto-increment rows?

It would nice to create some generic code for this - who knows, it could
be useful for someone?

 
Cheers
Derek


>>> fabrizio.sitzia@chem.lu 2005/12/14 04:07 PM >>>
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: users-unsubscribe@cocoon.apache.org 
For additional commands, e-mail: users-help@cocoon.apache.org 



-- 
This message is subject to the CSIR's copyright, terms and conditions and
e-mail legal notice. Views expressed herein do not necessarily represent the
views of the CSIR.
 
CSIR E-mail Legal Notice
http://mail.csir.co.za/CSIR_eMail_Legal_Notice.html 
 
CSIR Copyright, Terms and Conditions
http://mail.csir.co.za/CSIR_Copyright.html 
 
For electronic copies of the CSIR Copyright, Terms and Conditions and the CSIR
Legal Notice send a blank message with REQUEST LEGAL in the subject line to
HelpDesk@csir.co.za.


This message has been scanned for viruses and dangerous content by MailScanner, 
and is believed to be clean.  MailScanner thanks Transtec Computers for their support.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Mime
View raw message