cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Torsten Curdt <tcu...@dff.st>
Subject RE: HEADS UP - cocoon form handling (long!!)
Date Tue, 09 Apr 2002 17:36:38 GMT
> > HEADS UP - cocoon form handling
> > -------------------------------
> [...]
>
> Personally I would stay as close to XForms specification as possible (in all
> markup parts, including contraints and events), although several parts are
> not possible on the server side or would require too much client code
> (JavaScript XPath, etc.).

That's fine with me... but keep in mind we don't try a XForms
implementation here... I'm still not yet convinced it's will be working
that great on the server side. (it's not possible to write an XForms2HTML
stylesheet currently without XSLT extension functions!)

So we should limit ourselfs to that syntax where it is not so straight
forward or makes things too complicated...

we are in the XML world. For a later migration one can easily set up an
ant task for that!

> Reasons are:
> 	- it is a specification that addresses most of the possible cases
> 	- there is a hope that some day XForms would replace HTML forms and
> in that case it'll be possible to use Cocoon forms as-is without any
> additional transformation

Well, I'm sure this will not happen until Cocoon 3 ;-)
It has been really quite on the xforms list...

> 	- we need an agreement on terms and processing models and this can
> be achieved without reinventing the wheel

aggreed...

<snip/>

> > The view maps values from the instance to controls. Syntax reminds on
> > XForms:
> >
> >    <i:instance id="feedback-form">
> >      <i:textbox ref="user/firstname"/>
> >      <i:textbox ref="user/lastname"/>
> >      ...
> >    </i:instance>
>
> Why input fields are children of instance? And should we support multiple
> instances? Why not use pure XForms syntax? It will look like this:
>
>     <xforms:group ref="feedback-form">
>       <xforms:input ref="user/firstname"/>
>       <xforms:input ref="user/lastname"/>
>       ...
>     </xforms:group>
>
> (Field captions as well as other possible elements and attributes are
> omitted).

I am fine that, too... The XForms spec has changed quite a lot since the
last time I had look... IIRC it was something like to above before...
anyway. Children of the instance means use instance id=".." as reference.
We can use can use xforms syntax for that, too :)


> >                                -o-
> >                              Populating
> >
> > Taken from the ExFormular project we call this saving into
> > the instance
> > on a POST "populating". There are two different approaches when
> > populating. Direct and indirect. While the direct populating
> > method is
> > quite straight forward on the first glance: "go through the
> > request and
> > save the request parameters into the instance" it has some major
> > problems as of the POST behaviour of checkboxes: on "true"
> > there will be
> > a request parameter, on "false" there will be no request parameter at
> > all. So with direct population you cannot set checkboxes to
> > "false". The
> > other method is indirect population. With this approach you actually
> > *know* what parameters *should* come with the request. So a missing
> > checkbox parameter means "set this checkbox to false".
> > Although we could
> > use the direct population (with some workarounds) we aggreed on using
> > indirect populating as it is the cleaner approach in the long run. No
> > hidden field or something like that...
>
> That's good. And this will require to create an object model of the form to
> be able to iterate through its fields, according constraints, etc. This will
> also help in cases, when there are not 'relevant' (see XForms 'relevant'
> constraint) fields. This means, that not all the fields are necessary to be
> taken into account for the current request depending on values of some other
> fields (not sure that it's easy to implement, though).

what do mean by "object model of the form"? I actually don't want to have
always beans behind my forms. Is this what you are at?


> >
> >                                -o-
> >                              Phases
> >
> > A phase defines a set of nodes of an instance. Phases are usally used
> > in the validation and population process.
>
> Would we need this if we knew which fields are relevant for the current
> request?

for population:
since we have chosen indirect populating we need to know what to expect
from a specific POST.

for validation:
we could use it to know what is relevant...

> >                                -o-
> >                             Preceptor
> >
> > Our instance can be expressed in XML. Directly when it's a
> > DOM or mapped
> > via Castor when we have beans. This means we should be able to use the
> > commonly used validation methods to validate our instance (= data of a
> > form). We would usually  call them Schemas but since the term
> > collides with short form of the W3C XML Schema validation we
> > aggreed on
> > "preceptor" for a general validity description of an XML
> > document. Such
> > a desciption will be served via pipeline and then "compiled"
> > and saved
> > into the scope of the instance. The JARV project shares
> > almost the same
> > idea here. Unfortunately they do not have support for partial
> > validation
> > yet, too.
>
> I would keep Schema as it is also used in XForms to describe to model schema
> (which is not required to be W3C XML Schema). Preceptor is not obvious and
> is difficult to pronounce ;)

hm... don't know :-/

(do you really think it's difficult to pronounce?? Cannot be harder
than you lastname ;-)

> > There are two different parts of XML document validity:
> >   a) structure of the document
> >   b) content of nodes
>
> c) data dependency

oh... yes

