cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Wallez <sylv...@apache.org>
Subject Re: CForms Wizards
Date Fri, 12 Nov 2004 22:47:11 GMT
Reinhard Poetz wrote:

> Sylvain Wallez wrote:
>
>> Sylvain Wallez wrote:
>>
>>> Sorry to rain on the party, but the new widget state stuff in CForms 
>>> should make building multi-page forms a piece of cake.
>>>
>>> Off writing an example....
>>
>>
>> Done, I wrote my first wizard with CForms :-)
>>
>> Please update branch 2.1.x and point your browser to 
>> http://localhost:8888/forms-samples/do-multipage.flow
>>
>> Enjoy!
>
>
> Great, thanks for the example! One question: IIUC the wizard is driven 
> by the widget states and the event handling mechanism.


Yes: the various "pages" are widget groups (fd:struct) whose state is 
set either to active or invisible depending on the displayed page. The 
initial state, in the form definition, is to have only page1 being 
active, others being invisible. Navigation is managed by fd:action that 
change the page state. "next" validates the current page whereas "prev" 
doesn't. On the last page, a fd:submit goes back to flowscript if 
validation is successful.

> This may solve many use cases but would it be possible to control 
> which part of the form is shown by the controller (flowscript) which 
> would bring some more flexibility (mix in non-forms pages, jump to 
> different sub-pages)?


That is possible if you use fd:submit instead of fd:action when control 
has to come back to flowscript. Since only the active widgets are 
validated, the submit will be sucessful if the widgets in the current 
page are valid, not taking other pages into account. It's then the 
flowscript's responsibility to display the appropriate page when calling 
again form.showForm().

> [some pseudocode ...]
> var myFlow() {
>   var form = new Form("myForm");
>   form.load(myBean);
>   form.showSubForm("myPipeline", "../page1");
>   cocoon.sendPageAndWait("showAnotherPage");
>   form.showSubForm("myPipeline", "../page");
>   form.save(myBean);
> }


The "showSubForm" above would simply set all pages to invisible state 
except the one defined by the second parameter (which should be "pageX" 
rather than "../pageX").

> And while writing this, another question came up: What's the best way 
> to deal with validation errors? example: On page 2 the users enters 
> something that wouldn't let page 1 validate any more. Can we handle this?


Validation of the last page could revalidate previous pages in order, 
and switch back to the first one that doesn't validate successfully.

That could be something like:

function validateWizard() {
  currentPage.setState(WidgetState.INVISIBLE); // another one may be 
chosen below
  for (page in pageList) {
    page.setState(WidgetState.ACTIVE);
    if (page.validate()) {
      page.setState(WidgetState.INVISIBLE);
    } else {
      return false; // validation failed
    }
  }
}


Setting the page state to active before calling validate() is important 
as non-active widgets are not validated. That isn't a problem here since 
we must redisplay a page that doesn't validate, but I'm thinking of 
adding a Widget.validate(boolean force) method, that would, when "force" 
is true, validate widgets whatever their state.

Sylvain

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


Mime
View raw message