|
|
| |
Rose::HTML::Form(3) |
User Contributed Perl Documentation |
Rose::HTML::Form(3) |
Rose::HTML::Form - HTML form base class.
package PersonForm;
use base 'Rose::HTML::Form';
use Person;
sub build_form
{
my($self) = shift;
$self->add_fields
(
name => { type => 'text', size => 25, required => 1 },
email => { type => 'email', size => 50, required => 1 },
phone => { type => 'phone' },
);
}
sub validate
{
my($self) = shift;
# Base class will validate individual fields in isolation,
# confirming that all required fields are filled in, and that
# the email address and phone number are formatted correctly.
my $ok = $self->SUPER::validate(@_);
return $ok unless($ok);
# Inter-field validation goes here
if($self->field_value('name') ne 'John Doe' &&
$self->field_value('phone') =~ /^555/)
{
$self->error('Only John Doe can have a 555 phone number.');
return 0;
}
return 1;
}
sub init_with_person # give a friendlier name to a base-class method
{
my($self, $person) = @_;
$self->init_with_object($person);
}
sub person_from_form
{
my($self) = shift;
# Base class method does most of the work
my $person = $self->object_from_form(class => 'Person');
# Now fill in the non-obvious details...
# e.g., set alt phone to be the same as the regular phone
$person->alt_phone($self->field_value('phone'));
return $person;
}
...
#
# Sample usage in a hypothetical web application
#
$form = PersonForm->new;
if(...)
{
# Get query parameters in a hash ref and pass to the form
my $params = MyWebServer->get_query_params();
$form->params($params);
# ...or initialize form params from a CGI object
# $form->params_from_cgi($cgi); # $cgi "isa" CGI
# ...or initialize params from an Apache request object
# (mod_perl 1 and 2 both supported)
# $form->params_from_apache($r);
# Initialize the fields based on params
$form->init_fields();
unless($form->validate)
{
return error_page(error => $form->error);
}
$person = $form->person_from_form; # $person is a Person object
do_something_with($person);
...
}
else
{
$person = ...; # Get or create a Person object somehow
# Initialize the form with the Person object
$form->init_with_person($person);
# Pass the initialized form object to the template
display_page(form => $form);
}
...
Rose::HTML::Form is more than just an object representation of the <form>
HTML tag. It is meant to be a base class for custom form classes that can be
initialized with and return "rich" values such as objects, or
collections of objects.
Building up a reusable library of form classes is extremely
helpful when building large web applications with forms that may appear in
many different places. Similar forms can inherit from a common subclass, and
forms may be nested.
This class inherits from, and follows the conventions of,
Rose::HTML::Object. Inherited methods that are not overridden will not be
documented a second time here. See the Rose::HTML::Object documentation for
more information.
Rose::HTML::Form objects are meant to encapsulate an entire HTML form, including
all fields within the form. While individual fields may be queried and
manipulated, the intended purpose of this class is to treat the form as a
"black box" as much as possible.
For example, instead of asking a form object for the values of the
"name", "email", and "phone" fields, the user
would ask the form object to return a new "Person" object that
encapsulates those values.
Form objects should also accept initialization through the same
kinds of objects that they return. Subclasses are encouraged to create
methods such as (to use the example described above)
"init_with_person()" and
"person_from_form()" in order to do this.
The generic methods init_with_object() and object_from_form()
are meant to ease the implementation of such custom methods.
Form objects can also take input through a hash. Each hash key
correspond to a field (or subfield) name, and each value is either a scalar
or a reference to an array of scalars (for multiple-value fields). This hash
of parameters can be queried and manipulated before finally calling
init_fields() in order to initialize the fields based on the current
state of the parameters.
Compound fields (fields consisting of more than one HTML field,
such as a month/day/year date field with separate text fields for each
element of the date) may be "addressed" by hash arguments using
both top-level names (e.g., "birthday") or by subfield names
(e.g., "birthday.month", "birthday.day",
"birthday.year"). If the top-level name exists in the hash, then
subfield names are ignored. See Rose::HTML::Form::Field::Compound for more
information on compound fields.
Each form has a list of field objects. Each field object is stored
under a name, which may or may not be the same as the field name, which may
or may not be the same as the "name" HTML attribute for any of the
HTML tags that make up that field.
Forms are validated by calling validate() on each field
object. If any individual field does not validate, then the form is invalid.
Inter-field validation is the responsibility of the form object.
Though Rose::HTML::Form objects may have children just like any other
Rose::HTML::Object-derived object, the fields that make up the form are
treated like "immutable children" in that they can never be removed
using the standard child-related APIs. Instead, the fields exist in the middle
of any other children.
Pushing a child adds it after the list of fields. Unshifting a
child adds it before the list of fields. Popping or shifting children will
pull children through, past the fields, to exit the list of children at
either end. In other words, children manipulated using the child object APIs
will "flow around" the list of fields.
If a particular field is a group of sibling HTML elements with no
real parent HTML element (e.g., a radio button group), then the individual
sibling items will be flattened out into the list returned by the children
method.
If, on the other hand, a field has a true parent/child
relationship (e.g., a select box which contains zero or more options) then
the items it contains are not flattened by the children method.
For example, if a form has three fields, a text field, a checkbox
group with three checkboxes, and a select box with three options, then the
children method will return five objects: the text field object, the three
checkboxes objects, and a select box object.
See the hierarchy section of the Rose::HTML::Form::Field
documentation for more information about how fields made up of multiple HTML
tags are treated with respect to parent/child relationships.
Finally, note that nested forms do not affect the parent/child
hierarchy presented by the child-related methods inherited from
Rose::HTML::Object since the fields contained in nested forms are flattened
out into the field list of parent form, as described in the next
section.
Each form can have zero or more fields as well as zero or more sub-forms. Since
<form> HTML tags cannot be nested, this nesting of form objects appears
"flattened" in the external interfaces such as HTML generation or
field addressing.
Here's a simple example of a nested form made up of a
"PersonForm" and an
"AddressForm". (Assume
"PersonForm" is constructed as per the
synopsis above, and "AddressForm" is
similar, with street, city, state, and zip code fields.)
package PersonAddressForm;
use PersonForm;
use AddressForm;
sub build_form
{
my($self) = shift;
$self->add_forms
(
person => PersonForm->new,
address => AddressForm->new,
);
}
Each sub-form is given a name. Sub-field addressing incorporates
that name in much the same way as compound field addressing, with dots
(".") used to delimit the hierarchy. Here are two different ways
to get at the person's email field.
$form = PersonAddressForm->new;
# These are equivalent
$email_field = $form->field('person.email');
$email_field = $form->form('person')->field('email');
Methods on the sub-forms maybe accessed in a similar manner.
$person = $form->form('person')->person_from_form();
By default, methods are delegated to sub-forms automatically, so
this works too.
$person = $form->person_from_form();
(See the delegate_to_subforms() method to learn how to
alter this behavior.)
Nested forms may have their own fields as well, and the nesting
may continue to an arbitrary depth. Here's a form that contains a
"PersonAddressForm" as well as two fields
of its own.
package PersonAddressPetsForm;
use PersonAddressForm;
sub build_form
{
my($self) = shift;
$self->add_form(pa => PersonAddressForm->new);
$self->add_fields
(
dog => { type => 'text', size => 30 },
cat => { type => 'text', size => 30 },
);
}
Sub-form and field addressing works as expected. Here are several
equivalent ways to get at the person's email field.
$form = PersonAddressPetsForm->new;
# These are all equivalent
$email_field = $form->field('pa.person.email');
$email_field = $form->form('pa.person')->field('email');
$email_field = $form->form('pa')->form('person')->field('email');
Sub-form method calls and delegation also works as expected.
# Call method on the PersonForm, two different ways
$person = $form->form('pa')->form('person')->person_from_form();
$person = $form->form('pa.person')->person_from_form();
# Rely on delegation instead
$person = $form->form('pa')->person_from_form();
$person = $form->person_from_form();
Nested forms are a great way to build on top of past work. When
combined with traditional subclassing, form generation can be entirely
cleansed of duplicated code.
Valid attributes:
accept
accept-charset
accesskey
action
class
dir
enctype
id
lang
method
name
onblur
onclick
ondblclick
onfocus
onkeydown
onkeypress
onkeyup
onmousedown
onmousemove
onmouseout
onmouseover
onmouseup
onreset
onsubmit
style
tabindex
target
title
value
xml:lang
Required attributes (default values in parentheses):
action
enctype (application/x-www-form-urlencoded)
method (get)
- default_recursive_init_fields [BOOL]
- Get or set a boolean value that determines the default value of the
recursive_init_fields object attribute. The default value is false.
- delegate_to_subforms [SETTING]
- Get or set the value that determines how (or if) forms of this class
delegate unresolved method calls to sub-forms. If a method is called on a
form of this class, and that method does not exist in this class or any
other class in its inheritance hierarchy, then the method may optionally
be delegated to a sub-forms. Valid values for SETTING are:
- "0"
- A value of "0" (or undef or any other false value) means that no
sub-form delegation will be attempted.
- "1"
- A value of "1" means the same thing as a value of
"runtime" (see below).
- "compile"
- For each unresolved method call, each sub-form is is considered in the
order that they are returned from the forms method until one is found that
can handle this method. If one is found, then a new proxy method is added
to this class that calls the requested method on the sub-form, passing all
arguments unmodified. That proxy method is then called.
Subsequent invocations of this method will no longer trigger
the search process. Instead, they will be handled by the newly-compiled
proxy method. This is more efficient than repeating the sub-form search
each time, but it also means that a change in the list of sub-forms
could render the newly compiled method useless (e.g., if the sub-form it
delegates to is removed).
If no sub-form can handle the method, then a fatal
"unknown method" error occurs.
- "runtime"
- For each unresolved method call, each sub-form is is considered in the
order that they are returned from the forms method until one is found that
can handle this method. If one is found, then the method is called on that
sub-form, passing all arguments unmodified.
Subsequent invocations of this method will trigger the same
search process, again looking for a a sub-form that can handle it. This
is less efficient than compiling a new proxy method as described in the
documentation for the "compile" setting above, but it does
mean that any changes in the list of sub-forms will be handled
correctly.
If no sub-form can handle the method, then a fatal
"unknown method" error occurs.
The default value for SETTING is compile. See the nested
forms section for some examples of sub-form delegation.
- default_trim_xy_params [BOOL]
- Get or set a boolean value that is used as the default value of the
trim_xy_params object attribute. The default value is true.
- new PARAMS
- Constructs a new Rose::HTML::Form object based on PARAMS, where PARAMS are
name/value pairs. Any object method is a valid parameter name.
- add_field ARGS
- Convenience alias for add_fields().
- add_fields ARGS
- Add the fields specified by ARGS to the list of fields contained in this
form. ARGS may be a list or a reference to an array. Valid formats for
elements of ARGS are:
- Field objects
- If an argument is "isa" Rose::HTML::Form::Field, then it is
added to the list of fields, stored under the name returned by the field's
name method.
- Field name/type pairs
- A pair of simple scalars is taken as a field name and type. The class that
corresponds to the specified field type is determined by calling the
field_type_class method. Then a new object of that class is constructed
and added to the form.
- Field name/hashref pairs
- A simple scalar followed by a reference to a hash it taken as a field name
and a collection of object attributes. The referenced hash must contain a
value for the "type" key. The field
class that corresponds to the specified field type is determined by
calling the field_type_class method. Then a new object of that class is
constructed, with the remaining key/value pairs in the hash are passed to
the constructor. The completed field object is then added to the
form.
- Field name/object pairs
- A simple scalar followed by an object that "isa"
Rose::HTML::Form::Field is stored as-is, under the specified name.
Each field's parent_form is set to the form object. If the field's
rank is undefined, it's set to the value of the form's field_rank_counter
attribute and the rank counter is incremented.
Adding a field with the same name as an existing sub-form will
cause a fatal error.
Examples:
# Name/hashref pairs
$form->add_fields(name => { type => 'text', size => 20 },
email => { type => 'email', size => 30 });
# Name/type pairs
$form->add_fields(name => 'text',
email => 'email');
$name_field =
Rose::HTML::Form::Field::Text->new(name => 'name',
size => 25);
$email_field =
Rose::HTML::Form::Field::Text->new(name => 'email',
size => 50);
# Object arguments
$form->add_fields($name_field, $email_field);
# Name/object pairs
$form->add_fields(name => $name_field,
email => $email_field);
# Mixed
$form->add_fields($name_field,
email => $email_field,
nick => { type => 'text', size => 15 },
age => 'text');
- add_field_type_classes [MAP]
- Add entries to the field_type_classes hash that maps field type strings to
the names of the Rose::HTML::Form::Field-derived classes. Example:
My::HTML::Form->add_field_type_classes
(
nick => 'My::HTML::Form::Field::Nickname',
age => 'My::HTML::Form::Field::Age',
...
);
This method is an alias for the add_object_type_classes method
inherited from Rose::HTML::Object. It is an inherited hash representing
the union of the hashes of all superclasses, minus any keys that are
explicitly deleted in the current class.
- add_form ARGS
- This is an alias for the add_forms() method.
- add_forms ARGS
- Add the forms specified by ARGS to the list of sub-forms contained in this
form. See the nested forms section for more information.
Valid formats for elements of ARGS are:
- Form objects
- If an argument is "isa" Rose::HTML::Form, then it is added to
the list of forms, stored under the name returned by the form's form_name
method. Example:
$a_form = Rose::HTML::Form->new(...);
$b_form = Rose::HTML::Form->new(...);
# Object arguments
$form->add_forms($a_form, $b_form);
- Form name/object pairs
- A simple scalar followed by an object that "isa"
Rose::HTML::Form has its form_name set to the specified name and then is
stored under that name.
If the name contains any dots (".") it will be taken
as a hierarchical name and the form will be added to the specified
sub-form under an unqualified name consisting of the final part of the
name.
Examples:
$a_form = Rose::HTML::Form->new(...);
$b_form = Rose::HTML::Form->new(...);
# Name/object pairs
$form->add_forms(a => $a_form, b => $b_form);
# Mixed
$form->add_forms($a_form, b => $b_form);
# Set nested form from the top-level
$w_form = Rose::HTML::Form->new(...);
$x_form = Rose::HTML::Form->new(...);
$y_form = Rose::HTML::Form->new(...);
$z_form = Rose::HTML::Form->new(...);
$w_form->add_form('x' => $x_form);
$x_form->add_form('y' => $y_form);
# Add $z_form to $w_form->form('x')->form('y') under the name 'z'
$w_form->add_form('x.y.z' => $z_form);
- Form name/hashref pairs
- A simple scalar followed by a reference to a hash containing a
specification for a form. Currently, the only kind of form that can be
specified this way is a repeatable form, in which case the hash reference
is known as a "repeat spec". In order to be correctly detected
as a repeat spec, the hash must contain a key named
"repeatable".
The repeat spec is coerced into a set of name/value pairs that
are passed to the Rose::HTML::Form::Repeatable constructor call. The
coercion exists to allow shorter, more friendly names to be used in the
context of a repeat spec. These names are converted into the names of
valid Rose::HTML::Form::Repeatable object methods. The following
coercion rules are applied to the repeat spec hash reference:
- If the value of the "repeatable" key is
reference to a hash, the keys and values of that hash are folded into the
repeat spec. Otherwise, if a key named
"default_count" does not exist in the
repeat spec, then the value of the
"repeatable" key is used as the value of
the default_count parameter.
- The "spec" and
"form_spec" parameters are aliases for
the prototype_form_spec parameter.
- The "class" and
"form_class" parameters are aliases for
the prototype_form_class parameter.
- The "form" parameter is an alias for the
prototype_form parameter.
Here are some example name/hashref pairs suitable for passing as
arguments to the add_forms method:
# Using a form class name
emails =>
{
form_class => 'EmailForm',
repeatable => 3, # Default count is 3.
}
# Using a form class name and form spec
emails =>
{
form_class => 'EmailForm',
form_spec => { empty_is_ok => 1 },
repeatable => 3, # Default count is 3.
}
# Using a generic form class and form spec to specify the
# contents of a repeated form "inline" in the repeat spec
nicknames =>
{
form_class => 'My::HTML::Form',
form_spec => { fields => [ nick => { type => 'text' } ] },
repeatable => 3, # Default count is 3.
}
# Using a prototype object
nicknames =>
{
form => NickNameForm->new,
default_count => 0, # Explicitly set default count to 0.
repeatable => 1, # This key must be present even though
# the default count is set above.
}
Each form's parent_form is set to the form object it was added
to.
Adding a form with the same name as an existing field will cause a
fatal error.
- add_param_value NAME, VALUE
- Add VALUE to the parameter named NAME. Example:
$form->param(a => 1);
print $form->param('a'); # 1
$form->add_param_value(a => 2);
print join(',', $form->param('a')); # 1,2
- app [OBJECT]
- Get or set a weakened reference to the application object that
"owns" this form.
- add_repeatable_form ARGS
- This method is an alias for the add_repeatable_forms() method.
- add_repeatable_forms ARGS
- Add the repeatable forms specified by ARGS to the list of sub-forms
contained in this form. This method takes arguments in the same format as
the add_forms method, except that all argument types are coerced into a
form that will cause add_forms to recognize it as a repeatable form. This
is a convenient way to add repeatable forms without having to include the
"repeatable" key in your repeat spec.
(See the documentation for the add_forms method for more information.)
Examples
$form->add_repeatable_forms
(
# Object argument
EmailForm->new(...),
# Name/object pair
colors => ColorForm->new(...),
# Name/hashref pair. (Note: no "repeatable" key needed)
nicknames =>
{
form => NickNameForm->new,
default_count => 2,
},
);
- build_on_init [BOOL]
- Get or set a boolean flag that indicates whether or not
build_form() should be called from within the init() method.
See build_form() for more information.
- build_form
- This default implementation of this method is a no-op. It is meant to be
overridden by subclasses. It is called at the end of the init()
method if build_on_init() is true. (Remember that this class
inherits from Rose::HTML::Object, which inherits from Rose::Object, which
defines the init() method, which is called from the constructor.
See the Rose::Object documentation for more information.)
If build_on_init() is false, then you must remember to
call build_form() manually.
Subclasses should populate the field list in their overridden
versions of build_form(). Example:
sub build_form
{
my($self) = shift;
$self->add_fields
(
name => { type => 'text', size => 25, required => 1 },
email => { type => 'email', size => 50, required => 1 },
phone => { type => 'phone' },
);
}
- clear
- Call clear() on each field object and set error() to
undef.
- clear_fields
- Call clear() on each field object.
- coalesce_hidden_fields [BOOL]
- Get or set the boolean flag that controls how compound field values are
encoded in hidden fields. If this flag is true, then each compound field
is encoded as a single hidden field. If the flag is false (the default),
then each subfield of a compound field will have its own hidden
field.
- coalesce_query_string_params [BOOL]
- Get or set the boolean flag that controls how compound field values are
encoded in the query string. If this flag is true (the default), then
compound fields are represented by a single query parameter. Otherwise,
the subfields of each compound field appear as separate query
parameters.
- compare_fields [FIELD1, FIELD2]
- Compare two fields, returning 1 if FIELD1 should come before FIELD2, -1 if
FIELD2 should come before FIELD1, or 0 if neither field should come before
the other. This method is called from within the field_names method to
determine the order of the fields in this form.
The default implementation performs a string comparison on the
names of the fields.
- compare_forms [FORM1, FORM2]
- Compare two forms, returning 1 if FORM1 should come before FORM2, -1 if
FORM2 should come before FORM1, or 0 if neither form should come before
the other. This method is called from within the form_names and
field_monikers methods to determine the order of the sub-forms nested
within this form.
The default implementation compares the rank of the forms in
numeric context.
- delete_field NAME
- Delete the form stored under the name NAME. If NAME "isa"
Rose::HTML::Form::Field, then the name method is called on it and the
return value is used as NAME.
- delete_fields
- Delete all fields, leaving the list of fields empty. The
field_rank_counter is also reset to 1.
- delete_field_type_class TYPE
- Delete the type/class mapping entry for the field type TYPE.
- delete_form NAME
- Delete the form stored under the name NAME. If NAME "isa"
Rose::HTML::Form, then the form_name method is called on it and the return
value is used as NAME.
- delete_forms
- Delete all sub-forms, leaving the list of sub-forms empty.
- delete_param NAME [, VALUES]
- If just the NAME argument is passed, the parameter named NAME is deleted.
If VALUES are also passed, then VALUES are deleted from the
set of values held by the parameter name NAME. If only one value
remains, then it is the new value for the NAME parameter (i.e., the
value is no longer an array reference, but a scalar instead). If every
value is deleted, then the NAME parameter is deleted as well.
Example:
$form->param(a => [ 1, 2, 3, 4 ]);
$form->delete_param(a => 1);
$vals = $form->param('a'); # [ 2, 3, 4 ]
$form->delete_param(a => [ 2, 3 ]);
$vals = $form->param('a'); # 4
$form->delete_param(a => 4);
$vals = $form->param('a'); # undef
$form->param_exists('a'); # false
- delete_params
- Delete all parameters.
- delete_repeatable_form NAME
- Delete the repeatable form stored under the name NAME. If NAME
"isa" Rose::HTML::Form, then the form_name method is called on
it and the return value is used as NAME.
- delete_repeatable_forms
- Delete all repeatable sub-forms.
- empty_is_ok [BOOL]
- Get or set a boolean value that indicates whether or not validate will be
allowed to return true if every field in the form is empty, even if some
of them are required. The default value is false.
- end_html
- Returns the HTML required to end the form.
- end_xhtml
- Returns the XHTML required to end the form.
- end_multipart_html
- Returns the HTML required to end a multipart form.
- end_multipart_xhtml
- Returns the XHTML required to end a multipart form.
- field NAME [, VALUE]
- Get or set the field specified by NAME. If only a NAME argument is passed,
then the field stored under the name NAME is returned. If no field exists
under that name exists, then undef is returned.
If both NAME and VALUE arguments are passed, then the VALUE
must be a Rose::HTML::Form::Field or a reference to a hash whose
contents are as described in the documentation for the add_fields
method.
- fields [FIELDS]
- If FIELDS are passed, this method deletes all existing fields and then
calls add_fields, passing all arguments.
The return value is an ordered list of this form's field
objects in list context, or a reference to this list in scalar context.
The order of the fields matches the order of the field names returned by
the field_monikers method.
- fields_depth_first
- Returns a list (in list context) or reference to an array (in scalar
context) of this form's field objects ordered according to a depth-first
traversal of all sub-forms. Fields within a given form are ordered by
rank, and all fields at a given level precede any sub-forms nested under
that level.
- field_monikers
- Returns an ordered list of field monikers in list context, or a reference
to this list in scalar context. A "moniker" is a fully qualified
name, including any sub-form or sub-field prefixes (e.g.,
"pa.person.email" as seen in the nested forms section above).
The order is determined by the compare_forms and
compare_fields methods. The compare_forms method is passed the parent
form of each field. If it returns a true value, then that value is used
to sort the two fields being compared. If it returns false, then the
compare_fields method is called with the two field objects as arguments
and its return value is used to determine the order. See the
documentation for the compare_forms and compare_fields methods for more
information.
- field_names
- This method simply calls field_monikers.
- field_rank_counter [INT]
- Get or set the value of the counter used to set the rank of fields as
they're added to the form. The counter starts at 1 by default.
- field_type_class TYPE [, CLASS]
- Given the field type string TYPE, return the name of the
Rose::HTML::Object-derived class mapped to that name. If a CLASS is
passed, the field type TYPE is mapped to CLASS.
This method is an alias for the object_type_class method
inherited from Rose::HTML::Object. It is an inherited hash representing
the union of the hashes of all superclasses, minus any keys that are
explicitly deleted in the current class.
- field_type_classes [MAP]
- Get or set the hash that maps object type strings to the names of the
Rose::HTML::Object-derived classes. This map
If passed MAP (a list of type/class pairs or a reference to a
hash of the same) then MAP replaces the current field type mapping.
Returns a list of type/class pairs (in list context) or a reference to a
hash of type/class mappings (in scalar context).
This method is an alias for the object_type_classes method
inherited from Rose::HTML::Object. It is an inherited hash representing
the union of the hashes of all superclasses, minus any keys that are
explicitly deleted in the current class.
The default mapping of type names to classes is shown in the
Rose::HTML::Object documentation.
- field_value NAME [, VALUE]
- If passed NAME and VALUE arguments, then the input_value of the field
named NAME is set to VALUE. If passed only a NAME, then the internal_value
of the field named NAME is returned. In other words, this:
$form->field_value(zip_code => '11787');
is equivalent to this:
$form->field('zip_code')->input_value('11787');
and this:
$val = $form->field_value('zip_code');
is equivalent to this:
$val = $form->field('zip_code')->internal_value;
If no field named NAME exists, a fatal error will occur.
- form NAME [, OBJECT]
- Get or set the sub-form named NAME. If just NAME is passed, the specified
sub-form object is returned. If no such sub-form exists, undef is
returnend.
If both NAME and OBJECT are passed, a new sub-form is added
under NAME.
NAME is a fully-qualified sub-form name. Components of the
hierarchy are separated by dots ("."). OBJECT must be an
object that inherits from Rose::HTML::Form.
- forms [FORMS]
- If FORMS are passed, this method deletes all existing forms and then calls
add_forms, passing all arguments.
The return value is an ordered list of this form's sub-form
objects (if any) in list context, or a reference to this list in scalar
context. The order of the forms matches the order of the form names
returned by the form_names method.
See the nested forms section to learn more about nested
forms.
- form_name [NAME]
- Get or set the name of this form. This name may or may not have any
connection with the value of the "name" HTML attribute on the
<form> tag. See the documentation for the name method for
details.
- form_names
- Returns an ordered list of form names in list context, or a reference to
this list in scalar context. The order is determined by the compare_forms
method. Note that this only lists the forms that are direct children of
the current form. Forms that are nested more than one level deep are not
listed.
- form_rank_counter [INT]
- This method is deprecated and will be removed in a future release.
- hidden_fields
- Returns one or more Rose::HTML::Form::Field::Hidden objects that represent
the hidden fields needed to encode all of the field values in this form.
If coalesce_hidden_fields() is true, then each compound
field is encoded as a single hidden field. Otherwise, each subfield of a
compound field will be have its own hidden field.
- html_hidden_fields
- Returns the HTML serialization of the fields returned by
hidden_fields(), joined by newlines.
- init_fields [PARAMS]
- Initialize the fields based on params(). In general, this works as
you'd expect, but the details are a bit complicated.
The intention of init_fields() is to set field values
based solely and entirely on params(). That means that default
values for fields should not be considered unless they are explicitly
part of params().
In general, default values for fields exist for the purpose of
displaying the HTML form with certain items pre-selected or filled in.
In a typical usage scenario, those default values will end up in the web
browser form submission and, eventually, as as an explicit part of part
params(), so they are not really ignored.
But to preserve the intended functionality of
init_fields(), the first thing this method does is clear()
the form. (This is the default. See the
"no_clear" parameter below.)
If a parameter name exactly matches a field's name (note: the
field's name, which is not necessarily the the same as the name that the
field is stored under in the form), then the (list context) value of
that parameter is passed as the input_value() for that field.
If a field "isa" Rose::HTML::Form::Field::Compound,
and if no parameter exactly matches the name of the compound field, then
each subfield may be initialized by a parameter name that matches the
subfield's name.
If a field is an "on/off" type of field (e.g., a
radio button or checkbox), then the field is turned "on" only
if the value of the parameter that matches the field's name exactly
matches (string comparison) the "value" HTML attribute of the
field. If not, and if params_exist(), then the field is set to
"off". Otherwise, the field is not modified at all.
PARAMS are name/value pairs. Valid parameters are:
- no_clear BOOL
- If true, the form is not clear()ed before it is initialized.
- recursive BOOL
- If true, this method is called recursively on any nested sub-forms. If
false, the fields in all nested sub-forms are still initialized as
expected, but this is done by iterating over the "flattened"
fields list rather than through recursion.
If this parameter is not passed, its value defaults to the
value of the recursive_init_fields object attribute.
Examples:
package RegistrationForm;
...
sub build_form
{
my($self) = shift;
$self->add_fields
(
name => { type => 'text', size => 25 },
gender =>
{
type => 'radio group',
choices => { 'm' => 'Male', 'f' => 'Female' },
default => 'm'
},
hobbies =>
{
type => 'checkbox group',
name => 'hobbies',
choices => [ 'Chess', 'Checkers', 'Knitting' ],
default => 'Chess'
},
bday = => { type => 'date split mdy' }
);
}
...
$form = RegistrationForm->new();
$form->params(name => 'John',
gender => 'm',
hobbies => undef,
bday => '1/24/1984');
# John, Male, no hobbies, 1/24/1984
$form->init_fields;
$form->reset;
$form->params(name => 'John',
bday => '1/24/1984');
# No name, Male, Chess, 1/24/1984
$form->init_fields(no_clear => 1);
$form->reset;
# Set using subfield names for "bday" compound field
$form->params('name' => 'John',
'bday.month' => 1,
'bday.day' => 24,
'bday.year' => 1984);
# John, Male, no hobbies, 1/24/1984
$form->init_fields();
$form->reset;
$form->params('bday' => '1/24/1984',
'bday.month' => 12,
'bday.day' => 25,
'bday.year' => 1975);
# No name, no gender, no hobbies, but 1/24/1984 because
# the "bday" param trumps any and all subfield params.
$form->init_fields();
$form->reset;
# Explicitly set hobbies field to Knitting...
$form->field('hobbies')->input_value('Knitting');
# ...but then provide a hobbies param with no value
$form->params('hobbies' => undef);
# Fields are not cleared, but the existence of the hobbies
# param with an empty value causes the hobbies list to be
# empty, instead of the default Chess. Thus:
#
# No name, Male, no hobbies, no birthday
$form->init_fields(no_clear => 1);
- init_fields_with_cgi CGI [, ARGS]
- This method is a shortcut for initializing the form's params with a CGI
object and then calling init_fields. The CGI argument is passed to the
params_from_cgi method and ARGS are passed to the init_fields method.
For example, this:
$form->init_fields_with_cgi($cgi, no_clear => 1);
Is equivalent to this:
$form->params_from_cgi($cgi);
$form->init_fields(no_clear => 1);
See the documentation for the params_from_cgi and init_fields
methods for more information.
- init_fields_with_apache APR [, ARGS]
- This method is a shortcut for initializing the form's params with an
apache request object and then calling init_fields. The APR argument is
passed to the params_from_apache method and ARGS are passed to the
init_fields method.
For example, this:
$form->init_fields_with_apache($r, no_clear => 1);
Is equivalent to this:
$form->params_from_apache($r);
$form->init_fields(no_clear => 1);
See the documentation for the params_from_apache and
init_fields methods for more information.
- init_with_object OBJECT
- Initialize the form based on OBJECT. First, the form is clear()ed.
Next, for each field name(), if the object has a method with the
same name, then the return value of that method (called in scalar context)
is passed as the input_value() for the form field of the same name.
The actual code for the init_with_object() method may
be more clear than the description above. Essentially, it does this:
sub init_with_object
{
my($self, $object) = @_;
$self->clear();
foreach my $field ($self->fields)
{
my $name = $field->local_name;
if($object->can($name))
{
$field->input_value(scalar $object->$name());
}
}
}
Use this method as a "helper" when writing your own
methods such as "init_with_person()",
as described in the example in the overview. init_with_object()
should be called in the code for subclasses of Rose::HTML::Form, but
never by an end-user of such classes.
The convention for naming such methods is
"init_with_foo", where "foo" is a (lowercase,
underscore-separated, please) description of the object (or objects)
used to initialize the form. You are free to accept and handle any kind
or number of arguments in your "init_with_foo()"-style
methods (all which you'll carefully document, of course).
The field names may not match up exactly with the object
method names. In such cases, you can use init_with_object() to
handle all the fields that do match up with method names, and then
handle the others manually. Example:
sub init_with_person
{
my($self, $person) = @_;
# Handle field names that match method names
$self->init_with_object($person);
# Manually set the non-matching or other fields
$self->field('phone2')->input_value($person->alt_phone);
$self->field('is_new')->input_value(1);
...
}
- is_empty
- Returns true if each field and nested form in this form is_empty(),
false otherwise.
- is_repeatable
- Returns true if this form is a repeatable form, false otherwise.
- local_field NAME [, VALUE]
- Get or set a field that is an immediate child of the current form. That
is, it does not belong to a nested form. If the field specified by NAME
does not meet these criteria, then undef is returned. In all other
respects, this method behaves like the field method.
Note that NAME should be the name as seen from the perspective
of the form object upon which this method is called. So a nested form
can always address its local fields using their "short"
(unqualified) names even if the form is actually nested within another
form.
- local_fields
- Returns a list of fields that are immediate children of the current form
(i.e., fields that do not belong to a nested form).
- local_form NAME [, OBJECT]
- Get or set a form that is an immediate child of the current form. That is,
it does not belong to a nested form. If the form specified by NAME does
not meet these criteria, then undef is returned. In all other respects,
this method behaves like the form method.
Note that NAME should be the name as seen from the perspective
of the form object upon which this method is called. So a nested form
can always address its local sub-forms using their "short"
(unqualified) names even if the parent form itself is actually nested
within another form.
- name [NAME]
- If passed a NAME argument, then the "name" HTML attribute is set
to NAME.
If called without any arguments, and if the "name"
HTML attribute is empty, then the "name" HTML attribute is set
to the form_name.
Returns the value of the "name" HTML attribute.
- object_from_form OBJECT | CLASS | PARAMS
- Returns an object built based on the contents of the form.
For each field name(), if the object has a method with
the same name, then the internal_value() of the field is passed
to the object method of that name. The actual code is almost as simple
as this:
foreach my $field ($self->fields)
{
my $name = $field->local_name;
if($object->can($name))
{
$object->$name($field->internal_value);
}
}
The only wrinkle is the case where a sub-form and a parent
form have fields with the same local_name. In that case, the field
"closer" to the "root" form (in terms of the
parent/child relationship tree) takes precedence. For example, consider
the following fields:
name
vendor.name
vendor.country.name
The local_name for all of these fields is
"name", but object_from_form will pass
the value of the "name" field to the
"name()" method of the object. See the
nested forms section of the documentation for more information on nested
forms.
In order to return an object based on a form, object_from_form
needs an object. If passed an OBJECT argument, then that's the object
that's used. If passed a CLASS name, then a new object is constructed by
calling new() on that class. OBJECT or CLASS may alternately be
passed as a name/value pair in PARAMS.
Use this method as a "helper" when writing your own
methods such as "person_from_form()",
as described in the example in the overview. object_from_form()
should be called in the code for subclasses of Rose::HTML::Form, but
never by an end-user of such classes.
The convention for naming such methods is
"foo_from_form", where "foo" is a (lowercase,
underscore-separated, please) description of the object constructed
based on the values in the form's fields.
The field names may not match up exactly with the object
method names. In such cases, you can use object_from_form() to
handle all the fields that do match up with method names, and then
handle the others manually. Example:
sub person_from_form
{
my($self) = shift;
my $person = $self->object_from_form(class => 'Person');
$person->alt_phone($self->field('phone2')->internal_value);
...
return $person;
}
It is the caller's responsibility to ensure that the object
class ("Person" in the example above)
is loaded prior to calling this method.
- param NAME [, VALUE]
- Get or set the value of a named parameter. If just NAME is passed, then
the value of the parameter of that name is returned. If VALUE is also
passed, then the parameter value is set and then returned.
If a parameter has multiple values, the values are returned as
a reference to an array in scalar context, or as a list in list context.
Multiple values are set by passing a VALUE that is a reference to an
array of scalars.
Failure to pass at least a NAME argument results in a fatal
error.
- params [PARAMS]
- Get or set all parameters at once.
PARAMS can be a reference to a hash or a list of name/value
pairs. If a parameter has multiple values, those values should be
provided in the form of a reference to an array of scalar values. If the
list of name/value pairs has an odd number of items, a fatal error
occurs.
If PARAMS is a reference to a hash, then it is accepted as-is.
That is, no copying of values is done; the actual hash references is
stored. If PARAMS is a list of name/value pairs, then a deep copy is
made during assignment.
Regardless of the arguments, this method returns the complete
set of parameters in the form of a hash (in list context) or a reference
to a hash (in scalar context).
In scalar context, the hash reference returned is a reference
to the actual hash used to store parameter names and values in the
object. It should be treated as read-only.
The hash returned in list context is a deep copy of the actual
hash used to store parameter names and values in the object. It may be
treated as read/write.
- params_exist
- Returns true if any parameters exist, false otherwise.
- param_exists NAME
- Returns true if a parameter named NAME exists, false otherwise.
- param_exists_for_field [ NAME | FIELD ]
- Returns true if a param exists that addresses the field named NAME or the
Rose::HTML::Form::Field-derived object FIELD, false otherwise.
This method is useful for determining if any query parameters
exist that address a compound field. For example, a compound field named
"a.b.c.d" could be addressed by any
one of the following query parameters:
"a",
"a.b",
"a.b.c", or
"a.b.c.d". This method also works with
fields inside sub-form. Examples:
$form = Rose::HTML::Form->new;
$form->add_field(when => { type => 'datetime split mdyhms' });
$form->params({ 'when.date' => '2004-01-02' });
$form->param_exists_for_field('when'); # true
$form->param_exists_for_field('when.date'); # true
$form->param_exists_for_field('when.date.month'); # true
$form->param_exists_for_field('when.time.hour'); # false
$subform = Rose::HTML::Form->new;
$subform->add_field(subwhen => { type => 'datetime split mdyhms' });
$form->add_form(subform => $subform);
$form->params({ 'subform.subwhen.date' => '2004-01-02' });
$form->param_exists_for_field('subform.subwhen'); # true
$form->param_exists_for_field('subform.subwhen.date'); # true
$form->param_exists_for_field('subform.subwhen.date.month'); # true
$form->param_exists_for_field('subform.subwhen.time.hour'); # false
$form->param_exists_for_field('when'); # false
$form->param_exists_for_field('when.date'); # false
$form->param_exists_for_field('when.date.month'); # false
$form->param_exists_for_field('when.time.hour'); # false
- params_from_apache APR
- Set params by extracting parameter names and values from an apache request
object. Calling this method entirely replaces the previous params.
If running under mod_perl 1.x, the APR argument may be:
- An Apache object. In this case, the Apache::Request module must also be
installed.
- An Apache::Request object.
If running under mod_perl 2.x, the APR may be:
- An Apache2::RequestRec object. In this case, the Apache2::Request module
must also be installed.
- An Apache2::Request object.
In all cases, APR may be an object that has a
"param()" method that behaves in the
following way:
- When called in list context with no arguments, it returns a list of
parameter names.
- When called in list context with a single parameter name argument, it
returns a list of values for that parameter.
- params_from_cgi CGI
- Set params by extracting parameter names and values from a CGI object.
Calling this method entirely replaces the previous params. The CGI
argument must be either a CGI object or must have a
"param()" method that behaves in the
following way:
- When called in list context with no arguments, it returns a list of
parameter names.
- When called in list context with a single parameter name argument, it
returns a list of values for that parameter.
- param_value_exists NAME, VALUE
- Determines if a parameter of a particular name exists and has a particular
value. This method returns true if the parameter named NAME exists and
also has a value that is equal to (string comparison) VALUE. Otherwise, it
returns false.
A fatal error occurs unless both NAME and VALUE arguments are
passed.
- parent_form [FORM]
- Get or set the parent form, if any. The reference to the parent form is
"weakened" using Scalar::Util::weaken() in order to avoid
memory leaks caused by circular references.
- prepare [PARAMS]
- Prepare the form by calling the prepare method on each field, passing all
arguments. This same method is also called for each sub-form, passing all
arguments plus the "form_only" parameter
with a true value.
PARAMS are name/value pairs. Valid parameters are:
- form_only BOOL
- If true, the prepare method is not called for each field.
- query_string
- Returns a URI-escaped (but not HTML-escaped) query string that
corresponds to the current state of the form. If
coalesce_query_string_params() is true (which is the default), then
compound fields are represented by a single query parameter. Otherwise,
the subfields of each compound field appear as separate query
parameters.
- rank [INT]
- Get or set the form's rank. This value can be used for any purpose that
suits you, but by default it's used by the compare_forms method to sort
sub-forms.
- recursive_init_fields [BOOL]
- Get or set a boolean value indicating the default value of the
<recursive> parameter to the init_fields method. This attribute, in
turn, defaults to the value returned by the default_recursive_init_fields
class method.
- repeatable_form NAME [, OBJECT]
- Get or set the repeatable sub-form named NAME. If just NAME is passed, the
specified repeatable sub-form object is returned. If no such repeatable
sub-form exists, undef is returnend.
If both NAME and OBJECT are passed, a new repeatable sub-form
is added under NAME.
NAME is a fully-qualified sub-form name. Components of the
hierarchy are separated by dots ("."). OBJECT must be an
object that inherits from Rose::HTML::Form::Repeatable.
- repeatable_forms [FORMS]
- If FORMS are passed, this method deletes all existing repeatable forms and
then calls add_repeatable_forms, passing all arguments.
The return value is an ordered list of this form's repeatable
sub-form objects (if any) in list context, or a reference to this list
in scalar context. The order of the forms matches the order of the form
names returned by the form_names method.
See the nested forms section to learn more about nested forms,
and the Rose::HTML::Form::Repeatable documentation to learn more about
repeatable forms.
- reset
- Call reset() on each field object and set error() to
undef.
- reset_fields
- Call reset() on each field object.
- self_uri
- Returns a Rose::URI object corresponding to the current state of the form.
If uri_base() is set, then it is included in front of what would
otherwise be the start of the URI (i.e., the value of the form's
"action" HTML attribute).
- start_html
- Returns the HTML that will begin the form tag.
- start_xhtml
- Returns the XHTML that will begin the form tag.
- start_multipart_html
- Sets the "enctype" HTML attribute to
"multipart/form-data", then returns the HTML that will begin the
form tag.
- start_multipart_xhtml
- Sets the "enctype" HTML attribute to
"multipart/form-data", then returns the XHTML that will begin
the form tag.
- trim_xy_params [BOOL]
- Get or set a boolean value that determines whether or not params that end
in ".x" or ".y" have that suffix trimmed off. This is
useful for handling query parameters created by some web browsers in
response to clicks on image buttons and other image-based elements.
Setting this attribute will propagate the value down to all sub-forms.
The default value is the value returned by the
default_trim_xy_params class method.
- uri_base [STRING]
- Get or set the URI of the form, minus the value of the "action"
HTML attribute. Although the form action can be a relative URI, I suggest
that it be an absolute path at the very least, leaving the
uri_base() to be the initial part of the full URI returned by
self_uri(). Example:
$form->action('/foo/bar');
$form->uri_base('http://www.foo.com');
# http://www.foo.com/foo/bar
$uri = $form->self_uri;
- uri_separator [CHAR]
- Get or set the character used to separate parameter name/value pairs in
the return value of query_string() (which is in turn used to
construct the return value of self_uri()). The default is
"&".
- validate [PARAMS]
- Validate the form by calling validate() on each field and
validate() on each each sub-form. If any field or form returns
false from its "validate()" method call,
then this method returns false. Otherwise, it returns true.
If this method is about to return false and the error
attribute of this form is not set, then it is set to a generic error
message.
PARAMS are name/value pairs. Valid parameters are:
- "cascade BOOL"
- If true, then the validate() method of each sub-form is called,
passing PARAMS, with a "form_only"
parameter set to true. The default value of the
"cascade" parameter is true. Note that
all fields in all nested forms are validated regardless of the value of
this parameter.
- "form_only BOOL"
- If true, then the validate method is not called on the fields of this form
and its sub-forms. Defaults to false, but is set to true when calling
validate() on sub-forms in response to the
"cascade" parameter.
Examples:
$form = Rose::HTML::Form->new;
$form->add_field(foo => { type => 'text' });
$subform = Rose::HTML::Form->new;
$subform->add_field(bar => { type => 'text' });
$form->add_form(sub => $subform);
# Call validate() on fields "foo" and "sub.bar" and
# call validate(form_only => 1) on the sub-form "sub"
$form->validate;
# Same as above
$form->validate(cascade => 1);
# Call validate() on fields "foo" and "sub.bar"
$form->validate(cascade => 0);
# Call validate(form_only => 1) on the sub-form "sub"
$form->validate(form_only => 1);
# Don't call validate() on any fields or sub-forms
$form->validate(form_only => 1, cascade => 0);
- validate_field_html_attrs [BOOL]
- Get or set a boolean flag that indicates whether or not the fields of this
form will validate their HTML attributes. If a BOOL argument is passed,
then it is passed as the argument to a call to
validate_html_attrs() on each field. In either case, the current
value of this flag is returned.
- was_submitted
- Returns true id params exist for any field, false otherwise.
- xhtml_hidden_fields
- Returns the XHTML serialization of the fields returned by
hidden_fields(), joined by newlines.
Any Rose::HTML::Objects questions or problems can be posted to the
Rose::HTML::Objects mailing list. To subscribe to the list or search the
archives, go here:
<http://groups.google.com/group/rose-html-objects>
Although the mailing list is the preferred support mechanism, you
can also email the author (see below) or file bugs using the CPAN bug
tracking system:
<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-HTML-Objects>
There's also a wiki and other resources linked from the Rose
project home page:
<http://rosecode.org>
John C. Siracusa (siracusa@gmail.com)
Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is
free software; you can redistribute it and/or modify it under the same terms
as Perl itself.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |