/lib/HTML/FormHandler/Manual/Intro.pod

http://github.com/gshank/html-formhandler · Unknown · 289 lines · 208 code · 81 blank · 0 comment · 0 complexity · 48e1bb3e678aa9e0055662fba0804680 MD5 · raw file

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