The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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 the CGI routines to ultimately generate your field.

This parameter is propagated via properties(), but is intercepted by. record_field to set the value 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 to 3.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 the error 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 a record_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

The original authors are Raphael Manfredi <Raphael_Manfredi@pobox.com> and Christophe Dehaudt <Christophe.Dehaudt@teamlog.fr>.

Send bug reports, suggestions, problems or questions to Jason Purdy <Jason@Purdy.INFO>

SEE ALSO

CGI::MxScreen(3), CGI::MxScreen::Form::Button(3), CGI::MxScreen::Form::Utils(3).