You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Sylvain Wallez <sy...@apache.org> on 2003/12/30 00:00:28 UTC

Re: Broke car selector sample [Fwd: cvs commit: cocoon-2.1/src/blocks/woody/samples/forms car-db.xml]

Marc Portier wrote:

>
>
> Sylvain Wallez wrote:
>
>> Vadim Gritsenko wrote:
>>
>>> Hi all,
>>>
>>> I broke car selector sample :-)
>>>
>>> Problem is that when you assign / bind initial values to the form, 
>>> <on-value-change/> events are not fired, and form ends up in the 
>>> inconsistent state. Quick hack I used to fix this was to make 
>>> Form.fireWidgetEvents method public and call it directly from the 
>>> flow/action to make sure that all is ok; but this is clearly a hack 
>>> and I'd like to hear "expert opinion" on the subject.
>>
>>
>> The solution is to tie the loading phase to the global form 
>> processing. I started this by adding load() and save() to the Form 
>> class, but left them commented out waiting for some more thoughts in 
>> this area, since the binding is strongly separated from the Form object.
>>
>> Now your use case clearly shows that making the binding an integral 
>> part of the form processing is useful.
>>
>> So let's officially introduce Form.load() and Form.save() and make 
>> them the preferred way to use the binding framework.
>>
>
> Sylvain, care to explain a bit more?
>
> I do remember a more conceptual agreement on binding being a natural 
> part of the form's being (although the original late arrival of 
> binding in woody kept it modestly separate) and I thought we said back 
> then that save and load on a form were logical extensions...
>
> So I'm quite +1, I'm just not fully aware of what it is about yet...


It's just about that: integrate load an save as integral parts of the 
form processing lifecycle.

The processing phases are then the following:
1 - initialization
2 - load
3 - read from request
4 - validate
5 - save

Phase 1 can be useful if some widgets have an initial value and some 
others have dependent values. This allows event listeners to be 
triggered in the initial phase.

Phase 2 is optional and should normally occur only once.

Phase 3 can occur several times (the form can be redisplayed many times)

Phase 4 can occur several times also, but not necessarily after each 
phase 3 (e.g. repeater actions don't validate the form)

Phase 5 is optional and should normally occur only once can only happen 
if phase 4 is successful

Maybe we also need a phase 6 for destruction ?

How does all this sound?

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Orixo, the opensource XML business alliance  -  http://www.orixo.com



Re: Broke car selector sample [Fwd: cvs commit: cocoon-2.1/src/blocks/woody/samples/forms car-db.xml]

Posted by Antonio Gallardo <ag...@agsoftware.dnsalias.com>.
Marc Portier dijo:
>
>
> Sylvain Wallez wrote:
>
>> Marc Portier wrote:
>>
>>> Sylvain Wallez wrote:
>>>
>>>> Vadim Gritsenko wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> I broke car selector sample :-)
>>>>>
>>>>> Problem is that when you assign / bind initial values to the form,
>>>>> <on-value-change/> events are not fired, and form ends up in the
>>>>> inconsistent state. Quick hack I used to fix this was to make
>>>>> Form.fireWidgetEvents method public and call it directly from the
>>>>> flow/action to make sure that all is ok; but this is clearly a hack
>>>>> and I'd like to hear "expert opinion" on the subject.
>>>>
>>>>
>>>>
>>>> The solution is to tie the loading phase to the global form
>>>> processing. I started this by adding load() and save() to the Form
>>>> class, but left them commented out waiting for some more thoughts in
>>>> this area, since the binding is strongly separated from the Form
>>>> object.
>>>>
>>>> Now your use case clearly shows that making the binding an integral
>>>> part of the form processing is useful.
>>>>
>>>> So let's officially introduce Form.load() and Form.save() and make
>>>> them the preferred way to use the binding framework.
>>>>
>>>
>>> Sylvain, care to explain a bit more?
>>>
>>> I do remember a more conceptual agreement on binding being a natural
>>> part of the form's being (although the original late arrival of
>>> binding in woody kept it modestly separate) and I thought we said back
>>> then that save and load on a form were logical extensions...
>>>
>>> So I'm quite +1, I'm just not fully aware of what it is about yet...
>>
>>
>>
>> It's just about that: integrate load an save as integral parts of the
>> form processing lifecycle.
>
> still don't get the term 'integrate' in his technical meaning?
>
> is the following list to be seen as:
> 1/ subsequent calls in form.showForm()
> 2/ or even inside Form.processRequest()
> 3/ or are they just typical
> 4/ (or required?) order of methods called from end-user code or script?

