On Jun 20, 2005, at 11:42 PM, Sylvain Wallez wrote:
So in essence, you want to act on the selected rows, right?
Yup.
I encountered this already, and I've been thinking to explicitely add the selection concept to repeaters. That selection would be defined by a boolean field present on each row.
Great idea. That is orthogonal to what I've done... you are saying "selection is an intrinsic aspect of rows", and I'm saying "I need a handle on the data".
Note that a boolean field doesn't necessarily means rendering as a checkbox. It can also be some highlighting of selected rows.
Yup.
That would lead to+1
<fd:repeater name="repeater" selection="select">
<fd:widgets>
<fd:field id="name"/>
<fd:booleanfield id="select"/>
</fd:widgets>
</fd:repeater>
Repeater actions such as "delete-rows" would then no more have a need to be given the select widget's name as of today.
And even more, repeater actions could have constraints on the selection size, such as single-selection, multiple-selection, leading these actions to be disabled if their associated constraint isn't met....or a validation error. Like the classic "you must choose at least one" constraint.
And finally, we may be able to specify on repeater bindings if they have to act on the whole repeater on just on the selection.Not sure what you mean, can you give an example?
However...
I realized that I have a nomenclature clash with my choice of the name "model". I've been using the v2 API for a long time, so I forgot in v1, there is a Form.model property that denotes the widget value tree.
The "model" property is only available on the toplevel form JS object, so there may not be a clash.
It's not a hard "name clash", but it is a nomenclature clash in that it's a different sense of the term "model". My new row "model" property is truly the "model", as in "MVC" or as in "loadFormFromModel()". The v1 "model" is "model" in terms of "formmodel", I guess. I just think it's too confusing to have both senses. I actually sort of wish the v1 "model" were called something else, because it isn't the model a la MVC.
BTW, why do you prefer v2 rather than v1?
So I don't want to cause confusion with another sense of "model"... it should be called something else. "rowData"? "rowObject"? WDYT?
It doesn't seem good to me to provide at the API level a way to link the form to the data model,
No, no, it is good... :-)
as this is something that isn't suitable for all situations (think transactional systems, heavyweight objects, etc).
OK, for what percentage of real-life applications would you say it is unsuitable? If it's 10-20%, then do we want to penalize the other 80-90%? I don't deny those situations exist, but I think they are less common, and in those cases my instinct would be to use a DTO at some level instead of binding directly to the model object. My instinct would not be to say, "ah, now here is why we don't provide a handle from repeater rows to their bound data!" :-) One thing I've found to work really well is to build an ad hoc DTO right in the flowscript as a javascript object, which looks to the binding framework just like a Java bean.
Another way to say it: adding this repeater row decoration doesn't break any isolation between layers of the application. It breaks an undesirable isolation within a single layer (the form definition, binding and flowscript all live in the UI layer). The degree of isolation between the UI layer and the model, in turn, depends on what is given to the UI layer. If that is a live model object, then the isolation is already broken, and that may or may not be a bad thing, but that concern doesn't belong to the internal architecture of CForms (IMHO... just trying to state a case here :-).
This is making me think of a discussion in "Hibernate in Action"... In the chapter "Writing Layered Applications", there's a section entitled "Rethinking DTOs". The authors make the case that the dogma "you should never have live model objects in the view layer" is extreme (maybe it is "quaint and outmoded", like someone in the butthead government of my country has said about the Geneva convention :-/). Anyway... it's not quite what we're talking about here, but it's related.
And one of the big strengths of CForms is its strong isolation with the data model while the user is messing around with input values.
Hmm, well you can't modify the data from JXTemplate, or at least the mechanisms are not well-known ;-/ (and maybe JXT is too strong :-)... in any case, I think most people really are interested in using JXT as just a template engine, not in programming in JXT :-). That leaves the flowscript, and you can already have your way with the model data from flowscript if the live data is what the services layer provides...
However, there are some uses cases where this makes sense. You can then use widget attributes (see get/setAttribute) to attach some application data of your liking to any widget, including repeater rows.
See, that's the problem, this is what I have to deal with currently :-)... I have two parallel structures: a Collection, and a Repeater. If the Repeater does not give me a "view" to its collection, then I have to do some kind of iteration to create associations somewhere between the repeater rows and the collection elements, and this just feels silly and wasteful. I've done it this way, decorating the repeater rows with handles to the model data, and I just think that since the binding layer is already iterating across the collection, it should do this decoration for me! :-).
I could live with there being a "callback" facility in the repeater binding language, e.g. <fb:javascript> within <fb:on-bind>... know what I mean? But that's sort of beyond my ability to implement, and I was looking for something that I could actually do :-)
As Reinhard pointed out, you've already proposed my patch:
"Another option to ease repeater binding could be to attach the loaded
data as attributes in the widget row, thus giving instant access to that
data at save time."
(http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=109950611823830&w=2)
I've gotta do a better job of keeping up on the dev list... :-)
—ml—
