cocoon-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Fabrizio Sitzia" <fabrizio.sit...@chem.lu>
Subject Re: Processing of repeater row values in flowscript
Date Wed, 14 Dec 2005 16:02:08 GMT
Hello Derek,

Answers to your questions:

1. There's no need to instantiate the model.terrains[] array. An
assignment like  model.terrains[0].id = xxx  will automagically create
your first repeater row.

2. > ...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??

Yep, That's what I initially did: Comparing the IDs that came back with
the original IDs (ugly!!!), then deciding what database action (update,
delete...) to perform!

It's no fun when you start nesting repeaters. The code gets very messy!
That's why I decided to switch to Hibernate :->


> And how does the form "generate" new IDs if, for example, the user
> is adding back to a table with auto-increment rows?

As far as I know the form won't generate new IDs for you. Only thing you
can do is test for a returned null ID, meaning that the row has been
added.
In that case you perform your database insert operation. (...whether you
have to perform a sequence.nextval beforehand, or whether your ID gets
generated via an auto-increment mechanism depends on the database flavour
you're using)

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

That generic code already exists - you just have to pick one: Hibernate,
Castor, JDO... ;-)


Cheers,
Fabrizio



> 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


Mime
View raw message