All the 4 apply. The idea of the CForm (instance) lifecycle is similar as
avalon components lifecycle:

http://avalon.apache.org/framework/principals/lifecycle.html

>> The processing phases are then the following:
>> 1 - initialization
>> 2 - load
>> 3 - read from request
>> 4 - validate
>> 5 - save
>>
>> Phase 1 can be useful if some widgets have an initial value and some
>> others have dependent values. This allows event listeners to be
>> triggered in the initial phase.
>>
>> Phase 2 is optional and should normally occur only once.
>
> hm, there is now (maybe too much?) the flexibility that I can use
> multiple bindings to bind the same form to/from maybe multiple
> backend-model-objects (just to name a use case we would be killing)

Why? I think we can "check" if there is a binding for this form. The idea
behind all the thread is because the binding must be part of the overall
form management. If CForms are related to form handling the binding must
the the interface between other components and the CForms itself.

>
> afaiu the original statement in this thread is about missing events
> after a binding has loaded it's data?

Yep. The problem is this right now. Also as I pointed before, there is a
need to set some defaults values and a need to make some chanes just after
load data (using binding) and before the form is displayed.

As an example, see the car selection demo. The demo works fine when we
need to create a new entry, but currently there is a problem if we have
already loaded data and call the car form. The already loaded data will
not be displayed correctly.

Also, I see a better idea to create a similar handler as the one we used
to manage custom validations:

form.validator = theCustomValidatorFunction;

function theCustomValidatorFunction() {
   return true;
}

That way we can easily manage the after load stuff.

WDYT?


> also: even with binding in place there will be a need IMHO to have
> access to widgets itself and thus we are able to just setValue on those
> (regardless of any binding, or initialization 'phaze' timing! This is
> there and can thus happen any time, no? Event-handling should be
> triggered then too?)

AFAIK in other forms frameworks the changes made by code (internal
changes) don't emit new events. Only users changes emit new events. I
think this is correct since we are making internal changes then why we
need to know again we are making changes.

If we will emit new events, then there is (theoretical) posible to write a
endless loop just changing other widgets values that inevitable will emit
another event.

Also emiting new events by code changes just create more overhead, since
programmer already know what he is doing.

>> Phase 3 can occur several times (the form can be redisplayed many times)
>>
>
> yes, but I really see Phase 1,2,3 as alternatives for the same thing:
> setting values on widgets which possibly can lead to events fired?

I see the need to fill default values + a need to make some last changes
just before displaying the form. This to actions need to be done in
diferent time. The default values can be load in the initialization phase
(1) then just before displaying the form we need another chance to make
changes. This is a normal approach.

