Data::MuForm::Manual::Intro - introduction to using MuForm
version 0.05
Manual Index
Data::MuForm is a data validation and form handling package written in Moo. It is a conversion of FormHandler to Moo. The core behavior is the same, but things have been regularized, simplified and in some cases re-written. Rendering is substantially changed.
A MuForm 'validator' or 'form' is a Perl subclass of Data::MuForm. In your class you define fields and validators. Because it's a Perl class written with Moo, you have a lot of flexibility and control.
You can validate with Perl methods or Type::Tiny or Moose type constraints; you can use your own validation libraries. You can define your own field classes that perform specialized validation.
The most common way of using MuForm is to create a new package. You must 'use' Moo and Data::MuForm::Meta and 'extend' MuForm.:
package MyApp::Form::Sample; use Moo; use Data::MuForm::Meta; extends 'Data::MuForm';
Then you add some fields with 'has_field', and a field 'type' (the short name of the field package). (Fields with no type have type 'Text'.)
has_field 'foo'; has_field 'bar' => ( type => 'Select' );
For non-form validators there are field types such as Text, Integer, List, Compound, Float, Currency. For forms, common field types are Text, Select, Checkbox, Submit, Hidden, Reset, TextArea. See Data::MuForm::Manual::Fields for more information.
You can also create a class 'dynamically', by creating a 'new' Data::MuForm object. Use a 'field_list' parameter to create the fields instead of 'has_field'.
my $validator = Data::MuForm->new( field_list => [ 'username' => { type => 'Text' }, 'selections' => { type => 'Select' }, ] );
Some features will not be available using this method (like the automatic use of 'validate_<field_name>' methods) and it's not as easy to test, of course.
The MuForm object's 'check' or 'process' method should be run on each request, passing in the data or request parameters:
$validator->check( data => { .... } ); $form->process( params => $c->request->body_parameters );
If the data or parameters are not empty, then validation will be performed.
You can set most other MuForm attributes on the 'process' call., One useful feature is that you can activate or inactivate fields:
$form->process( params => $params, active => ['field1', 'field2'] );
The return value of $form->process is the 'validated' flag, or the same as $form->validated.
$form->process
$form->validated
See also Data::MuForm.
A database form inherits from Data::MuForm::Model::DBIC instead of Data::MuForm. You pass in the DBIC row object on 'process':
$form->process( model => $row, params => $params );
The 'model' is used for defaults, unless it's a new_result row.
See also Data::MuForm::Manual::Database and Data::MuForm::Role::Model::DBIC.
A database form will have saved the data or created a new row, so often no more processing is necessary. You can get the structured field values from $form->values, and do whatever you want with them.
$form->values
If the validation succeeded, you may want to redirect:
$form->process( params => $params ); return unless $form->validated $c->res->redirect( .... ); -- or -- return unless $form->process( params => params ); $c->res->redirect;
At its simplest, all you need to do is $form->render in a template.
$form->render
[% form.render %]
You can also easily render individual fields:
[% form.field('foo').render %]
or individual field elements:
[% form.field('foo').render_element({ class = 'mb20' }) %]
The form object will give you a hashref of values suitable for filling in the form with $form->fif.
$form->fif
For more rendering info, see Data::MuForm::Manual::Rendering.
The simplest way to provide defaults is by setting the default attribute in a field definition:
has_field 'my_foo' => ( default => 'my_foo' );
The database row ('model') that is passed in will provide initial values for the form, of course. You can also provide default values with an 'init_values', which acts kind of like a database object:
$form->process( init_values => { foo => '...', bar => '...' } );
There are a number of other flags and methods for providing defaults. See Data::MuForm::Manual::Defaults.
You can validate a field with a method in the form 'validate_<field_name>':
has_field 'foo'; sub validate_foo { my ( $self, $field ) = @_; # self is the form unless( $field->value == .... ) { $field->add_error( .... ); } }
You can provide a validation coderef that will be a field method:
has_field 'foo' => ( methods => { validate => \&check_foo } ); OR with shortcut has_field 'foo' => ( 'meth.validate' => \&check_foo ); sub check_foo { my $self = shift; # self is field unless( $self->value == ... ) { $self->add_error( ... ); } }
You can use 'apply' to use Type::Tiny types for validation, from Data::MuForm::Types or another Type::Tiny or Moose type collection:
use Data::MuForm::Types ('NotAllDigits'); ... has_field 'my_field' => ( apply => [NotAllDigits] );
Or create validators with check:
has_field 'quux' => ( apply => [ { check => qr/abc/, message => 'Not a valid quux' } ] );
You can also create custom fields with custom validation, or use an existing field that does the validation you need.
See Data::MuForm::Manual::Validation for more information on validation or Data::MuForm::Manual::Fields for more information on fields.
You can use 'has_field' in Moo roles:
package MyApp::Form::Role::Address; use Moo::Role; use Data::MuForm::Meta; has_field 'foo'; has_block 'bar';
Your forms can inherit from base classes that set common application defaults. You can override field definitions with '+'.
You can create 'compound' fields and include them in a form:
package MyApp::Form::Field::Complex; use Moo; use Data::MuForm::Meta; extends 'Data::MuForm::Field::Compound'; has_field 'field1' => ( validate_method => \&validate_field1 ); has_field 'field2' => ( type => 'Select', options_method => \&options_field2 ); sub validate_field1 { ... } sub options_field2 { ... } ... package MyApp::Form::Complex; use Moo; use Data::MuForm::Meta; extends 'Data::MuForm'; has '+field_name_space' => ( default => 'MyApp::Form::Field' ); has_field 'compound1' => ( type => 'Complex' ); has_field 'compound2' => ( type => 'Complex' );
It's much easier to write unit tests for MuForm forms than for Catalyst controllers. The 't' directory of the downloaded distribution has lots of examples. See Data::MuForm::Manual::Testing for more information.
MuForm's built-in errors are added to the form fields with $field->add_error, and to the form with $form->add_form_error.
$field->add_error
$form->add_form_error
If you wish to skip localization for a particular message (such as for system errors) you can use $field->push_error or $form->push_form_error.
$field->push_error
$form->push_form_error
See Data::MuForm::Localizer.
MuForm uses Moo, and is significantly faster than FormHandler on form creation. To make validation or form processing even faster, use a persistent form class in order to skip the object construction overhead. A 'clear' method is called at the beginning of each 'check' or process' call, but non-internal state added to the object will have to be cleared by the programmer.
Gerda Shank
This software is copyright (c) 2018 by Gerda Shank.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Data::MuForm, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Data::MuForm
CPAN shell
perl -MCPAN -e shell install Data::MuForm
For more information on module installation, please visit the detailed CPAN module installation guide.