Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sshaw/mojolicious-plugin-formfields
Use objects and data structures in your forms
https://github.com/sshaw/mojolicious-plugin-formfields
form form-builder form-validation mojolicious perl
Last synced: 8 days ago
JSON representation
Use objects and data structures in your forms
- Host: GitHub
- URL: https://github.com/sshaw/mojolicious-plugin-formfields
- Owner: sshaw
- Created: 2012-03-31T21:13:39.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2019-11-10T00:28:28.000Z (about 5 years ago)
- Last Synced: 2024-12-01T18:45:11.419Z (23 days ago)
- Topics: form, form-builder, form-validation, mojolicious, perl
- Language: Perl
- Homepage:
- Size: 61.5 KB
- Stars: 3
- Watchers: 6
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.pod
- Changelog: Changes
Awesome Lists containing this project
README
=pod
=head1 NAME
Mojolicious::Plugin::FormFields - Lightweight form builder with validation and filtering
=head1 SYNOPSIS
$self->plugin('FormFields');
# In your controller
sub edit
{
my $self = shift;
my $user = $self->users->find($self->param('id'));
$self->stash(user => $user);
}sub update
{
my $self = shift;
my $user = $self->params('user');$self->field('user.name')->is_required;
$self->field('user.password')->is_required->is_equal('user.confirm_password');if($self->valid) {
$self->users->save($user);
$self->redirect_to('/profile');
return;
}$self->stash(user => $user);
}# In your view
field('user.name')->text
field('user.name')->error unless field('user.name')->validfield('user.password')->password
field('user.age')->select([10,20,30])
field('user.password')->password
field('user.taste')->radio('me_gusta')
field('user.taste')->radio('estoy_harto_de')
field('user.orders.0.id')->hidden# Fields for a collection
my $kinfolk = field('user.kinfolk');
for my $person (@$kinfolk) {
$person->hidden('id')
$person->text('name')
}# Or, scope it to the 'user' param
my $user = fields('user')
$user->hidden('id')
$user->text('name')
$user->error('name') unless $user->valid('name')
$user->label('admin')
$user->checkbox('admin')
$user->password('password')
$user->select('age', [ [X => 10], [Dub => 20] ])
$user->file('avatar')
$user->textarea('bio', size => '10x50')my $kinfolk = $user->fields('kinfolk')
for my $person (@$kinfolk) {
$person->text('name')
# ...
}=head1 DESCRIPTION
C allows you to bind objects and data structures to form fields. It also performs validation and filtering via L.
=head1 CREATING FIELDS
Fields can be bound to a hash, an array, something blessed, or any combination of the three.
They are created by calling the C<< L >> helper with a path to the value you want to bind,
and then calling the desired HTML input methodfield('user.name')->text
Is the same as
text_field 'user.name', $user->name, id => 'user-name'
(though C sets C).
Field names/paths are given in the form C where C is an object or
data structure and C is a method, hash key, or array index. The target must be in the stash under the key C
or provided as an argument to C<< L >>.Some examples:
field('users.0.name')->text
Is the same as
text_field 'users.0.name', $users->[0]->name, id => 'users-0-name'
And
field('item.orders.0.XAJ123.quantity')->text
Is equivalent to
text_field 'item.orders.0.XAJ123.quantity', $item->orders->[0]->{XAJ123}->quantity, id => 'item-orders-0-XAJ123-quantity'
As you can see DOM IDs are always created.
Here the target key C does not exist in the stash so the target is supplied
field('book.upc', $item)->text
If a value for the flattened representation exists (e.g., from a form submission) it will be used instead of
the value pointed at by the field name (desired behavior?). This is the same as Mojolicious' Tag Helpers.Options can also be provided
field('user.name')->text(class => 'input-text', data => { name => 'xxx' })
See L for the list of HTML input creation methods.
=head2 STRUCTURED REQUEST PARAMETERS
Structured request parameters for the bound object/data structure are available via
C's L.
They can not be accessed via C.A request with the parameters C can be accessed in your action like
my $user = $self->param('user');
$user->{name};
$user->{email};Other parameters can be accessed as usual
$id = $self->param('id');
The flattened parameter can also be used
$name = $self->param('user.name');
See L for more info.
=head2 SCOPING
Fields can be scoped to a particular object/data structure via the C<< L >> helper
my $user = fields('user');
$user->text('name');
$user->hidden('id');When using C you must supply the field's name to the HTML input and validation methods, otherwise
the calls are the same as they are with C.=head2 COLLECTIONS
You can also create fields scoped to elements in a collection
my $addresses = field('user.addresses');
for my $addr (@$addresses) {
# field('user.addresses.N.id')->hidden
$addr->hidden('id');# field('user.addresses.N.street')->text
$addr->text('street');# field('user.addresses.N.city')->select([qw|OAK PHL LAX|])
$addr->select('city', [qw|OAK PHL LAX|]);
}Or, for fields that are already scoped
my $user = fields('user')
$user->hidden('id');my $addressess = $user->fields('addresses');
for my $addr (@$addresses) {
$addr->hidden('id')
# ...
}You can also access the underlying object and its position within a collection
via the C and C methods.<% for my $addr (@$addresses) { %>
Address #<%= $addr->index + 1 %>
<%= $addr->hidden('id') %>
...
<% } %>=head1 VALIDATING & FILTERING
Validation rules are created by calling validation and/or filter methods
on the field to be validated# In your controller
my $self = shift;
$self->field('user.name')->is_required;
$self->field('user.name')->filter('trim');These methods can be chained
$self->field('user.name')->is_required->filter('trim');
To perform validation on a field call its C method
$field = $self->field('user.name');
$field->is_required;
$field->valid;
$field->error;This will only validate and return the error for the C field. To validate all fields and retrieve all error messages call the controller's C and C methods
$self->field('user.name')->is_required;
$self->field('user.age')->is_like(qr/^\d+$/);
$self->valid;my $errors = $self->errors;
$errors->{'user.name'}
# ...Of course the C/C and C methods can be used in your view too
<% unless(valid()) { %>
Hey, fix the below errors
<% } %><%= field('name')->text %>
<% unless(field('name')->valid) { %>
<%= field('name')->error %>
<% } %>When creating validation rules for L you must pass the field name as the first argument
my $user = fields('user');
$user->is_required('password');
$user->is_equal(password => 'confirm_password');
$user->is_long_at_least(password => 8, 'Mais longo caipira');=head2 AVAILABLE RULES & FILTERS
C uses C, see L for a list.
=head2 RENAMING THE VALIDATION METHODS
In the event that the C and/or C methods clash with exiting methods/helpers
in your app you can rename them by specifying alternate names when loading the plugin$self->plugin('FormFields', methods => { valid => 'form_valid', errors => 'form_errors' });
# ...$self->field('user.name')->is_required;
$self->form_valid;
$self->form_errors;Note that this I changes the methods B and does not change the methods on the object returned by C.
=head1 METHODS
=head2 field
field($name)->text
field($name, $object)->text=head3 Arguments
C<$name>
The field's name, which can also be the path to its value in the stash. See L.
C<$object>
Optional. The object used to retrieve the value specified by C<$name>. Must be a reference to a
hash, an array, or something blessed. If not given the value will be retrieved from
the stash or, for previously submitted forms, the request parameter C<$name>.=head3 Returns
An object than can be used to create HTML form fields, see L.
=head3 Errors
An error will be raised if:
=over 4
=item * C<$name> is not provided
=item * C<$name> cannot be retrieved from C<$object>
=item * C<$object> cannot be found in the stash and no default was given
=back
=head3 Collections
See L
=head2 fields
$f = fields($name)
$f->text('address')$f = fields($name, $object)
$f->text('address')Create form fields scoped to a parameter.
For example
% $f = fields('user')
%= $f->select('age', [10,20,30])
%= $f->textarea('bio')Is the same as
%= field('user.age')->select([10,20,30])
%= field('user.bio')->textarea=head3 Arguments
Same as L.
=head3 Returns
An object than can be used to create HTML form fields scoped to the C<$name> argument, see L.
=head3 Errors
Same as L.
=head3 Collections
See L
=head1 SUPPORTED FIELDS
=head2 checkbox
field('user.admin')->checkbox(%options)
field('user.admin')->checkbox('yes', %options)Creates
=head2 file
field('user.avatar')->file(%options);
Creates
=head2 hidden
field('user.id')->hidden(%options)
Creates
=head2 input
field('user.phone')->input($type, %options)
For example
field('user.phone')->input('tel', pattern => '\d{3}-\d{4}')
Creates
=head2 label
field('user.name')->label
field('user.name')->label('Nombre', for => "tu_nombre_hyna")Creates
Name
Nombre=head2 password
field('user.password')->password(%options)
Creates
=head2 select
field('user.age')->select([10,20,30], %options)
field('user.age')->select([[Ten => 10], [Dub => 20], [Trenta => 30]], %options)Creates
10
20
30
Ten
Dub
Trenta
=head2 radio
field('user.age')->radio('older_than_21', %options)
Creates
=head2 text
field('user.name')->text(%options)
field('user.name')->text(size => 10, maxlength => 32)Creates
=head2 textarea
field('user.bio')->textarea(%options)
field('user.bio')->textarea(size => '10x50')Creates
Proprietary and confidential
Proprietary and confidential=head1 AUTHOR
Skye Shaw (sshaw [AT] gmail.com)
=head1 SEE ALSO
L, L, L, L
=head1 COPYRIGHT
Copyright (c) 2012-2014 Skye Shaw.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.