>> Phase 4 can occur several times also, but not necessarily after each
>> phase 3 (e.g. repeater actions don't validate the form)
>>
>> Phase 5 is optional and should normally occur only once can only happen
>> if phase 4 is successful
>>
>> Maybe we also need a phase 6 for destruction ?
>>
> for cleanup of temp resources assigned to the form probably?
> (memories of the upload-widget stuff?)

??? I don't see it as a good idea. We cannot take as a fact that the user
will interact with the form always. There can be cases where the user can
show the for and close the browser forever. So in this case I prefer to
release the components just before show the form. This was discused
before.

>> How does all this sound?

> sorry to be so boneheaded, still trying to understand :-(

No hay problema ;-)

Best Regards,

Antonio Gallardo

Re: Broke car selector sample [Fwd: cvs commit: cocoon-2.1/src/blocks/woody/samples/forms car-db.xml]

Posted by Marc Portier <mp...@outerthought.org>.

Sylvain Wallez wrote:

> Marc Portier wrote:
> 
>> Sylvain Wallez wrote:
>>
>>> Vadim Gritsenko wrote:
>>>
>>>> Hi all,
>>>>
>>>> I broke car selector sample :-)
>>>>
>>>> Problem is that when you assign / bind initial values to the form, 
>>>> <on-value-change/> events are not fired, and form ends up in the 
>>>> inconsistent state. Quick hack I used to fix this was to make 
>>>> Form.fireWidgetEvents method public and call it directly from the 
>>>> flow/action to make sure that all is ok; but this is clearly a hack 
>>>> and I'd like to hear "expert opinion" on the subject.
>>>
>>>
>>>
>>> The solution is to tie the loading phase to the global form 
>>> processing. I started this by adding load() and save() to the Form 
>>> class, but left them commented out waiting for some more thoughts in 
>>> this area, since the binding is strongly separated from the Form object.
>>>
>>> Now your use case clearly shows that making the binding an integral 
>>> part of the form processing is useful.
>>>
>>> So let's officially introduce Form.load() and Form.save() and make 
>>> them the preferred way to use the binding framework.
>>>
>>
>> Sylvain, care to explain a bit more?
>>
>> I do remember a more conceptual agreement on binding being a natural 
>> part of the form's being (although the original late arrival of 
>> binding in woody kept it modestly separate) and I thought we said back 
>> then that save and load on a form were logical extensions...
>>
>> So I'm quite +1, I'm just not fully aware of what it is about yet...
> 
> 
> 
> It's just about that: integrate load an save as integral parts of the 
> form processing lifecycle.

still don't get the term 'integrate' in his technical meaning?

is the following list to be seen as:
1/ subsequent calls in form.showForm()
2/ or even inside Form.processRequest()
3/ or are they just typical
4/ (or required?) order of methods called from end-user code or script?

> 
> The processing phases are then the following:
> 1 - initialization
> 2 - load
> 3 - read from request
> 4 - validate
> 5 - save
> 
> Phase 1 can be useful if some widgets have an initial value and some 
> others have dependent values. This allows event listeners to be 
> triggered in the initial phase.
> 
> Phase 2 is optional and should normally occur only once.
> 

hm, there is now (maybe too much?) the flexibility that I can use 
multiple bindings to bind the same form to/from maybe multiple 
backend-model-objects (just to name a use case we would be killing)

afaiu the original statement in this thread is about missing events 
after a binding has loaded it's data?

also: even with binding in place there will be a need IMHO to have 
access to widgets itself and thus we are able to just setValue on those 
(regardless of any binding, or initialization 'phaze' timing! This is 
there and can thus happen any time, no? Event-handling should be 
triggered then too?)


> Phase 3 can occur several times (the form can be redisplayed many times)
> 

yes, but I really see Phase 1,2,3 as alternatives for the same thing: 
setting values on widgets which possibly can lead to events fired?

