NAME
CGI::MxScreen::Form::Field - A recorded field
SYNOPSIS
# $self is a CGI::MxScreen::Screen
use CGI qw/:standard/;
my $amount = $self->record_field(
-name => "price",
-storage => [$order, 'set_amount'],
-default => $order->amount,
-override => 1,
-verify => 'is_positive',
-mandatory => 1,
-patch => 'strip_spurious_zeros',
-size => 10,
-maxlength => 10,
);
print textfield($amount->properties);
my $menu = $self->record_field(
-name => "mode",
-values => ['replace', 'append', 'prepend'],
-default => 'append',
);
print popup_menu($menu->properties);
DESCRIPTION
This class models a recorded CGI control field. One does not manually create objects from this class, they are created by CGI::MxScreen
when the record_field()
routine is called on a screen object to declare a new field.
In order to attach application-specific storage information and validating or patching callbacks to a CGI field, it is necessary to declare them within the screen they belong, usually before generating the HTML code for those fields. The declaration routine takes a set of meaningful arguments, and lets the others pass through verbatim (they are recorded to be given back when properties()
is called).
You must at least supply the -name
argument. You will probably supply -verify
as well if you wish to perform validation of control fields, and -storage
to be able to store the value in some place, or perform any other processing on it.
INTERFACE
Some of the arguments below take a plain routine argument as a scalar. This routine is not a code reference but a name that will be looked up in various packages unless it is already qualified, such as 'main::f'
. See "Utility Path" in CGI::MxScreen for information about how to specify the searching path, so to speak.
Creation Arguments
The following named arguments may be given to record_field()
. They are all optional but for -name
. Any argument not listed below will be simply recorded and propagated via properties()
:
-default
=> value-
Sets the default value, for the first time the field is shown. Since
CGI
routines create stateful fields, you may need to say:-default => $value, -override => 1,
to force the value of the field to
$value
. That is, if you use theCGI
routines to ultimately generate your field.This parameter is propagated via
properties()
, but is intercepted by.record_field
to set thevalue
attribute of the object. If no-default
is given, then the value will be that of the CGI parameter bearing the name you give via-name
. -mandatory
=> flag-
By default, fields are not mandatory. Setting flag to true tells
CGI::MxScreen
that this parameter should be filled. However, this checking only occurs when you list'validate'
as an action callback in the submit buttons of your screen. See CGI::MxScreen::Form::Button. -name
=> name-
Madantory parameter, giving the name of the field. This is the CGI parameter name.
-nostorage
=> 1-
This directs
CGI::MxScreen
to not handle the storage of the parameter, at submit time. No trail will be left anywhere in the context. This parameter is ignored when-storage
is also given. -patch
=> routine-
Specifies a patching routine, to be called on the field value to modify it on-the-fly, before storage and verification take place.
The routine is given the parameter value, and it must return a new (possibly unchanged) value, which will be the one retained for further processing. Everything will be as if the user had entered this value in the first place.
For instance, assume you say:
-patch => 'main::no_needless_zeros',
and define:
sub main::no_needless_zeros { my ($v) = @_; $v =~ s/^0+//; $v =~ s/0+$//; return $v; }
Then you if the user entered
003.140
in a text field, it would be patched to3.14
.See "Utility Path" in CGI::MxScreen to learn how to avoid qualifying the routine and just give its "basename", here
no_needless_zeros
. -storage
=> scalar | array_ref-
Storage indication lets you store the value of the field in some place, either directly in the global persistent hash, or in any other data structure of your choice, or even by invoking a callback.
If the argument is a scalar, then it is taken as a key in the global persistent hash. For instance:
-storage => "user_id",
would store the value of the field in the global hash, and would be accessed within a screen by saying:
my $id = $self->vars->{user_id};
Or the argument to
-storage
can be an array ref. In that case, the meaning of the items in the list depend on the nature of its first item:If it is an array ref, then the following item must be an index, and the value will be stored at that position in the array. For instance:
my $array = $self->vars->{user_array}; my $field = $self->record_field( -name => "id", -storage => [$array, 2], );
If it is an hash ref, then the following item must be a key, and the value will be store at that key in the hash. For instance:
my $hash = $self->vars->{user_hash}; my $field = $self->record_field( -name => "id", -storage => [$hash, "uid"], );
If it is a blessed ref, then we have a callback specification of the third kind, as described in "Callbacks" in CGI::MxScreen. For instance:
my $field = $self->record_field( -name => "id", -storage => [$object, 'record_uid', 4], );
The parameter value is prepended to the argument list, so the above would raise the following call:
$object->record_uid(CGI::param("id"), 4);
so to speak.
Note: the storage specification is serialized into the context, and the actual processing will occur once the user has submitted the form back to the server, on the deserialized context. This means that anything you specify needs to be persistent, and stay accessible throughout the section.
That's why it's useless to say:
my $field = $self->record_field( -name => "id", -storage => [['a'], 2], );
because it will indeed store the value in an anonymous array, which is not otherwise accessible by the application. You should say something along those lines:
my $vars = $self->vars; my $array; if (exists $vars->{user_array}) { $array = $vars->{user_array}; } else { $array = $vars->{user_array} = []; } my $field = $self->record_field( -name => "id", -storage => [$array, 2], );
The
exists()
check is there because by default, keys within the global hash context are protected: it is a fatal error to access a non-existent key (see CGI::MxScreen::Config to learn how to disable that check).All the code examples given above were simplified, assuming the value within the context was already properly initialized.
-verify
=> routine-
Specifies a validation routine to be run. The routine will not be actually run unless the
'validate'
action callback is not recorded in the pressed submit button (see CGI::MxScreen::Form::Button).The routine can be specified as a single scalar, or as an array ref:
['is_greater', 4]
The validation routine is passed the parameter value as a first argument, and it must return
0
if OK, an error message otherwise, which will be stored in theerror
field. In the example above,is_greater($value, 4);
would be called, assuming
$value
is the value of the field.
Any other argument will be recorded as-is and passed through when properties()
is called on the field object.
Features
Once created via record_field
, the following features may be called on the object:
error
-
The error message returned by the validation routine. If it evaluates to false, there is no error condition for this field.
name
-
Returns the field name.
properties
-
Generates the list of CGI arguments suitable to use with the routines in the
CGI
modules. An easy way to generate a popup menu is to do:print popup_menu($menu->properties);
assuming
$menu
was obtained through arecord_field()
call and included such things as-values
. Otherwise, you may add those additional switches now, like in:print popup_menu($menu->properties, -values => ['a', 'b']);
but it might be better to group properties at the same place, i.e. when
record_field()
is called. value
-
Returns the recorded field value.
When recording a field within a screen, the
value
attribute is automatically set to the CGI parameter value.
AUTHORS
Raphael Manfredi <Raphael_Manfredi@pobox.com> and Christophe Dehaudt <Christophe.Dehaudt@teamlog.fr>.
SEE ALSO
CGI::MxScreen(3), CGI::MxScreen::Form::Button(3), CGI::MxScreen::Form::Utils(3).