Summary: [% form.summary %]
Or you can make these customizations Moose roles. package MyApp::Form::Role::Base; use Moose::Role; ... package MyApp::Form::Whatsup; use Moose; with 'MyApp::Form::Role::Base'; ... =head2 Split up your forms into reusable pieces An address field: package Form::Field::Address; use HTML::FormHandler::Moose; extends 'HTML::FormHandler::Field::Compound'; has_field 'street'; has_field 'city'; has_field 'state' => ( type => 'Select', options_method => \&options_state ); has_field 'zip' => ( type => '+Zip' ); sub options_state { ... } no HTML::FormHandler::Moose; 1; A person form that includes an address field: package Form::Person; use HTML::FormHandler::Moose; extends 'HTML::FormHandler'; has '+widget_name_space' => ( default => sub {['Form::Field']} ); has_field 'name'; has_field 'telephone'; has_field 'email' => ( type => 'Email' ); has_field 'address' => ( type => 'Address' ); sub validate_name { .... } no HTML::FormHandler::Moose; 1; Or you can use roles; package Form::Role::Address; use HTML::FormHandler::Moose::Role; has_field 'street'; has_field 'city'; has_field 'state' => ( type => 'Select' ); has_field 'zip' => ( type => '+Zip' ); sub options_state { ... } no HTML::FormHandler::Moose::Role; 1; You could make roles that are collections of validations: package Form::Role::Member; use Moose::Role; sub check_zip { ... } sub check_email { ... } 1; And if the validations apply to fields with different names, specify the 'validate_method' on the fields: with 'Form::Role::Member'; has_field 'zip' => ( type => 'Integer', validate_method => \&check_zip ); =head2 Access a user record in the form You might need the user_id to create specialized select lists, or do other form processing. Add a user_id attribute to your form: has 'user_id' => ( isa => 'Int', is => 'rw' ); Then pass it in when you process the form: $form->process( item => $item, params => $c->req->parameters, user_id => $c->user->user_id ); =head2 Handle extra database fields If there is another database field that needs to be updated when a row is created, add an attribute to the form, and then process it with C< before 'update_model' >. In the form: has 'hostname' => ( isa => 'Int', is => 'rw' ); before 'update_model' => sub { my $self = shift; $self->item->hostname( $self->hostname ); }; Then just use an additional parameter when you create/process your form: $form->process( item => $item, params => $params, hostname => $c->req->host ); Some kinds of DB relationships need to have primary keys which might be more easily set in the update_model method; sub update_model { my $self = shift; my $values = $self->values; $values->{some_field}->{some_key} = 'some_value'; $self->_set_value($values); $self->next::method; } If you need to access a database field in order to create the value for a form field you can use a C< default_* > method. sub default_myformfield { my ($self, $field, $item) = @_; return unless defined $item; my $databasefield = $item->databasefield; my $value = ... # do stuff return $value; } =head2 Additional changes to the database If you want to do additional database updates besides the ones that FormHandler does for you, the best solution would generally be to add the functionality to your result source or resultset classes, but if you want to do additional updates in a form you should use an 'around' method modifier and a transaction: around 'update_model' => sub { my $orig = shift; my $self = shift; my $item = $self->item; $self->schema->txn_do( sub { $self->$orig(@_);