> Phase 4 can occur several times also, but not necessarily after each 
> phase 3 (e.g. repeater actions don't validate the form)
> 
> Phase 5 is optional and should normally occur only once can only happen 
> if phase 4 is successful
> 
> Maybe we also need a phase 6 for destruction ?
> 

for cleanup of temp resources assigned to the form probably?
(memories of the upload-widget stuff?)

> How does all this sound?
> 

sorry to be so boneheaded, still trying to understand :-(

> Sylvain
> 

-marc=
-- 
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at                http://blogs.cocoondev.org/mpo/
mpo@outerthought.org                              mpo@apache.org


Re: [CForms] Form lifecycle and events

Posted by Antonio Gallardo <ag...@agsoftware.dnsalias.com>.
Marc Portier dijo:
>
>
> Antonio Gallardo wrote:
>
> <snip />
>
>>
>>>Maybe we also need a phase 6 for destruction ?
>>
>>
>> I think it is not necesary at all. If someone need processing at this
>> time. We can easily manage any situation just before saving or after
>> destruction. Something between them is not necesary.
>>
>
> again (see other post), save() in my view can be called multiple times
> to save one form back to multiple back-end-objects, you would have a
> hard time knowing if this was the last save() without the additional
> destruction phase, no?

Nope. Because it is an instance issue. Every form will have his own space.
This is similar as the form.validator handler for validation. No matter
how many instances of the same form are currently running, the caller send
the form we need to validate. The same will apply here (even in the save
case).

>
>>
>>>How does all this sound?
>>
>>
>> Overall sounds great. The phase 1 can be used for default values and the
>> load() can rewrote the default values without checking.
>>
>> I think we can also add a new tag <wd:default/> for <widgets/>.
>>
>> I think we also need an event handler "after load" (after phase 3).
>> Sometimes we need to fix some values based on what we got from the DB.
>> As
>> an example we can present a synchronized set of comboboxes where the
>> value
>> selected on the 2nd combo dependens on value of the first. The 1st combo
>> act just as filter for the 2nd combo.
>>
>
> I don't see it yet: I would assume that the same logic applies for
> on-change?

No always. Please review the car-selection sample. Also I see a "name"
problem if we are calling the on-change event at the startup. The is not a
true on-change event since the user not changed nothing. This is a on-load
event for the widget. Isn't it?

>> BTW, I don't like the term "on-change" because it is not clear when it
>> happens: after or before change. I will prefer names like:
>>
>> <after-change>, <after-load> etc.
>
> but this suggests that there is a before-change maybe?

I think this would be another step. Sometimes the before change is needed.
Also in fat clients there are more events for every widget:

on-create, on-initializate, on-getfocus, on-lost-focus, on-destroy, etc

This event give more freedom to developers. Of course I am aware of the
problem in an HTML environment.

> to me on-change sounds quite ok, there could not be a detection of
> change if somebody didn't change a field and submit it, right?
>
> only subtle extra meaning is maybe that on-change sounds like there is a
> way to veto the change?
> (maybe on-changed offers the compromise?)

OK.

> also, I still don't see a reason for different <after-load> (probably
> due to me not understanding your above example)

I have a problem trying to fill an edit form with 2 combos from a table
that has 2 fields as Primary keys. One of these keys is a Foreign key form
another table.

Maybe you are right that we can already use the on-change event to do
this, but the actual documentation have some gaps. :-(

> in any case, if the use case is there I'ld like to suggest this
> alternative.  IMHO in most cases the same logic needs to be triggered
> when values change, regardless of their life-cycle phase... so if there
> is phase-specific logic to execute then it maybe makes more sense to
> allow the event itself to carry that information: getLifeCyclePhase()
> (rather then having different events?)

Nope. I prefer to see widgets with his own lifecycle.

I think there is a mix of concepts because the <wd:form> and the
<wd:repeater> are widget when in fact they are widget containers. And this
is another level.

> PS: don't let above sound like defensive, I'm wide open to changing and
> fixing this.

I know. We need to discuss this more before making the final decision. It
is OK to me. I am glad to be part of this. :-D

Best Regards,

Antonio Gallardo

Re: [CForms] Form lifecycle and events

Posted by Marc Portier <mp...@outerthought.org>.

Antonio Gallardo wrote:

<snip />

> 
>>Maybe we also need a phase 6 for destruction ?
> 
> 
> I think it is not necesary at all. If someone need processing at this
> time. We can easily manage any situation just before saving or after
> destruction. Something between them is not necesary.
> 

again (see other post), save() in my view can be called multiple times 
to save one form back to multiple back-end-objects, you would have a 
hard time knowing if this was the last save() without the additional 
destruction phase, no?

> 
>>How does all this sound?
> 
> 
> Overall sounds great. The phase 1 can be used for default values and the
> load() can rewrote the default values without checking.
> 
> I think we can also add a new tag <wd:default/> for <widgets/>.
> 
> I think we also need an event handler "after load" (after phase 3).
> Sometimes we need to fix some values based on what we got from the DB. As
> an example we can present a synchronized set of comboboxes where the value
> selected on the 2nd combo dependens on value of the first. The 1st combo
> act just as filter for the 2nd combo.
> 

I don't see it yet: I would assume that the same logic applies for 
on-change?

> BTW, I don't like the term "on-change" because it is not clear when it
> happens: after or before change. I will prefer names like:
> 
> <after-change>, <after-load> etc.
> 

but this suggests that there is a before-change maybe?

to me on-change sounds quite ok, there could not be a detection of 
change if somebody didn't change a field and submit it, right?

only subtle extra meaning is maybe that on-change sounds like there is a 
way to veto the change?
(maybe on-changed offers the compromise?)


also, I still don't see a reason for different <after-load> (probably 
due to me not understanding your above example)

in any case, if the use case is there I'ld like to suggest this 
alternative.  IMHO in most cases the same logic needs to be triggered 
when values change, regardless of their life-cycle phase... so if there 
is phase-specific logic to execute then it maybe makes more sense to 
allow the event itself to carry that information: getLifeCyclePhase() 
(rather then having different events?)

<snip/>

regards,
-marc=
PS: don't let above sound like defensive, I'm wide open to changing and 
fixing this
-- 
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at                http://blogs.cocoondev.org/mpo/
mpo@outerthought.org                              mpo@apache.org


[CForms] Form lifecycle and events (was: Re: Broke car selector sample)

Posted by Antonio Gallardo <ag...@agsoftware.dnsalias.com>.
Sylvain Wallez dijo:
> Marc Portier wrote:
>
>>
>>
>> Sylvain Wallez wrote:
>>
>>> Vadim Gritsenko wrote:
>>>
>>>> Hi all,
>>>>
>>>> I broke car selector sample :-)
>>>>
>>>> Problem is that when you assign / bind initial values to the form,
>>>> <on-value-change/> events are not fired, and form ends up in the
>>>> inconsistent state. Quick hack I used to fix this was to make
>>>> Form.fireWidgetEvents method public and call it directly from the
>>>> flow/action to make sure that all is ok; but this is clearly a hack
>>>> and I'd like to hear "expert opinion" on the subject.
>>>
>>>
>>> The solution is to tie the loading phase to the global form
>>> processing. I started this by adding load() and save() to the Form
>>> class, but left them commented out waiting for some more thoughts in
>>> this area, since the binding is strongly separated from the Form
>>> object.
>>>
>>> Now your use case clearly shows that making the binding an integral
>>> part of the form processing is useful.
>>>
>>> So let's officially introduce Form.load() and Form.save() and make
>>> them the preferred way to use the binding framework.
>>>
>>
>> Sylvain, care to explain a bit more?
>>
>> I do remember a more conceptual agreement on binding being a natural
>> part of the form's being (although the original late arrival of
>> binding in woody kept it modestly separate) and I thought we said back
>> then that save and load on a form were logical extensions...
>>
>> So I'm quite +1, I'm just not fully aware of what it is about yet...
>
>
> It's just about that: integrate load an save as integral parts of the
> form processing lifecycle.
>
> The processing phases are then the following:
> 1 - initialization
> 2 - load
> 3 - read from request
> 4 - validate
> 5 - save
>
> Phase 1 can be useful if some widgets have an initial value and some
> others have dependent values. This allows event listeners to be
> triggered in the initial phase.
>
> Phase 2 is optional and should normally occur only once.
>
> Phase 3 can occur several times (the form can be redisplayed many times)
>
> Phase 4 can occur several times also, but not necessarily after each
> phase 3 (e.g. repeater actions don't validate the form)
>
> Phase 5 is optional and should normally occur only once can only happen
> if phase 4 is successful

I was waiting for this thread! :-DDD

> Maybe we also need a phase 6 for destruction ?

I think it is not necesary at all. If someone need processing at this
time. We can easily manage any situation just before saving or after
destruction. Something between them is not necesary.

> How does all this sound?

Overall sounds great. The phase 1 can be used for default values and the
load() can rewrote the default values without checking.

I think we can also add a new tag <wd:default/> for <widgets/>.

I think we also need an event handler "after load" (after phase 3).
Sometimes we need to fix some values based on what we got from the DB. As
an example we can present a synchronized set of comboboxes where the value
selected on the 2nd combo dependens on value of the first. The 1st combo
act just as filter for the 2nd combo.

BTW, I don't like the term "on-change" because it is not clear when it
happens: after or before change. I will prefer names like:

<after-change>, <after-load> etc.

... While writing I think we can add to the form this type of events. I
know I am already outdated in this topic and you are a step further here.
Anyway I need and will to read in wiki the CForms events before extending
in this area. :-DDD

Best Regards

Antonio Gallardo