=pod =head1 NAME Mojolicious::Plugin::FormFields - Use objects and data structures in your forms =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; $self->users->update($self->param('user')); } # In your view field('user.name')->text 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->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 L binds objects and data structures to form fields. =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 method field('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. Nested parameters 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/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 method, otherwise the calls are the same as they are with C. =head2 COLLECTIONS You can also create fields scoped to elements in the 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 it's position within a collection via the C and C methods. <% for my $addr (@$addresses) { %>

Address #<%= $addr->index + 1 %>

<%= $addr->hidden('id') %> ...
<% } %> =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 =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 =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 =head1 AUTHOR Skye Shaw (sshaw AT lucas.cis.temple.edu) =head1 SEE ALSO L, L, L =head1 COPYRIGHT Copyright (c) 2012 Skye Shaw. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.