=head1 NAME

HTML::FormHandler::Manual::Rendering

=head1 SYNOPSIS

HFH has a number of different rendering methods.

   1. Handcoded html with no assist from HFH at all
   2. Use templates and the field 'widget' to determine the template snippet
   3. Use a rendering role in your form class, like Render::Simple

and now:

   4. Automatically installed rendering widgets using a combination of 
      rendering roles, which can easily be customized by the user.

=head1 Rendering with Widgets

This feature is still experimental. The functionality will probably remain
approximately the same, but interfaces may change.

All FormHandler widgets are Moose roles.
Default widget roles are found in the HTML::FormHandler::Widget directory. They include
widgets for the fields in the distribution. Each field can render itself with
C<< $field->render >>. The widget rendering roles are applied at build time in 
each field object. 

The name space used to look for the widget roles can be specified on a form or
field basis by setting 'widget_name_space' to an arrayref of name spaces:

   has '+widget_name_space' => ( default => sub { ['MyApp::Form::Submit',
       'MyApp::Form::Widget' ]);

The HTML::FormHandler::Widget name space is always searched as the last name space.
This means that you can set up an application or form specific set of widgets.

Widgets in a widget directory (specified in widget_name_space) are located in either
a 'Field', 'Wrapper', or 'Form' subdirectory.

The form's rendering role is looked for in the widget name space plus 'Form'. The
default form rendering roles are in HTML::FormHandler::Widget::Form. The form
widget is specified in the form with 'widget_form'.

   package MyApp::Form;
   ....
   has '+widget_form' => ( widget_form => 'Simple' ); 
   ...

The 'wrapper' for field rendering can also be specified with 'widget_wrapper'. 
The widget specified will be looked for in the widget directories' 'Wrapper'
subdirectory. It contains a 'wrap_field' method which is called from the Field
widgets.  The wrap_field method takes the basic rendered field (passed from the
field widget) and wraps it with HTML. The defaults provided are 'Div' and 'Table'.
You can specify a wrapper class for all the fields in the form by setting 
'widget_wrapper' in the form class, or you can set them individually by setting
'widget_wrapper' on individual fields.

   has 'some_field' => ( widget_wrapper => 'MyWrapper' );
 
The 'widget' attribute is set to a default in FormHandler fields, or you can 
set it to a different widget in your field declarations.

   has 'another_field' => ( widget => 'MyWidget', widget_wrapper => 'MyWrapper' ); 

Can be set in the form:

   widget_name_space
   widget_wrapper
   widget_form

Can be set in the field:

   widget_name_space
   widget_wrapper
   widget

The widget_name_space and widget_wrapper will be copied into the fields from the
form if they are not already defined.

By default, a form will use the Form::Simple and Wrapper::Simple widgets. If you
want to use the table format you can change the 'widget_form' and 'widget_wrapper'
attributes in the form, or do it on new:

   my $form = MyApp::Form->new( widget_form => 'Table', widget_wrapper => 'Table' );

The form widgets will not be applied if a 'render' method already exists in the form,
such as is the case when you've done a 'with' for L<HTML::FormHandler::Render::Simple>.

=head1 Customized Widgets

You can create custom widgets for your complete application or on a per-form basis.
One possible layout for your widgets;

   lib/MyApp/Form
   lib/MyApp/Form/Widget/Form
   lib/MyApp/Form/Widget/Field (contains MyWidget.pm)
   lib/MyApp/Form/Widget/Wrapper

Create custom widgets and put them in the respective directories, and then specify your
widget name space:

   MyApp::Form::User:
   ...
   has '+widget_name_space' => ( default => sub { ['MyApp::Form::Widget'] } );
   ..
   has 'some_field' => ( widget => 'MyWidget' );

Your rendering widgets will be applied into your field classes.

The 'widget_tags' hashref attribute has been provided to allow customizing
rendering behavior on a per-field basis. They can be used to switch the Simple
wrapper from divs to using paragraphs instead:

   has_field 'my_field' => ( widget_tags => {wrapper_start => '<p>',
       wrapper_end => '</p>' } );

Widget tags set for the form will be copied into the fields if the same key
does not exist in the field 'wrapper_tags' hashref, so you can set the
widget_tags in a form to apply them to all the fields:

   package MyApp::Form;
   ....
   has '+widget_tags' => ( default => sub { {wrapper_start => '<p>',
      wrapper_end => '</p>' } );

=head1 Creating Widgets

The new widgets are designed to be used with either the original FormHandler 
form objects or the new L<HTML::FormHandler::Result> objects. For that reason,
you should use C<< $field->result >> to access the current value, errors and 
'fif' (fill-in-form) in field widgets, so that they will work 
for both form and result rendering.

The basic structure for a field widget:

   package MyApp::Form::Widget::Field::MyWidget;
   use Moose::Role;

   sub render {
      my ( $self, $result ) = @_;

      $result ||= $self->result;
      my $output;
      < create rendered field >
      my $fif = $result->fif;
      my $value = $result->value;
      my $errors = $result->errors;
      < done creating rendered field )
      return $self->wrap_field($result, $output);
   }
   use namespace::autoclean; 
   1;

=cut
