HTML::FormHandler::FieUser)Contributed Perl DocumenHTML::FormHandler::Field(3)NAMEHTML::FormHandler::Field - base class for fields
VERSION
version 0.35005
SYNOPSIS
Instances of Field subclasses are generally built by HTML::FormHandler
from 'has_field' declarations or the field_list, but they can also be
constructed using new (usually for test purposes).
use HTML::FormHandler::Field::Text;
my $field = HTML::FormHandler::Field::Text->new( name => $name, ... );
In your custom field class:
package MyApp::Field::MyText;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler::Field::Text';
has 'my_attribute' => ( isa => 'Str', is => 'rw' );
apply [ { transform => sub { ... } },
{ check => ['fighter', 'bard', 'mage' ], message => '....' }
];
1;
DESCRIPTION
This is the base class for form fields. The 'type' of a field class is
used in the FormHandler field_list or has_field to identify which field
class to load. If the type is not specified, it defaults to Text.
There are two rough categories of Field classes: those that do extra
processing and those that are simple validators. The 'Compound',
'Repeatable', and 'Select' fields are fields that are functional.
A number of field classes are provided by the distribution. The basic
for-validation (as opposed to 'functional') field types are:
Text
Integer
Boolean
These field types alone would be enough for most applications, since
the equivalent of the others could be defined using field attributes,
custom validation methods, and applied actions. There is some benefit
to having descriptive names, of course, and if you have multiple fields
requiring the same validation, defining a custom field class may be a
good idea.
Inheritance hierarchy of the distribution's field classes:
Compound
Repeatable
Text
Money
Password
Integer
PosInteger
TextArea
HtmlArea
Select
Multiple
IntRange
Hour
Minute
MonthDay
Month
Second
Year
MonthName
Weekday
Boolean
Checkbox
DateMDY
DateTime
Email
PrimaryKey
See the documentation or source for the individual fields.
Many field classes contain only a list of constraints and
transformations to apply. Some use the 'validate' method, which is
called after the actions are applied. Some build a custom select list
using 'build_options'.
ATTRIBUTES
Names, types, accessor
name
The name of the field. Used in the HTML form. Often a db accessor.
The only required attribute.
type
The class or type of the field. The 'type' of
HTML::FormHandler::Field::Money is 'Money'. Classes that you define
yourself are prefixed with '+'.
accessor
If the name of your field is different than your database accessor,
use this attribute to provide the accessor.
full_name
The name of the field with all parents:
'event.start_date.month'
full_accessor
The field accessor with all parents
html_name
The full_name plus the form name if 'html_prefix' is set.
input_param
By default we expect an input parameter based on the field name.
This allows you to look for a different input parameter.
Field data
inactive, is_inactive, is_active
Set the 'inactive' attribute to 1 if this field is inactive. The
'inactive' attribute that isn't set or is set to 0 will make a
field 'active'. This provides a way to define fields in the form
and selectively set them to inactive. There is also an '_active'
attribute, for internal use to indicate that the field has been
activated/inactivated on 'process' by the form's
'active'/'inactive' attributes.
You can use the is_inactive and is_active methods to check whether
this particular field is active.
if( $form->field('foo')->is_active ) { ... }
input
The input string from the parameters passed in.
value
The value as it would come from or go into the database, after
being acted on by transforms. Used to construct the "$form->values"
hash. Validation and constraints act on 'value'.
fif Values used to fill in the form. Read only. Use a deflation to get
from 'value' to 'fif' if an inflator was used. (Deflations can be
done in two different places. Set 'deflate_to' => 'fif' to deflate
in fillinform'.)
[% form.field('title').fif %]
init_value
Initial value populated by init_from_object. You can tell if a
field has changed by comparing 'init_value' and 'value'. Read only.
input_without_param
Input for this field if there is no param. Needed for checkbox,
since an unchecked checkbox does not return a parameter.
Form, parent
form
A reference to the containing form.
parent
A reference to the parent of this field. Compound fields are the
parents for the fields they contain.
Errors
errors
Returns the error list for the field. Also provides 'num_errors',
'has_errors', 'push_errors' and 'clear_errors' from Array trait.
Use 'add_error' to add an error to the array if you want to use a
MakeText language handle. Default is an empty list.
add_error
Add an error to the list of errors. If $field->form is defined
then process error message as Maketext input. See
$form->language_handle for details. Returns undef.
return $field->add_error( 'bad data' ) if $bad;
error_fields
Compound fields will have an array of errors from the subfields.
Attributes for creating HTML
There's a generic 'html_attr' hashref attribute that can be used to set
arbitrary HTML attributes on a field.
has_field 'foo' => ( html_attr => { readonly => 1, my_attr => 'abc' } );
Some attributes also have specific setters (readonly', 'disabled',
'style', 'title', 'tabindex).
has_field 'bar' => ( readonly => 1 );
title - Place to put title for field.
style - Place to put field style string
disabled - for the HTML flag
tabindex - for the HTML tab index
readonly - for the HTML flag
The javascript value of the javascript attribute is entered completely.
javascript - for a Javascript string
The following are used in rendering HTML, but are handled specially.
label - Text label for this field. Defaults to ucfirst field name.
css_class - For a css class name (string; could be several classes,
separated by spaces or commas). Used in wrapper for input field.
input_class - class attribute on the 'input' field. applied with
'_apply_html_attribute' (also html_attr => { class => '...' } )
id - Useful for javascript (default is html_name. to prefix with
form name, use 'html_prefix' in your form)
render_filter - Coderef for filtering fields before rendering. By default
changes >, <, &, " to the html entities
The order attribute may be used to set the order in which fields are
rendered.
order - Used for sorting errors and fields. Built automatically,
but may also be explicitly set
widget
The 'widget' attribute is used in rendering, so if you are not using
FormHandler's rendering facility, you don't need this attribute. It is
intended for use in generating HTML, in templates and the rendering
roles, and is used in HTML::FormHandler::Render::Simple. Fields of
different type can use the same widget.
This attribute is set in the field classes, or in the fields defined in
the form. If you want a new widget type, use a new name and provide a
'widget_<name>' method in your copy of Render::Simple or in your form
class.
If you are using a template based rendering system you will want to
create a widget template. (see HTML::FormHandler::Manual::Templates)
If you are using the widget roles, you can specify the widget with the
short class name instead.
Widget types for the provided field classes:
Widget : Field classes
---------------:-----------------------------------
text (Text) : Text, Integer
checkbox (Checkbox) : Checkbox, Boolean
radio_group
(RadioGroup) : Select, Multiple, IntRange (etc)
select (Select) : Select, Multiple, IntRange (etc)
checkbox_group
(CheckboxGroup) : Multiple select
textarea (Textarea) : TextArea, HtmlArea
compound (Compound) : Compound, Repeatable, DateTime
password (Password) : Password
hidden (Hidden) : Hidden
submit (Submit) : Submit
reset (Reset) : Reset
no_render (NoRender) :
upload (Upload) : Upload
Widget roles are automatically applied to field classes unless they
already have a 'render' method. Render::Simple will fall back to doing
"$field->render" if the corresponding widget method does not exist.
You can create your own widget roles and specify the namespace in
'widget_name_space'. In the form:
has '+widget_name_space' => ( default => sub { ['MyApp::Widget'] } );
If you want to use a fully specified role name for a widget, you can
prefix it with a '+':
widget => '+MyApp::Widget::SomeWidget'
For more about widgets, see HTML::FormHandler::Manual::Rendering.
Flags
password - prevents the entered value from being displayed in the form
writeonly - The initial value is not taken from the database
noupdate - Do not update this field in the database (does not appear in $form->value)
Form methods for fields
These provide the name of a method in a form (not the field ) which
will act on a particular field.
set_validate
Specify a form method to be used to validate this field. The
default is "'validate_' . $field->name". Periods in field names
will be replaced by underscores, so that the field 'addresses.city'
will use the 'validate_addresses_city' method for validation.
has_field 'title' => ( isa => 'Str', set_validate => 'check_title' );
has_field 'subtitle' => ( isa => 'Str', set_validate => 'check_title' );
set_default
The name of the method in the form that provides a field's default
value. Default is "'default_' . $field->name". Periods replaced by
underscores.
default
Provide an initial value just like the 'set_default' method, except
in the field declaration:
has_field 'bax' => ( default => 'Default bax' );
FormHandler has flipped back and forth a couple of times about
whether a default specified in the has_field definition should
override values provided in an initial item or init_object.
Sometimes people want one behavior, and sometimes the other. Now
'default' does *not* override.
If you pass in a model object with "item => $row" or an initial
object with "init_object => {....}" the values in that object will
be used instead of values provided in the field definition with
'default' or 'default_fieldname'.
If you *want* values that override the item/init_object, you can
use the field attribute 'default_over_obj'.
However you might want to consider putting your defaults into your
row or init_object instead.
default_over_obj
Allows setting defaults which will override values provided with an
item/init_object.
has_field 'quux' => ( default_over_obj => 'default quux' );
At this time there is no equivalent of 'set_default', but the type
of the attribute is not defined so you can provide default values
in a variety of other ways, including providing a trait which does
'build_default_over_obj'. For examples, see tests in the
distribution.
Constraints and Validations
Constraints set in attributes
required
Flag indicating whether this field must have a value
unique
For DB field - check for uniqueness. Action is performed by the DB
model.
messages
messages => { required => '...', unique => '...' }
Set messages created by FormHandler by setting in the 'messages'
hashref. Some field subclasses have additional settable messages.
required: Error message text added to errors if required field is
not present The default is "Field <field label> is required".
unique: message for when 'unique' is set, but field is not unique
range_start
range_end
Field values are validated against the specified range if one or
both of range_start and range_end are set and the field does not
have 'options'.
The IntRange field uses this range to create a select list with a
range of integers.
In a FormHandler field_list
age => {
type => 'Integer',
range_start => 18,
range_end => 120,
}
not_nullable
Fields that contain 'empty' values such as '' are changed to undef
in the validation process. If this flag is set, the value is not
changed to undef. If your database column requires an empty string
instead of a null value (such as a NOT NULL column), set this
attribute.
has_field 'description' => (
type => 'TextArea',
not_nullable => 1,
);
This attribute is also used when you want an empty array to stay an
empty array and not be set to undef.
apply
Use the 'apply' keyword to specify an ArrayRef of constraints and
coercions to be executed on the field at validate_field time.
has_field 'test' => (
apply => [ 'MooseType',
{ check => sub {...}, message => { } },
{ transform => sub { ... lc(shift) ... } }
],
);
In general the action can be of three types: a Moose type (which is
represented by its name), a transformation (which is a callback called
on the value of the field), or a constraint ('check') which performs a
'smart match' on the value of the field. Currently we implement the
smart match in our code - but in the future when Perl 5.10 is more
widely used we'll switch to the core
http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perlsyn.pod#Smart_matching_in_detail
<http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perlsyn.pod#Smart_matching_in_detail>
smart match operator.
The Moose type action first tries to coerce the value - then it checks
the result, so you can use it instead of both constraints and
tranformations - TIMTOWTDI. For most constraints and transformations
it is your choice as to whether you use a Moose type or use a 'check'
or 'transform'.
All three types define a message to be presented to the user in the
case of failure. Messages are passed to Locale::MakeText, and can
either be simple strings or an array suitable for MakeText, such as:
message => ['Email should be of the format [_1]',
'someuser@example.com' ]
Transformations and coercions are called in an eval to catch the
errors. Warnings are trapped in a sigwarn handler.
All the actions are called in the order that they are defined, so that
you can check constraints after transformations and vice versa. You can
weave all three types of actions in any order you need. The actions
specified with 'apply' will be stored in an 'actions' array.
To declare actions inside a field class use HTML::FormHandler::Moose
and 'apply' sugar:
package MyApp::Field::Test;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler::Field;
apply [ 'SomeConstraint', { check => ..., message => .... } ];
1;
Actions specified with apply are cumulative. Actions may be specified
in field classes and additional actions added in the 'has_field'
declaration.
In addition to being a string, Messages may be arrayrefs, for
localization, or coderefs, which will be passed a reference to the
field and the original value.
apply [ { check => ['abc'], message => \&err_message } ];
sub err_message {
my ( $value, $field ) = @_;
return $field->name . ": must .... ";
}
You can see examples of field classes with 'apply' actions in the
source for HTML::FormHandler::Field::Money and
HTML::FormHandler::Field::Email, and in t/constraints.t.
Moose types for constraints and transformations
Moose types can be used to do both constraints and transformations. If
a coercion exists it will be applied, resulting in a transformation.
You can use type constraints form MooseX::Types> libraries or defined
using Moose::Util::TypeConstraints.
A Moose type defined with Moose::Util::TypeConstraints:
subtype 'MyStr'
=> as 'Str'
=> where { /^a/ };
This is a simple constraint checking if the value string starts with
the letter 'a'.
Another Moose type:
subtype 'MyInt'
=> as 'Int';
coerce 'MyInt'
=> from 'MyStr'
=> via { return $1 if /(\d+)/ };
This type contains a coercion.
You can use them in a field like this (types defined with MooseX::Types
would not be quoted):
has_field 'some_text_to_int' => (
apply => [ 'MyStr', 'MyInt' ]
);
This will check if the field contains a string starting with 'a' - and
then coerce it to an integer by extracting the first continuous string
of digits.
If the error message returned by the Moose type is not suitable for
displaying in a form, you can define a different error message by using
the 'type' and 'message' keys in a hashref:
apply => [ { type => 'MyStr', message => 'Not a valid value' } ];
Non-Moose checks and transforms
A simple 'check' constraint uses the 'check' keyword pointing to a
coderef, a regular expression, or an array of valid values, plus a
message.
A 'check' coderef will be passed the current value of the field. It
should return true or false:
has_field 'this_num' => (
apply => [
{
check => sub { if ( $_[0] =~ /(\d+)/ ) { return $1 > 10 } },
message => 'Must contain number greater than 10',
}
]
);
A 'check' regular expression:
has_field 'some_text' => (
apply => [ { check => qr/aaa/, message => 'Must contain aaa' } ],
);
A 'check' array of valid values:
has_field 'more_text' => (
apply => [ { check => ['aaa', 'bbb'], message => 'Must be aaa or bbb' } ]
);
A simple transformation uses the 'transform' keyword and a coderef.
The coderef will be passed the current value of the field and should
return a transformed value.
has_field 'sprintf_filter' => (
apply => [ { transform => sub{ sprintf '<%.1g>', $_[0] } } ]
);
trim
An action to trim the field. By default this contains a transform to
strip beginning and trailing spaces. Set this attribute to null to
skip trimming, or supply a different transform.
trim => { transform => sub {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
} }
trim => { type => MyTypeConstraint }
Trimming is performed before any other defined actions.
deflation, deflate
A 'deflation' is a coderef that will convert from an inflated value
back to a flat data representation suitable for displaying in an HTML
field. If deflation is defined for a field it is automatically used
for data that is taken from the database.
has_field 'my_date_time' => (
type => 'Compound',
apply => [ { transform => sub{ DateTime->new( $_[0] ) } } ],
deflation => sub { { year => $_[0]->year, month => $_[0]->month, day => $_[0]->day } },
fif_from_value => 1,
);
has_field 'my_date_time.year';
has_field 'my_date_time.month';
has_field 'my_date_time.day';
You can also use a 'deflate' method in a custom field class. See the
Date field for an example. If the deflation requires data that may vary
(such as a format) string and thus needs access to 'self', you would
need to use the deflate method since the deflation coderef is only
passed the current value of the field
Normally if you have a deflation, you will need a matching inflation,
which can be supplied via a 'transform' action. When using a
'transform', the 'value' hash only contains reliably inflated values
after validation has been performed, since inflation is performed at
validation time.
Deflation can be done at two different places: transforming the value
that's saved from the initial_object/item, or when retrieving the 'fif'
(fill-in-form) value that's displayed in the HTML form. The default is
"deflate_to => 'value'". To deflate when getting the 'fif' value set
'deflate_to' to 'fif'. (See t/deflate.t for examples.)
Processing and validating the field
validate_field
This is the base class validation routine. Most users will not do
anything with this. It might be useful for method modifiers, if you
want code that executed before or after the validation process.
validate
This field method can be used in addition to or instead of 'apply'
actions in custom field classes. It should validate the field data and
set error messages on errors with "$field->add_error".
sub validate {
my $field = shift;
my $value = $field->value;
return $field->add_error( ... ) if ( ... );
}
AUTHOR
FormHandler Contributors - see HTML::FormHandler
COPYRIGHT AND LICENSE
This software is copyright (c) 2011 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.
perl v5.14.1 2011-10-08 HTML::FormHandler::Field(3)