> >                                -o-
> >                           Content Validation
> >
> > Let's focus on the content first. It's the most important
> > thing for form
> > validation. Each preceptor defines some kind of rules, restrictions,
> > assertations for the content of nodes of the instance. As
> > general term
> > we will call them "constraints". Probably the most important
> > constraints
> > from the grammar based world (schema,relaxng) are
> >
> >   *) regular expressions constraint
> >   *) enumeration or choice constraint
> >   *) minimum number value constraint
> >   *) maxmimum number value constraint
> >   *) minimum string length constraint
> >   *) maximum string length constraint
> >   *) ...
> >
> > While schematron only has a single but very powerful constraint that
> > combines all the above into the
> >
> >   *) XPath expression constraint (except for regex until XPath 2.0)
>
> We can use XForms markup for model schema description and use Schematron for
> validation. Although, I'm not sure for other implementations.

I need to have a look at that... but I'd still prefer my people to be able
to use XMLspy to define our forms and their validation. That's possible
nice for XSD and I bet they soon come up with relaxng support, too.

> >                                -o-
> >                           Structure Validation
> >
> > The structure validation takes care of the instance to conform to a
> > described xml structure. We have not yet aggreed if the
> > structure should
> > be fully described by the preceptor or a partial describtion may be
> > sufficient. This decision has a major impact on the building of the
> > instance and the implementation details.
>
> What about the validation against contraints? Say, 'required' fields? Maybe
> we can develop our own validator for XForms binding contraints?
>
> >
> >                                -o-
> >                           Building the Instance
> >
> > At the start of the flow an instance needs to be created to take the
> > values of the POSTs. If we want to support structure
> > validation we need
> > to make sure that already the empty instance conforms to the
> > preceptor.
> > As of this we need to create all the required nodes in this
> > instance then.
>
> How do we deteremine required nodes?

Well, the preceptor should know about it... it defines what is required
and what is optional.

> >
> >                        A SIMPLE FORM VALIDATION
> >
> > This is how we would like to see form validation in action:
> >
> >   1. Introspection happens at the start of flow. An empty
> > instance gets
> >      created and save into the desired scope. It can also get filled
> >      with some inital values.
>
> Agree.
>
> >
> >   2. The controller (an action or schecoon) will choose the
> > first view to
> >      present to the user.
>
> Also agree.
>
> >
> >   3. If the user now presses a (submit) button the values get
> > populated
> >      into the instance and then validated. If some
> > constraints failed we
> >      go back to the first view telling the user which constraint have
> >      failed otherwise present him the next view.
>
> Flow controller also should determine that the process is finished and
> perform some business logic calls with collected data, isn't it? After that
> some default (success page) should be displayed.

why finished?? can you elaborate a bit more, please?

> > Unfortunately this looks much easier at the first glance than
> > it is. We
> > will now try to talk about the problems we have encounter so far.
> > (and there possible sollutions ;)
> >
> > on 1)
> >    How do we specify an introspection for a flow?
> >
> >      This can easily be done either with schecoon or with the
> > multiaction
> >      that comes with precept. But the question is: Should
> > this be modeled
> >      in XML, in java or a scripting language?
>
> Form descriptor can be dynamic and have special tags for this, e.g.:
> <instance>
> 	<castor:insertBean .../>
> <instance>
> Then it will be used as source for IntrospectionAction:
>
> <map:act type="init">
> 	<map:parameter name="form-descriptor"
> value="cocoon:/get-form?form-id=102" />
> </map:act>
>
> Seems a little complicated...

Sorry, you've lost me...

> > on 2)
> >    How does the controller know which view is the first one and what
> >    views are actually available?
>
> For a good wizard it would be also needed to know what actions are available
> ('next', 'previous', 'done', etc.).

Well, I see this bound to a button in the view markup... or in a
descriptor...

> >      This could be set from the introspection. If not
> > specified the first
> >      view from a possible descriptor could be taken.
> >      See also "VIEWS AND PHASES".
>
> This depends on the flow engine. Should we focus on this now?

focus on what? on the flow engine?

> > on 3)
> >    How does the controller know what to populate and validate on a
> >    submit?
> >
> >      Inside the views or in a descriptor like it is in Struts
> > we should
> >      probably have a mapping of the phases to buttons.
> >      See "VIEWS AND PHASES".
>
> This can be addressed by using XForms 'relevant' contraint and some of the
> events. Say, treat a button as event, then go through the form description
> to find out which fields are affected with this event.

ok.. but how and where do you want to define relevance then?

> >    And how does he know about the current and the next view?
> >
> >      Same as above. This can happen in the controler or be specified
> >      in the view.
> >      See "VIEWS AND PHASES".
>
> This is also flow controller specific.
>
> >
> >    What if we don't want to populate and validate all
> > controls in a view?
> >
> >      We need to keep in mind to decouple the phases from the views
> >      See "VIEWS AND PHASES".
>
> See 'relevant' contraint in XForms.
>
> >
> >    How do we present the failed constraints to the user?
> >
> >       We can use the InstanceTransformer to insert a
> > list/tree of errors
> >       into the SAX stream somewhere in the view or output the failed
> >       constraints with the controls itself.
>
> Agree.
>
> >
> >    How can we only validate parts of an instance?
> >
> >       Unfortunately most current validation implementations don't
> >       support partial validation of documents yet. Schematron is
> >       one exception. Maybe some of the authors can assist here.
>
> Maybe we can validate the document in whole, but ignore irrelevant parts?

