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

FreeBSD Manual Pages


home | help
Maypole::Model::CDBI::UserrContributed Perl DocMaypole::Model::CDBI::AsForm(3)

       Maypole::Model:CDBI::AsForm - Produce HTML form elements	for database

	   package Music::CD;
	   use Maypole::Model::CDBI::AsForm;
	   use base 'Class::DBI';
	   use CGI;

	   sub create_or_edit {
	       my $self	= shift;
	       my %cgi_field = $self->to_cgi;
	       return start_form,
		      (map { "<b>$_</b>: ". $cgi_field{$_}->as_HTML." <br>" }

	  . . .

	   # Somewhere else in a Maypole application about beer...

	  $beer->to_field('brewery', 'textfield', {
		       name => 'brewery_id', value => $beer->brewery,
		       # however, no need to set value since $beer is object

	  # Rate a beer
	  $beer->to_field(rating =>  select => {
		       items =>	[1 , 2,	3, 4, 5],

	  # Select a Brewery to	visit in the UK
	  Brewery->to_field(brewery_id => {
		       items =>	[ Brewery->search_like(location	=> 'UK') ],

	 # Make	a select for a boolean field
	 $Pub->to_field('open' , { items => [ {'Open' => 1, 'Closed' =>	0 } ] });

	  $beer->to_field('brewery', {
		       selected	=> $beer->brewery, # again not necessary since caller is obj.

	   $beer->to_field('brewery', 'link_hidden', {r	=> $r, uri => ''.$beer->brewery});
	   # an	html link that is also a hidden	input to the object. R is required to
	   # make the uri  unless you  pass a  uri

	   # Templates Usage

	   <form ..>



	    <span class="field"> [% classmetadata.colnames.$col	%] : </span>

	    [% object.to_field(col).as_XML %]


	   . . .


	    <span class="field"> Brewery : </span>

	    [% object.to_field('brewery', { selected =>	23} ).as_XML %]


	   . . .


	   # Advanced Usage

	   # has_many select
	   package Job;
	   __PACKAGE__->has_a('job_employer' =>	'Employer');
	   __PACKAGE__->has_a('contact'	 => 'Contact')

	   package Contact;
	   __PACKAGE__->has_a('cont_employer' => 'Employer');
	   __PACKAGE__->has_many('jobs'	 => 'Job',
				 { join	=> { job_employer => 'cont_employer' },
				   constraint => { 'finshed' =>	0  },
				   order_by   => "created ASC",

	   package Employer;
	   __PACKAGE__->has_many('jobs'	 => 'Job',);
	   __PACKAGE__->has_many('contacts'  =>	'Contact',
				 order_by => 'name DESC',

	 # Choose some jobs to add to a	contact	(has multiple attribute).
	 my $job_sel = Contact->to_field('jobs'); # Uses constraint and	order by

	 # Choose a job	from $contact->jobs
	 my $job_sel = $contact->to_field('jobs');


       This module helps to generate HTML forms	for creating new database rows
       or editing existing rows. It maps column	names in a database table to
       HTML form elements which	fit the	schema.	Large text fields are turned
       into textareas, and fields with a has-a relationship to other
       "Class::DBI" tables are turned into select drop-downs populated with
       objects from the	joined class.

       This provides a convenient way to tweak AsForm's	behavior in
       exceptional or not so exceptional instances. Below describes the
       arguments hash and example usages.

	 $beer->to_field($col, $how, $args);
	 $beer->to_field($col, $args);

       Not all _to_* methods pay attention to all arguments. For example,
       '_to_textfield' does not	look in	$args->{'items'} at all.

       name -- the name	the element will have ,	this trumps the	derived	name.
	     $beer->to_field('brewery',	'readonly', {
			   name	=> 'brewery_id'

       value --	the initial value the element will have, trumps	derived	value
	     $beer->to_field('brewery',	'textfield', {
			   name	=> 'brewery_id', value => $beer->brewery,
			   # however, no need to set value since $beer is object

       items --	array of items generally used to make select box options
	   Can be array	of objects, hashes, arrays, or strings,	or just	a

	      #	Rate a beer
	      $beer->to_field(rating =>	 select	=> {
			   items => [1 , 2, 3, 4, 5],

	      #	Select a Brewery to visit in the UK
	      Brewery->to_field(brewery_id => {
			   items => [ Brewery->search_like(location => 'UK') ],

	     # Make a select for a boolean field
	     $Pub->to_field('open' , { items =>	[ {'Open' => 1,	'Closed' => 0 }	] });

       selected	-- something representing which	item is	selected in a select
	      $beer->to_field('brewery', {
			   selected => $beer->brewery, # again not necessary since caller is obj.

	   Can be an simple scalar id, an object, or an	array of either

       class --	the class for which the	input being made for field pertains
	   This	in almost always derived in cases where	it may be difficult to
	   derive, --
	      #	Select beers to	serve on handpump
	      Pub->to_field(handpumps => select	=> {	       class =>
	   'Beer', order_by => 'name ASC', multiple => 1,      });

       column_type -- a	string representing column type
	     $pub->to_field('open', 'bool_select', {
			   column_type => "bool('Closed', 'Open'),

       column_nullable -- flag saying if column	is nullable or not
	   Generally this can be set to	get or not get a null/empty option
	   added to a select box.  AsForm attempts to call
	   "$class->column_nullable" to	set this and it	defaults to true if
	   there is no shuch method.

	     $beer->to_field('brewery',	{ column_nullable => 1 });

       r or request  --	the Mapyole request object
       uri -- uri for a	link , used in methods such as _to_link_hidden
	    $beer->to_field('brewery', 'link_hidden',
		     {r	=> $r, uri => ''.$beer->brewery});
	    # an html link that	is also	a hidden input to the object. R	is required to
	    # make the uri  unless you	pass a	uri

       order_by, constraint, join
	   These are used in making select boxes. order_by is a	simple order
	   by clause and constraint and	join are hashes	used to	limit the rows
	   selected. The difference is that join uses methods of the object
	   and constraint uses static values. You can also specify these in
	   the relationship definitions.  See the relationships	documentation
	   of how to set arbitrayr meta	info.

	     BeerDB::LondonBeer->has_a('brewery', 'BeerDB::Brewery',
			      order_by	   => 'brewery_name ASC',
		      constraint   => {location	 => 'London'},
		      'join'	   => {'brewery_tablecolumn  =>	'beer_obj_column'},

       no_hidden_constraints --
	   Tell	AsForm not to make hidden inputs for relationship constraints.
	   It does this	 sometimes when	making foreign inputs. However,	i
	   think it should not do this and that	the FromCGI 's _create_related
	   method should do it.

	 $self->to_cgi([@columns, $args]);

       This returns a hash mapping all the column names	to HTML::Element
       objects representing form widgets.  It takes two	opitonal arguments --
       a list of columns and a hashref of hashes of arguments for each column.
       If called with an object	like for editing, the inputs will have the
       object's	values.

	 $self->to_cgi(); # uses $self->columns;  # most used
	 $self->to_cgi(qw/brewery style	rating/); # sometimes
	 # and on rare occassions this is desireable if	you have a lot of fields
	 # and dont want to call to_field a bunch of times just	to tweak one or
	 # two of them.
	 $self->to_cgi(@cols, {brewery => {
										how => 'textfield' # too big for select
						       style   => {
										column_nullable	=> 0,
										how => 'select',
										items => ['Ale', 'Lager']

   to_field($field [, $how][, $args])
       This maps an individual column to a form	element. The "how" argument
       can be used to force the	field type into	any you	want. All that you
       need is a method	named "_to_$how" in your class.	Your class inherits
       many from AsForm	 already.

       If "how"	is specified but the class cannot call the method it maps to,
       then AsForm will	issue a	warning	and the	default	input will be made.
       You can write your own "_to_$how" methods and AsForm comes with many.
       See "HOW	Methods". You can also pass this argument in $args->{how}.

	 my $cgi = $class->search_inputs ([$args]); # optional $args

       Returns hash or hashref of search inputs	elements for a class making
       sure the	inputs are empty of any	initial	values.	 You can specify what
       columns you want	inputs for in $args->{columns} or by the method
       "search_columns". The default is	 "display_columns".  If	you want to te
       search on columns in related classes you	can do that by specifying a
       one element hashref in place of the column name where the key is	the
       related "column"	(has_a or has_many method for example) and the value
       is a list ref of	columns	to search on in	the related class.

	 sub  BeerDB::Beer::search_columns {	   return ( 'name' , 'rating',
       { brewery => [ 'name', 'location'] } );

	 # Now foreign inputs are made for Brewery name	and location and the
	 # there will be no name clashing and processing can be	automated.

	 unselect any selected elements	in a HTML::Element select list widget

   _field_from_how($field, $how,$args)
       Returns an input	element	based the "how"	parameter or nothing at	all.
       Override	at will.

   _field_from_relationship($field, $args)
       Returns an input	based on the relationship associated with the field or
       nothing.	 Override at will.

       For has_a it will give select box

   _field_from_column($field, $args)
       Returns an input	based on the column's characteristics, namely type, or
       nothing.	 Override at will.

   recognized arguments
	 selected => $object|$id,
	 name	  => $name,
	 value	  => $value,
	 where	  => SQL 'WHERE' clause,
	 order_by => SQL 'ORDER	BY' clause,
	 constraint => hash of constraints to search
	 limit	  => SQL 'LIMIT' clause,
	 items	  => [ @items_of_same_type_to_select_from ],
	 class => $class_we_are_selecting_from
	 stringify => $stringify_coderef|$method_name

   1. a	select box out of a has_a or has_many related class. # For has_a the
       default behavior	is to make a select box	of every element in # related
       class and you choose one. #Or explicitly	you can	create one and pass
       options like where and order BeerDB::Beer->to_field('brewery','select',
       {where => "location = 'Germany'");
	 # For has_many	the default is to get a	multiple select	box with all objects.
	 # If called as	an object method, the objects existing ones will be selected.
	 Brewery::BeerDB->to_field('beers','select', {where => "rating > 5"});

   2. a	select box for objects of arbitrary class -- say BeerDB::Beer for fun.
       # general BeerDB::Beer->to_field('', 'select', $options)
	 BeerDB::Beer->to_field('', 'select'); # Select	box of all the rows in class
									 # with	PK as ID, $Class->to_field() same.
	 BeerDB::Beer->to_field('','select',{ where => "rating > 3 AND class like 'Ale'", order_by => 'rating DESC, beer_id ASC' , limit => 10});
	 # specify exact where clause

   3. If you already have a list of objects to select from  --
	 BeerDB:;Beer->to_field($col, 'select' , {items	=> $objects});

       # 3. a select box for arbitrary set of objects
	# Pass array ref of objects as first arg rather	than field
	$any_class_or_obj->to_field([BeerDB::Beer->search(favorite => 1)],

       Returns a select	box for	the an enum column type.

       Returns a "No/Yes"  select box for a boolean column type.

   _to_hidden($field, $args)
       This makes a hidden html	element	input. It uses the "name" and "value"
       arguments. If one or both are not there,	it will	look for an object in
       "items->[0]" or the caller. Then	it will	use $field or the primary key
       for name	 and the value of the column by	the derived name.

   _to_link_hidden($col, $args)
       Makes a link with a hidden input	with the id of $obj as the value and
       name.  Name defaults to the objects primary key.	The object defaults to

       Creates inputs for a foreign class, usually related to the calling
       class or	object.	In names them so they do not clash with	other names
       and so they can be processed generically.  See _rename_foreign_inputs
       below  and Maypole::Model::CDBI::FromCGI::classify_foreign_inputs.

       Arguments this recognizes are :

	       related_meta -- if you have this, great,	othervise it will determine or die
	       columns	-- list	of columns to make inputs for
	       request (r) -- TODO the Maypole request so we can see what action

       *Function* to make sense	out of the "selected" argument which has
       values of the options that should be selected by	default	when making a
       select box.  It can be in a number formats.  This method	returns	a map
       of which	options	to select with the values being	the keys in the	map (
       {val1 =>	1, val2	= 1} ).

       Currently this method  handles the following formats for	the "selected"
       argument	and in the following ways

	 Object				       -- uses the id method  to get the value
	 Scalar				       -- assumes it *is* the value
	 Array ref of objects  -- same as Object
	 Arrays	of data		       -- uses the 0th element in each
	 Hashes	of data		       -- uses key named 'id'

       Internal	api  method to make the	actual select box form elements.  the

       Items to	make options out of can	be
	 Hash, Array,
	 Array of CDBI objects.
	 Array of scalars ,
	 Array or  Array refs with cols	from class,
	 Array of hashes

   _options_from_objects ( $objects, $args);
       Private method to makes a options out of	 objects. It attempts to call
       each objects stringify method specified in $args->{stringify} as	the
       content.	Otherwise the default stringification prevails.

       *Note only  single primary keys supported

       Makes a checkbox	element	-- TODO

       Makes a radio button element -- TODO

       _rename_foreign_input($html_el_or_hash_of_them);	# changes made by

       Recursively renames the foreign inputs made by _to_foreign_inputs so
       they can	be processed generically.  It uses foreign_input_delimiter.

       So if an	Employee is a Person who has_many  Addresses and you call and
       the method 'foreign_input_delimiter' returns '__AF__' then


       will get	inputs for the Person as well as their Address (by default,
       override	_field_from_relationship to change logic) named	like this:


       And the processor would know to create this address, put	the address id
       in person->{address} data slot, insert the person and put the person id
       in the employee->{person} data slot and then insert the employee	with
       that data.

       This tells AsForm what to use to	delmit forieign	input names. This is
       important to avoid name clashes as well as automating processing	of

       This functions computes the dimensions of a textarea based on the value
       or the defaults.

       1.0 15-07-2004 -- Initial version =head1	MAINTAINER

       Maypole Developers

       Peter Speltz, Aaron Trevena

       Simon Cozens, Tony Bowden

	 Testing - lots
	 checkbox generalization
	 radio generalization
	 Make link_hidden use standard make_url	stuff when it gets in Maypole
	 How do	you tell AF --"	I want a has_many select box for this every time so,
	    when you call "to_field($this_hasmany)" you	get a select box

       Please direct all correspondence	regarding this module to:
	Maypole	list.

       Copyright 2003-2004 by Simon Cozens / Tony Bowden

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

       Class::DBI, Class::DBI::FromCGI,	HTML::Element.

perl v5.32.1			  2007-05-18   Maypole::Model::CDBI::AsForm(3)


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

home | help