NAME

Catalyst::Plugin::FormValidator::Simple - Validator for Catalyst with FormValidator::Simple

SYNOPSIS

use Catalyst qw/FormValidator::Simple FillInForm/;

# set option
MyApp->config->{validator} = {
    plugins => ['CreditCard', 'Japanese'],
    options => { charset => 'euc'},
}

in your controller

sub defaulti : Private {

    my ($self, $c) = @_;

    $c->form(
        param1 => [qw/NOT_BLANK ASCII/, [qw/LENGTH 4 10/]],
        param2 => [qw/NOT_BLANK/, [qw/JLENGTH 4 10/]],
        mail1  => [qw/NOT_BLANK EMAIL_LOOSE/],
        mail2  => [qw/NOT_BLANK EMAIL_LOOSE/],
        { mail => [qw/mail1 mail2/] } => ['DUPLICATION'],
    );

    print $c->form->valid('param1');

    if ( some condition... ) {

        $c->form(
            other_param => [qw/NOT_INT/],
        );
    }

    if ( some condition... ) {

        # set your original invalid type.
        $c->set_invalid_form( param3 => 'MY_ERROR' );

    }

    if ( $c->form->has_error ) {
        
        if ( $c->form->missing('param1') ) {
            ...
        }

        if ( $c->form->invalid( param1 => 'ASCII' ) ) {
            ...
        }

        if ( $c->form->invalid( param3 => 'MY_ERROR' ) ) {
            ...
        }

    }
}

DESCRIPTION

This plugin allows you to validate request parameters with FormValidator::Simple. See FormValidator::Simple for more information.

This behaves like as Catalyst::Plugin::FormValidator.

CONFIGURATION

set config with 'validator' key.

MyApp->config->{validator} = { ... };

or

MyApp->config(
    validator => { ... },
);

PLUGINS

If you want to use some plugins for FormValidator::Simple, you can set like following.

MyApp->config(
    validator => {
        plugins => [qw/Japanese CreditCard DBIC::Unique/],
    },
);

In this example, FormValidator::Simple::Plugin::Japanese, FormValidator::Simple::Plugin::CreditCard, and FormValidator::Simple::Plugin::DBIC::Unique are loaded.

OPTIONS

When you set some options needed by specific validations, do like this.

MyApp->config(
    validator => {
        plugins => [qw/Japanese CreditCard DBIC::Unique/],
        options => {
            charset => 'euc',
            dbic_base_class => 'MyApp::Model::DBIC',
        },
    },
);

'charset' is necessary for Plugin::Japanese, and 'dbic_cbase_class' is used in Plugin::DBIC::Unique.

VALIDATION

use 'form' method, see FormValidator::Simple in detail.

sub do_add : Local {
    my ( $self, $c ) = @_;

    # execute validation.
    $c->form(
        name  => [qw/NOT_BLANK ASCII/,       [qw/LENGTH 0 20/] ],
        email => [qw/NOT_BLANK EMAIL_LOOSE/, [qw/LENGTH 0 20/] ],
        { unique => [qw/name email/] } => [qw/DBIC_UNIQUE User name email/],
    );

    if ( ... ) {

        # execute validation one more time in specific condition.
        $c->form(
            ...                 
        );

    }

    # See Catalyst::Plugin::RequestToken for '$c->validate_token'
    if ( $c->validate_token ) {

        # you can force to set invalid data.
        $c->set_invalid_form( token => 'TOKEN' );

    }

    # check result.
    # you can pick up result-object with 'form' method

    my $result = $c->form;

    if ( $result->has_error ) {

    # this is same as
    # if ( $result->has_missing or $result->has_invalid )

        $c->detach('add');

    }

}

HANDLING SUCCESSFUL RESULT

After it passes all validations, you may wanna put input-data into database. It's a elegant way to use [ Class::DBI and Class::DBI::FromForm ] or [ DBIx::Class and DBIx::Class::WebForm ].

sub do_add : Local {
    my ( $self, $c ) = @_;

    $c->form(
        name  => [qw/NOT_BLANK/],
        email => [qw/NOT_BLANK/],
    );

    my $result = $c->form;
    if ( $result->has_error ) {
        $c->detach('add');
    }

    my $user = MyProj::Model::DBIC::User->create_from_form($result);
    
    # this behaves like this...
    # MyProj::Model::DBIC::User->create({
    #    name  => $result->valid('name'),
    #    email => $result->valid('email'),
    # });
    #
    # if the key exists as the table's column, set the value with 'valid'
}

Here, I explain about 'valid' method. If the value indicated with key-name passes validations, You can get the data with 'valid',