I have been thinking about this, too... This way we adopt validation
implementations more quickly... unfortunately validation itself will be
much slower...

> > Since much of the problems are phases / views related we took
> > a closer look.
> >
> >
> >                        VIEWS AND PHASES
> >
> >
> > First thing our discussion revealed was that views and phases are not
> > necessarily the same. They might be the same for the most
> > easy webforms
> > but as soon as it comes to more complex applications you need to
> > decouple them. They describe different things:
> >
> >   *) phases describe a set of instance nodes to be validated
> >   *) views describe a set of instance nodes to be displayed
> >
> > So as a result we found that buttons should be bound to phases.
> > Either within the view or within a descriptor:
> >
> > a) within the view
> > <view>
> >    <instance id="..">
> >      <textbox ref="user/firstname"/>
> >      <textbox ref="user/lastname"/>
> >      <button>
> >        <caption>Next</caption>
> >        <populate>phase2</populate>
> >        <validate>phase2</validate>
> >      </button>
> >    </instance>
> > </view>
>
> Hm... Absolutely not XForms synax. Are we going to invent our own markup?

Not really... but I fear we have to compromise... I'll have look into the
XForms draft again but IIRC I didn't like their approach on the buttons...

> >
> > b) within a descriptor
> >
> >     <no syntax yet/>
>
> Maybe XForms bindings can solve this one?

I have to have a look into the spec again...

>
> >
> > Currently only schematron comes with a native phases support. All the
> > others don't support partial validation yet. Although Torsten
> > is not so
> > sure if this should be really part of the preceptor.
> > (Torsten: as soon as you move a textbox from one view into
> > another one
> > you need alter your preceptor because the phases have
> > changed. For SoC
> > this should not be IMHO)
>
> I am agree with Ivelin on this one.

...so you think it should be part of the preceptor??

> > But the question still remains: how can we implement phases for
> > preceptor other than schematron? All we came up was some kind of
> > PhaseResolver than can takes the same schematron file as
> > input for the
> > SchemtronPhaseResolver and other descriptors (to be defined) for e.g.
> > the RelaxNGPhaseResolver.
>
> Seems to me a little artificial, it's not a good sign ;)

well, then we need come up with something better...


> >                        IMPLEMENTATION DETAILS
> >
> >  From the above we came up with some minimalistic interfaces:
> >
> > /**  the instance save and retrieves values based on an xpath
> >    */
> > interface Instance {
> >    public void setValue( String xpath, Object value, Context context);
> >    public Object getValue( String xpath );
> > }
>
> What about the
> addValue(...)
> removeValue(...)

whatfor?

> > /**  the preceptor validates nodes from a specific phase
> > looked up via
> > the phase resolver
> >    *
> >    */
> > interface Preceptor {
> >    public Collection validate( Instance i, PhaseResolver resolver,
> > String phase, Context context );
> >    /* or better typesafe?
> >    public Constraint[] validate( Instance i, PhaseResolver resolver,
> > String phase, Context context );
> >    */
>
> Why Constraint[] and not ContraintViolation[]? Shouldn't validate perform
> validation then return an error list?

Well, why create ConstraintViolation object. Returning the Constraint
itself is enough. We know that this Constraint failed... because it is
returned...

> > }
> >
> > /**  the constraint actually checks the the values of a node.
> >    *  it's usually a wrapper to existing "restrictions,rules,..."
> >    */
> > interface Constraint {
> >    public boolean isSatifiedBy( Object value, Context context );
> >    public String getId();
> > }
>
> Shoudn't it be used inside of validate to iterate through and get
> ConstraintViolation or ValidationError objects?

true... "validate" gets the constraints for the nodes it is checking
and "validate" returns failed constraints.

> > /**  the phase resolver returns the xpaths for for phase
> >    */
> > interface PhaseResolver {
> >    public String[] lookupNodesForPhase( String phase );
> > }
>
> IMO, 'getRelevantNodes()' sounds a little better.

whatever ;-) ...it needed a name...

> >                          COMMENTS
> >
> > from Torsten:
> > - I am in favor of "structure validation" of forms. So all I
> > define is
> > the preceptor (xsd or relaxng) and this even describes how
> > the instance
> > has to look like. And I am then sure my instance looks like
> > the preceptor.
> > - I am in favor of grammar markups like xsd or relaxng because then
> > constraints (e.g. EnumerationConstraints) can easily be used to fill
> > e.g. comboboxes (see example2 in precept) with e.g.
> > schematron all this
> > is "hidden" in expressions
>
> Agree
>
> > - Later I like to add an interface ClientJavaScript (or somthing like
> > that) so that constraints can produce javascript code for
> > client validation
>
> This would be a cool feature.

definitly!!

> > Puh! Now it's your time ;)
> > Any comments are welcome!!!
>
> See above. More to come after looking closer to your samples.

looking forward on that...
--
Torsten


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


Mime
View raw message