/lib/HTML/FormHandler/Manual/Intro.pod
Unknown | 289 lines | 208 code | 81 blank | 0 comment | 0 complexity | 48e1bb3e678aa9e0055662fba0804680 MD5 | raw file
1package HTML::FormHandler::Manual::Intro; 2# ABSTRACT: introduction to using FormHandler 3 4=head1 SYNOPSIS 5 6L<Manual Index|HTML::FormHandler::Manual> 7 8HTML::FormHandler is a form handling package that validates HTML form data 9and, for database forms, saves it to the database on validation. 10It has field classes that match various data types and HTML form elements, 11and rendering roles that can be used to render forms in many 12different ways, from hand-built forms to totally automated rendering. 13It can, of course, be used to validate data even if you are not interested 14in the rendering capabilities. 15 16A FormHandler 'form' is a Perl subclass of L<HTML::FormHandler> for non-database forms, 17or a subclass of L<HTML::FormHandler::Model::DBIC> for database forms, and in 18it you define your fields and validation routines. Because it's a Perl class 19written in Moose, you have a lot of flexibility and control. 20 21You can validate with Perl methods or Moose type constraints; you can use 22your own validation libraries. You can define your own field classes that 23perform specialized validation. 24 25When the form is validated, you can get the validated values back with 26C<< $form->value >>. 27 28A working example of a Catalyst app using FormHandler forms is available 29on github at L<https://github.com/gshank/formhandler-example>. 30 31=head1 Basics 32 33=head2 Create a form class 34 35The most common way of using FormHandler is to create a form package. You 36must 'use' "HTML::FormHandler::Moose" and 'extend' FormHandler: 37 38 package MyApp::Form::Sample; 39 use HTML::FormHandler::Moose; 40 extends 'HTML::FormHandler'; 41 42Then you add some fields with 'has_field', and a field 'type' (the short 43name of the field package). (Fields with no type have type 'Text'.) 44 45 has_field 'foo'; 46 has_field 'bar' => ( type => 'Select' ); 47 48Basic field types are Text, Select, Checkbox, Submit, Hidden, Reset, 49TextArea, Password, Upload. See L<HTML::FormHandler::Manual::Fields> for 50more information. 51 52=head2 Or create a form class dynamically 53 54You can also create a form class 'dynamically', by creating a 'new' 55HTML::FormHandler object. Use a 'field_list' parameter to create the fields 56instead of 'has_field'. 57 58 my $form = HTML::FormHandler->new( field_list => [ 59 'username' => { type => 'Text' }, 60 'selections' => { type => 'Select' }, 61 ] 62 ); 63 64Some features will not be available using this method (like the automatic 65use of 'validate_<field_name>' methods) and it's not as easy to test, 66of course. 67 68=head2 Process the form 69 70The form's 'process' method should be run on each request, passing in the 71request parameters: 72 73 $form->process( params => $c->request->body_parameters, 74 action => $action, 75 ); 76 77If the parameters are not empty, then validation will be performed. The 78corollary is that you should not pass in extra parameters when the form 79has not been posted. A special 'posted' flag can be used if 80the form consists entirely of fields like checkboxes that do not include 81names in params if unchecked, and also works to prevent validation from 82being performed if there are extra params: 83 84 $form->process( posted => ( $c->req->method eq 'POST' ), 85 params => $c->request->parameters, action => $action ); 86 87There is an alternative method for processing the form, which is sometimes 88preferred for persistent forms. It returns a 'result' object, and clears 89the form: 90 91 my $result = $form->run( params => $c->request->body_parameters ); 92 93You can also set most other FormHandler attributes on the 'process' call., 94One useful feature is that you can activate or inactivate fields: 95 96 $form->process( params => $params, active => ['field1', 'field2'] ); 97 98See also L<HTML::FormHandler>. 99 100=head2 Or process a database form 101 102A database form inherits from L<HTML::FormHandler::Model::DBIC> instead of 103L<HTML::FormHandler>. You must either pass in the DBIC row object or give 104FormHandler information to retrieve the row object. 105 106 $form->process( item => $row, params => $params ); 107 -- or -- 108 $form->process( item_id => $id, schema => $schema, 109 item_class => 'MyRow', params => $params ); 110 111'item_class' is often set in the form class. 112 113See also L<HTML::FormHandler::Manual::Database> and 114L<HTML::FormHandler::TraitFor::Model::DBIC>. 115 116=head2 After processing the form 117 118A database form will have saved the data or created a new row, so often no 119more processing is necessary. You can get the structured field values from 120C<< $form->value >>, and do whatever you want with them. 121 122If the validation succeeded, you may want to redirect: 123 124 $form->process( params => $params ); 125 return unless $form->validated 126 $c->res->redirect( .... ); 127 -- or -- 128 return unless $form->process( params => params ); 129 $c->res->redirect; 130 131=head2 Rendering the form 132 133At its simplest, all you need to do is C<< $form->render >> in a 134template. 135 136 [% form.render %] 137 138The automatic rendering is powerful and flexible -- you can do almost 139anything with the right settings. Or you can render the form with a 140template. 141 142The form object will give you a hashref of values suitable for 143filling in the form with C<< $form->fif >>. 144 145By default FormHandler structures fields (and renders them) in a way 146that matches the database. If you want to organize the rendering output 147in different ways, you can use blocks to organize your fields. 148 149 has_block 'fieldset1' => ( render_list => ['foo', 'bar'] ); 150 151For more rendering info, see L<HTML::FormHandler::Manual::Rendering>. 152 153=head2 Defaults for form fields 154 155The simplest way to provide defaults is by setting the default attribute 156in a field definition: 157 158 has_field 'my_foo' => ( default => 'my_foo' ); 159 160The database row ('item') that is passed in will provide initial values 161for the form, of course. You can also provide default values with an 162'init_object', which acts kind of like a database object: 163 164 $form->process( init_object => { foo => '...', bar => '...' } ); 165 166There are a number of other flags and methods for providing defaults. 167See L<HTML::FormHandler::Manual::Defaults>. 168 169=head2 Validation 170 171You can validate a field with a method in the form 'validate_<field_name>': 172 173 has_field 'foo'; 174 sub validate_foo { 175 my ( $self, $field ) = @_; # self is the form 176 unless( $field->value == .... ) { 177 $field->add_error( .... ); 178 } 179 } 180 181You can provide a validation coderef that will be a field method: 182 183 has_field 'foo' => ( validate_method => \&check_foo ); 184 sub check_foo { 185 my $self = shift; # self is field 186 unless( $self->value == ... ) { 187 $self->add_error( ... ); 188 } 189 } 190 191You can use 'apply' to use Moose types for validation, from L<HTML::FormHandler::Types> 192or another Moose type collection: 193 194 use HTML::FormHandler::Types ('NotAllDigits'); 195 ... 196 has_field 'my_field' => ( apply => [NotAllDigits] ); 197 198Or create validators with check: 199 200 has_field 'quux' => ( 201 apply => [ { check => qr/abc/, message => 'Not a valid quux' } ] ); 202 203Or use a validate coderef: 204 205 has_field 'foo' => ( validate_method => \&check_foo ); 206 sub check_foo { 207 my $self = shift; 208 if ( $self->value =~ s/..../ ) { 209 $self->add_error('....'); 210 } 211 } 212 213You can also create custom fields with custom validation, or use an 214existing field that does the validation you need. 215 216See L<HTML::FormHandler::Manual::Validation> for more information on 217validation or L<HTML::FormHandler::Manual::Fields> for more information 218on fields. 219 220=head2 Organizing your form code 221 222You can use 'has_field' and 'has_block' in Moose roles: 223 224 package MyApp::Form::Role::Address; 225 use HTML::FormHandler::Moose::Role; 226 227 has_field 'foo'; 228 has_block 'bar'; 229 230Your forms can inherit from base classes that set common application 231defaults. You can override field definitions with '+'. 232 233You can create 'compound' fields and include them in a form: 234 235 package MyApp::Form::Field::Complex; 236 use HTML::FormHandler::Moose; 237 extends 'HTML::FormHandler::Field::Compound'; 238 has_field 'field1' => ( validate_method => \&validate_field1 ); 239 has_field 'field2' => ( type => 'Select', 240 options_method => \&options_field2 ); 241 sub validate_field1 { ... } 242 sub options_field2 { ... } 243 ... 244 package MyApp::Form::Complex; 245 use HTML::FormHandler::Moose; 246 extends 'HTML::FormHandler'; 247 has '+field_name_space' => ( default => 'MyApp::Form::Field' ); 248 has_field 'compound1' => ( type => 'Complex' ); 249 has_field 'compound2' => ( type => 'Complex' ); 250 251=head2 Testing 252 253It's much easier to write unit tests for FormHandler forms than for 254Catalyst controllers. The 't' directory of the downloaded distribution 255has lots of examples. See L<HTML::FormHandler::Manual::Testing> for more 256information. 257 258=head1 Localization 259 260FormHandler's built-in errors are added to the form fields with 261C<< $field->add_error >>, and to the form with C<< $form->add_form_error >>. 262These methods call a C<< $self->_localize >> method which is a coderef set from 263the field's default_localize sub, the field's 'localize_meth' attribute with 264C<< localize_meth => sub {} >>, or a form's sub localize_meth. The default localize 265uses Locale::Maketext. You can also use duck_type classes for localization. 266See the documentation in L<HTML::FormHandler::TraitFor::I18N> and the tests in xt/locale.t. 267 268If you wish to skip localization for a particular message (such as for system errors) 269you can use C<< $field->push_errors >> or C<< $form->push_form_errors >>. 270 271See also L<HTML::FormHandler::TraitFor::I18N>. 272 273=head1 Performance 274 275FormHandler makes heavy use of Moose, so almost all of FormHandler's profiled time 276will actually be in Moose methods, mostly constructing form and field attributes. 277Some people prefer to use a persistent form class (in a Moose attribute) in order 278to skip the form building step on each call. Other people don't like that solution 279because state will remain in the form until the next process call. The 'clear' 280method is called at the beginning of each 'process', but additional Moose attributes 281in the form, etc, will have to cleared by the programmer. 282 283If you are loading options from the database and you don't need to have them refreshed 284each time, you can set the 'do_not_reload' flag in the Select/Multiple field. 285If you're not using the field widget roles, you can set the 'no_widgets' flag. 286If you always use 'process' on each call (recommended) then you can set the 287'no_preload' flag in the form to skip building results in BUILD (new). 288 289=cut