Mark Lundquist wrote:
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".
Yeah, right :-)
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
<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.
+1
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.
Not sure this is a validation error. In the case of actions this should
be more a transient message (e.g. a popup). That isn't persisted across
successive posts of a form. Now we may consider that actions have a
special way of handling validation errors by clearing them at each
readFromRequest() which is different from other widget types.
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?
The idea is to specify in the binding if it should operate on the full
repeater or only on the selected rows. Something like:
<fb:repeater use-selection="true">
....
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.
You're right. The "form.model" is actually the value tree.
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! :-).
Yes. That's the idea behind the "bound repeater binding" idea Reinhard
pointed to.
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 :-)
Extending the repeater binding to keep the connection to the data model
may be easier, no?
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)/
/
:-)
Sylvain
--
Sylvain Wallez Anyware Technologies
http://apache.org/~sylvain http://anyware-tech.com
Apache Software Foundation Member Research & Technology Director