[html-formfu] multi-page forms
Carl Franks
fireartist at gmail.com
Tue Jan 29 16:15:35 GMT 2008
I've added support for multi-page / multi-stage forms.
The main aim of the approach I've taken is to remove the need for
server-side sessions to store the intermediary data.
Data from previous pages is encrypted and stored in a single hidden field.
Having the data encrypted means you don't have to worry about
validating it all over again, as you can be sure the user hasn't
changed it.
Catalyst-Controller-HTML-FormFu has been updated to provide new
multiform-specific actions. MultiFormConfig is comparable to the older
FormConfig action. e.g.
sub homepage : Path('') : MultiForm {
my ( $self, $c ) = @_;
}
will essentially do:
my $multiform = HTML::FormFu::MultiForm->new;
$multiform->load_config_file('root/forms/homepage.yml');
$c->stash->{multiform} = $multiform;
Note that it's creating a HTML::FormFu::MultiForm object, instead of a
HTML::FormFu object.
To use the multiform in your templates, you just need to do:
[% multiform%]
and it'll do the right thing (tm).
To handle the multiform in your code, you probably just need to do:
sub foo : Path('foo') : MultiForm {
my ( $self, $c ) = @_;
my $multi = $c->stash->{multiform};
if ( $multi->complete ) {
my $params = $multi->current_form->params;
# do something with params
}
}
By default, params() will include all the input from previous forms.
If you don't want that, and would rather handle each form as it's
submitted, set combine_params() to false.
You can retrieve the current form with $multi->current_form;
and the current form number with $multi->current_form_number;
(note that it counts up from 1, not zero!)
An example of a suitable multiform config file is:
---
auto_fieldset: 1
crypt_args:
-key: 'my secret'
forms:
# form 1
-
elements:
- name: foo
constraints: [ Required ]
- type: Submit
name: submit
# form 2
-
indicator: bar
elements:
- name: bar
constraints: [ Required ]
- type: Submit
name: submit
'forms' takes an arrayref, with each item comprising a complete form.
Notice that I set 'auto_fieldset' at the multiform-level. This causes
auto_fieldset to be passed to every form as it's created.
Take note though, that not all form-methods are supported by a
multiform. In particular, you can't set elements(), constraints(),
etc. on a multiform - these need to be set on each individual form.
You must set crypt_args->{-key} yourself, otherwise it'll die.
crypt_args({}) is passed directly to Crypt::CBC->new, so can contain
any args that'll accept.
In particular, you can change the default encryption from DES to something else:
crypt_args:
-key: 'my key',
-cipher: 'Blowfish'
You also don't need to manually add the hidden-field for the encrypted
data yourself.
If you want to add the hidden-field yourself (for example, if you're
not using auto_fieldset, and you're worried about valid markup), the
docs will explain how to - once they're written ;)
I've been playing with this in a test app and am fairly happy with it,
so hopefully the API won't need to change; but the usual caveats
apply.
Cheers,
Carl
More information about the HTML-FormFu
mailing list