|
NAMERose::HTML::Form::Repeatable - Repeatable sub-form automation.SYNOPSISpackage Person; use base 'Rose::Object'; use Rose::Object::MakeMethods::Generic ( scalar => [ 'name', 'age' ], array => 'emails', ); ... package Email; use base 'Rose::Object'; use Rose::Object::MakeMethods::Generic ( scalar => [ 'address', 'type' => { check_in => [ 'home', 'work' ] }, ], ); ... package EmailForm; use base 'Rose::HTML::Form'; sub build_form { my($self) = shift; $self->add_fields ( address => { type => 'email', size => 50, required => 1 }, type => { type => 'pop-up menu', choices => [ 'home', 'work' ], required => 1, default => 'home' }, save_button => { type => 'submit', value => 'Save Email' }, ); } sub email_from_form { shift->object_from_form('Email') } sub init_with_email { shift->init_with_object(@_) } ... package PersonEmailsForm; use base 'Rose::HTML::Form'; sub build_form { my($self) = shift; $self->add_fields ( name => { type => 'text', size => 25, required => 1 }, age => { type => 'integer', min => 0 }, save_button => { type => 'submit', value => 'Save Person' }, ); ## ## The important part happens here: add a repeatable form ## # A person can have zero or more emails $self->add_repeatable_form(emails => EmailForm->new); # Alternate ways to add the same repeatable form: # # Name/hashref pair: # $self->add_repeatable_form(emails => { form_class => 'EmailForm' }); # # Using the generic add_form() method: # $self->add_form # ( # emails => # { # form_class => 'EmailForm', # default_count => 0, # repeatable => 1, # } # ); # # See the documentation for Rose::HTML::Form's add_forms() and # add_repeatable_forms() methods for more information. } sub init_with_person { my($self, $person) = @_; $self->init_with_object($person); # Delete any existing email forms and create # the appropriate number for this $person my $email_form = $self->form('emails'); $email_form->delete_forms; my $i = 1; foreach my $email ($person->emails) { $email_form->make_form($i++)->init_with_email($email); } } sub person_from_form { my($self) = shift; my $person = $self->object_from_form(class => 'Person'); my @emails; foreach my $form ($self->form('emails')->forms) { push(@emails, $form->email_from_form); } $person->emails(@emails); return $person; } DESCRIPTIONRose::HTML::Form::Repeatable provides a convenient way to include zero or more copies of a nested form. See the nested forms section of the Rose::HTML::Form documentation for some essential background information.Rose::HTML::Form::Repeatable works like a wrapper for an additional level of sub-forms. The Rose::HTML::Form::Repeatable object itself has no fields. Instead, it has a list of zero or more sub-forms, each of which is named with a positive integer greater than zero. The synopsis above contains a full example. In it, the "PersonEmailsForm" contains zero or more EmailForm sub-forms under the name "emails". The "emails" name identifies the Rose::HTML::Form::Repeatable object, while "emails.N" identifies each EmailForm object contained within it (e.g., "emails.1", "emails.2", etc.). Each repeated form must be of the same class. A repeated form can be generated by cloning a prototype form or by instantiating a specified prototype form class. A repeatable form decides how many of each repeated sub-form it should contain based on the contents of the query parameters (contained in the params attribute for the parent form). If there are no params, then the default_count determines the number of repeated forms. Repeated forms are created in response to the init_fields or prepare methods being called. In the synopsis example, the "person_from_form" method does not need to create, delete, or otherwise set up the repeated email sub-forms because it can sensibly assume that the init_fields and/or prepare methods have been called already. On the other hand, the "init_with_person" method must configure the repeated email forms based on the number of email addresses contained in the "Person" object that it was passed. On the client side, the usual way to handle repeated sub-forms is to make an AJAX request for new content to add to an existing form. The make_form method is designed to do exactly that, returning a correctly namespaced Rose::HTML::Form-derived object ready to have its fields serialized (usually through a template) into HTML which is then inserted into the existing form on a web page. This class inherits from and follows the conventions of Rose::HTML::Form. Inherited methods that are not overridden will not be documented a second time here. See the Rose::HTML::Form documentation for more information. CONSTRUCTOR
CLASS METHODS
OBJECT METHODS
AUTHORJohn C. Siracusa (siracusa@gmail.com)LICENSECopyright (c) 2010 by John C. Siracusa. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Visit the GSP FreeBSD Man Page Interface. |