Maypole...:AsForm(3)
Maypole::Model::CDBI::AsForm(3) π
okay bestie, welcome to the manual page for Maypole::Model::CDBI::AsForm β part 1 of 2, so don't go anywhere. This is the module that makes HTML form elements for your database columns. No cap, it's iconic. β¨
β¨ NAME β¨
Maypole::Model:CDBI::AsForm - Produce HTML form elements for database columns
(yes, the original has a lil typo with one colon, but we're keeping it real π)
π SYNOPSIS π
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>" }
$class->Columns),
end_form;
}
. . .
# 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 => 'www.maypole.perl.org/brewery/view/'.$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 ..>
...
<label>
<span class="field"> [% classmetadata.colnames.$col %] : </span>
[% object.to_field(col).as_XML %]
</label>
. . .
<label>
<span class="field"> Brewery : </span>
[% object.to_field('brewery', { selected => 23} ).as_XML %]
</label>
. . .
</form>
#####################################################
# 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');
1;
π DESCRIPTION π
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.
π ARGUMENTS HASH π
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 hash.
# 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 box. Can be a simple scalar id, an object, or an array of either.
$beer->to_field('brewery', {
selected => $beer->brewery, # again not necessary since caller is obj.
});
classβ the class for which the input being made for field pertains to. 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_nullableto set this and it defaults to true if there is no such method.
$beer->to_field('brewery', { column_nullable => 1 });
rorrequestβ the Maypole request object.uriβ uri for a link, used in methods such as_to_link_hidden.
$beer->to_field('brewery', 'link_hidden',
{r => $r, uri => 'www.maypole.perl.org/brewery/view/'.$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_byis a simple order by clause andconstraintandjoinare hashes used to limit the rows selected. The difference is thatjoinuses methods of the object andconstraintuses static values. You can also specify these in the relationship definitions. See the relationships documentation of how to set arbitrary 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_relatedmethod should do it.
to_cgi
$self->to_cgi([@columns, $args]);
This returns a hash mapping all the column names to HTML::Element objects representing form widgets. It takes two optional 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}.
search_inputs
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.
Example:
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_element
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 β¨
okay bestie, here's the full menu of stuff you can hand over π
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
and now the three flavors of select box, because obviously there's lore π«Ά
- a select box out of a
has_aorhas_manyrelated class. # Forhas_athe 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 likewhereandorder
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"});
- a select box for objects of arbitrary class -- say
BeerDB::Beerfor fun. # generalBeerDB::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
- 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)],
'select',);
πΈ _to_enum_select
Returns a select box for the an enum column type. cute, tidy, done β¨
π _to_bool_select
Returns a "No/Yes" select box for a boolean column type. two options, zero drama π
π¦ _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. sneaky little thing, no cap π
π _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 self. it's giving "link but also secret payload" π₯
π _to_foreign_inputs
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
β _hash_selected
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'
π _select_guts
Internal api method to make the actual select box form elements. the data.
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
bestie. only single primary keys. that's the limit. respect it π
π§ _to_checkbox
Makes a checkbox element -- TODO
π _to_radio
Makes a radio button element -- TODO
π _rename_foreign_input
_rename_foreign_input($html_el_or_hash_of_them); # changes made by
reference
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
Employee->to_field("person");
will get inputs for the Person as well as their Address (by default, override _field_from_relationship to change logic) named like this:
person__AF__address__AF__street
person__AF__address__AF__city
person__AF__address__AF__state
person__AF__address__AF__zip
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. the way it just threads the whole thing together is lowkey iconic π
πΈ foreign_input_delimiter
This tells AsForm what to use to delmit forieign input names. This is important to avoid name clashes as well as automating processing of forms. iykyk π
π¦ _box($value)
This functions computes the dimensions of a textarea based on the value or the defaults. π
β¨ CHANGES β¨
1.0 15-07-2004 -- Initial version =head1 MAINTAINER
Maypole Developers
π AUTHORS π
Peter Speltz, Aaron Trevena
π AUTHORS EMERITUS π
Simon Cozens, Tony Bowden
π TODO π
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
π BUGS and QUERIES π
Please direct all correspondence regarding this module to: Maypole list.
π COPYRIGHT AND LICENSE π
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.
π«Ά SEE ALSO π«Ά
Class::DBI, Class::DBI::FromCGI, HTML::Element.
and that's a wrap bestie, this page was served up by perl v5.42.0 on 2025-07-25 β go forth and make select boxes that slay π
β¨π
π¦ where this page comes from
- fedora 43: perl-Maypole 1:2.13-46.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms