NAME

Oogly::Aagly - A form building, processing and data validation system!

VERSION

version 0.02

SYNOPSIS

Oogly-Aagly is basically form building on top of the Oogly data validation framework. This means that existing packages and code using Oogly can be easily converted to utilize this new functionality.

The following is an example of that...

    use MyApp::FormFu;
    my $form = MyApp::FormFu->new(\%params);
    my @flds = qw/search/;
    if ($form->validate(@flds)){
        ...
    }
    else {
	print $form->render('form_name', '/url', @flds);
    }

    package MyApp::FormFu;
    use Oogly::Aagly;

    # cpan and see Oogly for all the gritty details ...
    field 'search' => {
        label => 'user search',
        error => 'your search must contain a valid id number',
	element => {
	    type => 'input',
	    template => ''
	},
        validation => sub {
            my ($form, $field, $params) = @_;
            $form->error($field, $field->{error})
                if $field->{value} =~ /\D/;
        }
    };

METHODS

new

The new method instantiates a new Oogly::Aagly instance.

field

The field function defines the validation rules for the specified parameter it is named after. e.g. field 'some_data' => {...}, validates against the value of the hash reference where the key is `some_data`.

field 'some_param' => {
    mixin => 'default',
    validation => sub {
        my ($v, $this, $params) = @_;
        $v->error($this, "...")
            if ...
    }
};

Fields are comprised of specific directives, those directives are as follows:
name: The name of the field (auto set)
value: The value of the parameter matching the name of the field (auto set)
mixin: The template to be used to copy directives from

mixin 'template' => {
    required => 1
};

field 'a_field' => {
    mixin => 'template'
}

mixin_field: The field to be used as a mixin(template) to copy directives from

field 'a_field' => {
    required => 1,
    min_length => 2,
    max_length => 10
};

field 'b_field' => {
    mixin_field => 'a_field'
};

validation: A validation routine that returns true or false

field '...' => {
    validation => sub {
        my ($self, $field, $all_parameters) = @_;
        return 1
    }
};

errors: The collection of errors encountered during processing (auto set arrayref)
label: An alias for the field name, something more human-readable
error: A custom error message, displayed instead of the generic ones
required : Determines whether the field is required or not, takes 1/0 true of false
min_length: Determines the maximum length of characters allowed
max_length: Determines the minimum length of characters allowed
ref_type: Determines whether the field value is a valid perl reference variable
regex: Determines whether the field value passed the regular expression test

field 'c_field' => {
    label => 'a field labeled c',
    error => 'a field labeled c cannot ',
    required => 1,
    min_length => 2,
    max_length => 25,
    ref_type => 'array',
    regex => '^\d+$'
};

filter: An alias for the filters directive, see filter method for filter names
filters: Set filters to manipulate the data before validation

field 'd_field' => {
    ...,
    filters => [
        'trim',
        'strip'
    ]
};

field 'e_field' => {
    filter => 'strip'
};

field 'f_field' => {
    filters => [
        'trim',
        sub {
            $_[0] =~ s/(abc)|(123)//;
        }
    ]
};

mixin

The mixin function defines validation rule templates to be later reused by more specifically defined fields.

mixin 'default' => {
    required    => 1,
    min_length  => 4,
    max_length  => 255
};

error

The error function is used to set and/or retrieve errors encountered or set during validation. The error function with no parameters returns the error message arrayref which can be used to output a single concatenated error message a with delimeter.

$self->error() # returns an arrayref of errors
join '<br/>', @{$self->error()}; # html-break delimeted errors
$self->error('some_param'); # show parameter-specific error messages arrayref
$self->error($this, "$name must conform ..."); # set error, see `field` function

errors

The errors function is a synonym for the error function.

check_mixin

The check_mixin function is used internally to validate the defined keys and values of mixins.

check_field

The check_field function is used internally to validate the defined keys and values of fields.

use_mixin

The use_mixin function sequentially applies defined mixin parameteres (as templates)to the specified field.

use_mixin_field

The use_mixin_field function copies the properties (directives) of a specified field to the target field processing copied mixins along the way.

validate

The validate function sequentially checks the passed-in field names against their defined validation rules and returns 0 or 1 based on the existence of errors.

basic_validate

The basic_validate function processes the pre-defined contraints e.g., required, min_length, max_length, etc.

basic_filter

The basic_filter function processes the pre-defined filters e.g., trim, strip, digit, alpha, numeric, alphanumeric, uppercase, lowercase, titlecase, or custom etc.

Oogly

The Oogly method encapsulates fields and mixins and returns an Oogly::Aagly instance for further validation. This method exist for situations where Oogly::Aagly is use outside of a specific validation package.

my $i = Oogly(
        mixins => {
                'default' => {
                        required => 1
                }
        },
        fields => {
                'test1' => {
                        mixin => 'default'
                }
        },
);

# Important store the new instance
$o = $i->new({ test1 => '...' });

if ($o->validate('test1')) {
    ...
}

render

The render method returns an html form using the supplied url, and fields.

templates

The templates method is used to define the absolute path to where the form element templates are stored.

$form->templates('/var/www/templates/');

