Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Rose::HTML::Form::RepeUserlContributed Perl DocRose::HTML::Form::Repeatable(3)

       Rose::HTML::Form::Repeatable - Repeatable sub-form automation.

	 package 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 =>
	     'type' => { check_in => [ 'home', 'work' ]	},


	 package EmailForm;

	 use base 'Rose::HTML::Form';

	 sub build_form
	   my($self) = shift;

	     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;

	     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) =	@_;


	   # Delete any	existing email forms and create
	   # the appropriate number for	this $person

	   my $email_form = $self->form('emails');

	   my $i = 1;

	   foreach my $email ($person->emails)

	 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);


	   return $person;

       Rose::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

       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",

       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.

       new PARAMS
	   Constructs a	new Rose::HTML::Form::Repeatable object	based on
	   PARAMS, where PARAMS	are name/value pairs.  Any object method is a
	   valid parameter name.

       default_form_class [CLASS]
	   Get or set the name of the default Rose::HTML::Form-derived class
	   of the repeated form.  The default value is Rose::HTML::Form.

       default_count [INT]
	   Get or set the default number of repeated forms to create in	the
	   absence of any parameters.  The default value is zero.

       empty_is_ok [BOOL]
	   Get or set a	boolean	value that indicates whether or	not it's OK
	   for a repeated form to be empty.  (That is, validation should not
	   fail	if the entire sub-form is empty, even if the sub-form has
	   required fields.)  Defaults to false.

	   In addition to doing	all the	usual things that the base class
	   implementation does,	this method creates or deletes repeated	sub-
	   forms as necessary to make sure they	match the query	parameters, if
	   present, or the default_count if there are no parameters that apply
	   to any of the sub-forms.

       init_with_objects [ OBJECTS | PARAMS ]
	   Given a list	of OBJECTS or name/value pairs PARAMS, initialize each
	   sub-form, taking one	object from the	list and passing it to a
	   method called on each sub-form.  The	first object is	passed to the
	   first form, the second object to the	second form, and so on.	 (Form
	   order is determined by the the order	forms are returned from	the
	   forms method.)

	   Valid parameters are:

	   objects ARRAYREF
	       A reference to an array of objects with which to	initialize the
	       form(s).	 This parameter	is required if PARAMS are passed.

	   method NAME
	       The name	of the method to call on each sub-form.	 The default
	       value is	"init_with_object".

       make_form INT
	   Given an integer argument greater than zero,	create,	add to the
	   form, and return a new numbered prototype form clone	object.

	   Create, add to the form, and	return a new numbered prototype	form
	   clone object	whose rank is one greater than the the highest-ranking
	   existing sub-form.

       objects_from_form [PARAMS]
	   Return a list (in list context) or reference	to an array (in	scalar
	   context) of objects corresponding to	the list of repeated sub-
	   forms.  This	is done	by calling a method on each sub-form and
	   collecting the return values.  Name/value parameters	may be passed.
	   Valid parameters are:

	   method NAME
	       The name	of the method to call on each sub-form.	 The default
	       value is	"object_from_form".

	   This	method does the	same thing as the init_fields method, but
	   calls through to the	base class prepare method rather than the
	   base	class init_fields method.

       prototype_form [FORM]
	   Get or set the Rose::HTML::Form-derived object used as the
	   prototype for each repeated form.

       prototype_form_class [CLASS]
	   Get or set the name of the Rose::HTML::Form-derived class used by
	   the prototype_form_clone method to create each repeated sub-form.
	   The default value is	determined by the default_form_class class

       prototype_form_spec [SPEC]
	   Get or set the specification	for the	Rose::HTML::Form-derived
	   object used as the prototype	for each repeated form.	 The SPEC can
	   be a	reference to an	array, a reference to a	hash, or a list	that
	   will	be coerced into	a reference to an array.  In the absence of a
	   prototype_form, the SPEC is dereferenced and	passed to the "new()"
	   method called on the	prototype_form_class in	order to create	each

	   Returns a clone of the prototype_form, if one was set.  Otherwise,
	   creates and returns a new prototype_form_class object, passing the
	   prototype_form_spec to the constructor.

       John C. Siracusa	(

       Copyright (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.

perl v5.24.1			  2015-03-17   Rose::HTML::Form::Repeatable(3)


Want to link to this manual page? Use this URL:

home | help