NAME

Form::Sensible::Reflector - A base class for writing Form::Sensible reflectors.

SYNOPSIS

my $reflector = Form::Sensible::Reflector::SomeSubclass->new();

my $generated_form = $reflector->reflect_from($data_source, $options);

DESCRIPTION

A Reflector in Form::Sensible is a class that inspects a data source and creates a form based on what it finds there. In other words it creates a form that 'reflects' the data elements found in the data source.

A good example of this would be to create forms based on a DBIx::Class result_source (or table definition.) Using the DBIC reflector, you could create form for editing a user's profile information simply by passing the User result_source into the reflector.

This module is a base class for writing reflectors, meaning you do not use this class directly. Instead you use one of the subclasses that deal with your data source type.

USAGE

my $reflector = Form::Sensible::Form::Reflector::SomeSubclass->new();

my $generated_form = $reflector->reflect_from($data_source, $options);

By default, a Reflector will create a new form using the exact fields found within the datasource. It is possible, however, to adjust this behavior using the $options hashref passed to the reflect_from call.

Adjusting the parameters of your new form

my $generated_form = $reflector->reflect_from($data_source, 
                                              { 
                                                form => {
                                                    name => 'profile_form',
                                                    validation => { 
                                                        code => sub { ... }
                                                    }
                                                }
                                              });

If you want to adjust the parameters of the new form, you can provide a hashref in the $options->{form} that will be passed to the Form::Sensible::Form->new() call.

Providing your own form

$reflector->reflect_from($data_source, 
                        { 
                            form => $my_existing_form_object
                        }
                        );

If you do not want to create a new form, but instead want the fields appended to an existing form, you can provide an existing form object in the options hash ( $options->{form} )

Changing field order

$reflector->reflect_from($data_source, 
                        { 
                            ## sort fields alphabetically
                            fieldname_filter => sub { 
                                                    return sort(@_);
                                                },
                        }
                        );
                        

If you are unhappy with the order that your fields are displaying in you can adjust it by providing a subroutine in $options->{'fieldname_filter'}. The subroutine takes the list of fields as returned by get_fieldnames() and should return an array (not an array ref) of the fields in the new order. Note that you can also remove fields this way. Note also that no checking is done to verify that the fieldnames you return are valid, if you return any fields that were not in the original array, you are likely to cause an exception when the field definition is created.

Changing field names

$reflector->reflect_from($data_source, { ## change 'logon' field to be 'username' in the form ## and other related adjustments. fieldname_map => { logon => 'username', pass => 'password', address => 'email', home_num => 'phone', parent_account => undef, }, } );

By default, the Form::Sensible field names are exactly the same as the data source's feild names. If you would rather not expose your internal field names or have other reason to change them, you can provide a $options->{'fieldname_map'} hashref to change them on the fly. The fieldname_map is simply an mapping between the original field name and the Form::Sensible field name you would like it to use. If you use this method you must provide a mapping for ALL fields as a missing field (or a field with an undef value) is treated as a request to remove the field from the form entirely.

CREATING YOUR OWN REFLECTOR

Creating a new reflector class is extraordinarily simple. All you need to do is create a subclass of Form::Sensible::Reflector and then create two subroutines: get_fieldnames and get_field_definition.

As you might expect, get_fieldnames should return an array containing the names of the fields that are to be created. get_field_definition is then called for each field to be created and should return a hashref representing that field suitable for passing to the Form::Sensible::Field create_from_flattened method.

Note that in both cases, the contents of $datasource are specific to your reflector subclass and are not inspected in any way by the base class.

Subclass Boilerplate

package My::Reflector;
use Moose;
use namespace::autoclean;
extends 'Form::Sensible::Form::Reflector';

sub get_fieldnames {
    my ($self, $form, $datasource) = @_;
    my @fieldnames;
    
    foreach my $field ($datasource->the_way_to_get_all_your_fields()) {
        push @fieldnames, $field->name;
    }
    return @fieldnames;
}

sub get_field_definition { 
    my ($self, $form, $datasource, $fieldname) = @_;
    
    my $field_definition = {
        name => $fieldname
    };
    
    ## inspect $datasource's $fieldname and add things to $field_definition
    
    return $field_definition;
}

Author's note

This is a base class to write reflectors for things like, configuration files, or my favorite, a database schema.

The idea is to give you something that creates a form from some other source that already defines form-like properties, ie a database schema that already has all the properties and fields a form would need.

I personally hate dealing with forms that are longer than a search field or login form, so this really fits into my style.

AUTHOR

Devin Austin <dhoss@cpan.org>

ACKNOWLEDGEMENTS

Jay Kuri <jayk@cpan.org> for his awesome Form::Sensible library and helping me get this library in tune with it.

SEE ALSO

Form::Sensible Form::Sensible Wiki: http://wiki.catalyzed.org/cpan-modules/form-sensible Form::Sensible Discussion: http://groups.google.com/group/formsensible