template

The template method is used to define the relative path to where the specified form element template is stored.

$form->template(input => 'elements/input_text.tt');

Warning!

Oogly-Aagly is still undergoing testing, etc. The package is being published as a proof-of-concept sort-a-thing. Use at your own risk, although I am confident you'll love the simplicity, syntax and DRY nature.

Building Forms

Ok really quickly, the idea behind Oogly-Aagly (derived from Oogly) is to define each piece of incoming data individually for DRY (dont repeat yourself) purposes. It stands-to-reason that you'll need to use/create a form element or validate the same data input more than once in an application of any complexity, that said, say your application (and probably your database) has a email field, chances are the validation rules, form element look and feel, etc, are the same each time you request it from the user, so it makes sense to define it only once and call it when we need it, this is the where Oogly/Oogly-Aagly concept of fields come in. Anyway...

package Foo;
use Oogly::Aagly ':all';

field 'email' => {
    'label' => 'Email address',
    'error' => 'Please use a valid email address',
    'element' => {
        type => 'input_text',
    },
    validation => sub {
        return $_[1]->{value} =~ /\@/ if $_[1]->{value};
    }
};

my $form = Foo->new($params_hashref);
$form->render('form_name', 'url', 'email');

In the code above we have labeled the input parameter, given it a label, specified which type of html form element should represent it when called, and defined a simple validation rule to validate input.

If you are used to using Oogly the only difference you'll notice s the existence of the `element` hashref. This key is used to defined all form element related options.

Forms are rendered using HTML Templates marked-up using Template-Toolkit syntax and are stored in the Perl library. The `goat.pl` (Get Oogly-Aagly Template) utility can be used to copy those templates to the current work directory for customization. Oogly-Aagly only has templates for HTML form input elements, the following is a guide to each element and how it might be defined.

Form Templates

form
... form.tt
This template is a wrapper that encapsulates the selected form elements
rendered.
input_checkbox
... input_checkbox

field 'languages' => {
    element => {
        type => 'input_checkbox',
        options => {
            { value => 100, label => 'English' },
            { value => 101, label => 'Spanish' },
            { value => 102, label => 'Russian' },
        }
    },
    default => 100
};

... or ...

field 'languages' => {
    label => 'US Languages',
    element => {
        type => 'input_checkbox',
        options => {
            { value => 100, label => 'English' },
            { value => 101, label => 'Spanish' },
            { value => 102, label => 'Russian' },
        }
    },
    default => [100,101]
};
input_file
... input_file

field 'avatar_upload' => {
    element => {
        type => 'input_file'
    }
};
input_hidden
... input_hidden

field 'sid' => {
    element => {
        type => 'input_hidden'
    },
    value => $COOKIE{SID} # or whatever
};
input_password
... input_password

field 'password_confirm' => {
    element => {
        type => 'input_password'
    }
};
input_radio
... input_radio

field 'payment_method' => {
    element => {
        type => 'input_radio',
        options => {
            { value => 100, label => 'Visa' },
            { value => 101, label => 'MasterCard' },
            { value => 102, label => 'Discover' },
        },
        default => 100
    }
};
input_text
... input_text

field 'login' => {
    element => {
        type => 'input_login'
    }
};
select
... select

field 'payment_terms' => {
    element => {
        type => 'select',
        options => {
            { value => 100, label => 'Net 10' },
            { value => 101, label => 'Net 15' },
            { value => 102, label => 'Net 30' },
        },
    }
};
select_multiple
... select_multiple

field 'user_access_group' => {
    element => {
        type => 'select_multiple',
        options => {
            { value => 100, label => 'User' },
            { value => 101, label => 'Admin' },
            { value => 102, label => 'Super Admin' },
        },
    }
};
textarea
... textarea

field 'myprofile_greeting' => {
    element => {
        type => 'textarea',
    }
};

Validating Forms

Validating forms is the point, simply pass and array list of field names to the validate method in the order in which you would like them validated and presto.

package Foo;
use Oogly::Aagly ':all';

field 'email' => {
    'label' => 'Email address',
    'error' => 'Please use a valid email address',
    'element' => {
        type => 'input_text',
    },
    validation => sub {
        return $_[1]->{value} =~ /\@/ if $_[1]->{value};
    }
};

my $form = Foo->new($params_hashref);

if ($form->validate(@form_fields)) {
    # redirect ...
}
else {
    print $form->render('form_name', 'url', @form_fields);
}

Customizing Forms

Included with this package is a command-line utility, `goat.pl`, which should be used to copy Oogly-Aagly templates from the Perl library to your current-working-directory, once there you can specify that using the template method and customize your html elements any way you see fit.

my $form = Foo->new($params);
$form->templates('/var/www/view/elements');

You can expand the Oogly-Aagly template library using the template method to add custom templates.

my $form = Foo->new($params);
$form->template('input_jstree' => '/var/www/view/elements/input_jstree.tt');

More to come, try it for yourself...

AUTHOR

Al Newkirk <awncorp@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2010 by Al Newkirk.

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

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 938:

'=item' outside of any '=over'

Around line 1072:

You forgot a '=back' before '=head2'