my $result = $c->form(
    name  => [qw/NOT_BLANK/],
    email => [qw/NOT_BLANK/],
); 

print $result->valid('name');

print $result->valid('email');

But, this is for only single key validation normally.

my $result = $c->form(
    name => [qw/NOT_BLANK/], # single key validation
    { mail_dup => [qw/email email2/] } => ['DUPLICATION'] # multiple keys one
);

print $result->valid('name'); # print out the value of 'name'

print $result->valid('mail_dup'); # no value.

There are exceptions. These are 'DATETIME', 'DATE'.

my $result = $c->form(
    { created_on => [qw/created_year created_month created_day/] }
    =>
    [qw/DATETIME/],
);

print $result->valid('created_on'); #print out datetime string like "2005-11-23 00:00:00".

If you set some class around datetime in configuration. It returns object of the class you indicate. You can choose from Time::Piece and DateTime. For example...

MyApp->config(
    validator => {
        plugins => [...],
        options => {
            datetime_class => 'Time::Piece',
        },
    },
);

or

MyApp->config(
    validator => {
        plugins => [...],
        options => {
            datetime_class => 'DateTime',
            time_zone      => 'Asia/Tokyo',
        },
    },
);

then

my $result = $c->form(
    { created_on => [qw/created_year created_month created_day/] }
    =>
    [qw/DATETIME/],
);

my $dt = $result->valid('created_on');

print $dt->ymd;

MyProj::Model::CDBI::User->create_from_form($result);

This may be useful when you define 'has_a' relation for datetime columns. For example, in your table class inherits 'Class::DBI'

__PACKAGE__->has_a( created_on => 'DateTime',
    inflate => ...,
    deflate => ...,
);

And see also Class::DBI::Plugin::TimePiece, Class::DBI::Plugin::DateTime.

MESSAGE HANDLING

in template file, you can handle it in detail.

[% IF c.form.has_error %]
<p>Input Error</p>
<ul>
[% IF c.form.missing('name') %]
<li>input name!</li>
[% END %]
[% IF c.form.invalid('name') %]
<li>name is wrong</li>
[% END %]
[% IF c.form.invalid('name', 'ASCII') %]
<li>input name with ascii code.</li>
[% END %]
[% IF c.form.invalid('name', 'LENGTH') %]
<li>wrong length for name.</li>
[% END %]
</ul>
[% END %]

or, make it more easy.

[% IF c.form.has_error %]
<p>Input Error</p>
<ul>
[% FOREACH key IN c.form.error %]
    [% FOREACH type IN c.form.error(key) %]
    <li>Invalid: [% key %] - [% type %]</li>
    [% END %]
[% END %]
</li>
[% END %]

And you can also use messages configuration as hash reference.

MyApp->config(
    validator => {
        plugins  => [...],
        messages => {
            user => {
                name => {
                    NOT_BLANK => 'Input name!',
                    ASCII     => 'Input name with ascii code!',
                },
                email => {
                    DEFAULT   => 'email is wrong.!',
                    NOT_BLANK => 'input email.!'
                },
            },
            company => {
                name => {
                    NOT_BLANK => 'Input name!',
                },
            },
        },
    },
);

or YAML file. set file name

MyApp->config(
    validator => {
        plugins  => [...],
        messages => 'conf/messages.yml',
    },
);

and prepare yaml file like following,

DEFAULT:
    name:
        DEFAULT: name is invalid
user:
    name:
        NOT_BLANK: Input name!
        ASCII: Input name with ascii code!
    email:
        DEFAULT: Email is wrong!
        NOT_BLANK: Input email!
company:
    name:
        NOT_BLANK: Input name!

the format is...

Action1_Name:
    Key1_Name:
        Validation1_Name: Message
        Validation2_Name: Message
    Key2_Name:
        Validation1_Name: Message
Action2_Name:
    Key1_Name:
        ...
    

After messages configuration, call messages() method from result-object. and set action-name as argument.

[% IF c.form.has_error %]
<ul>
    [% FOREACH message IN c.form.messages('user') %]
    <li>[% message %]</li>
    [% END %]
</ul>
[% END %]

you can set each message format

MyApp->config(
    validator => {
        messages => 'messages.yml',  
        message_format => '<p>%s</p>'
    },
);

[% IF c.form.has_error %]
    [% c.form.messages('user').join("\n") %]
[% END %]

SEE ALSO

FormValidator::Simple

Catalyst

AUTHOR

Lyo Kato <lyo.kato@gmail.com>

COPYRIGHT AND LICENSE

Copyright(C) 2005 by Lyo Kato

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.