|
NAMEMaypole::Model:CDBI::AsForm - Produce HTML form elements for database columnsSYNOPSISpackage 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; DESCRIPTIONThis 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 HASHThis 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.
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 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}. search_inputsmy $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_elementunselect 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 argumentsselected => $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)], 'select',); _to_enum_selectReturns a select box for the an enum column type._to_bool_selectReturns 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 self._to_foreign_inputsCreates 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_gutsInternal 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 _to_checkboxMakes a checkbox element -- TODO_to_radioMakes a radio button element -- TODO_rename_foreign_input_rename_foreign_input($html_el_or_hash_of_them); # changes made by referenceRecursively 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. foreign_input_delimiterThis tells AsForm what to use to delmit forieign input names. This is important to avoid name clashes as well as automating processing of forms._box($value)This functions computes the dimensions of a textarea based on the value or the defaults.CHANGES1.0 15-07-2004 -- Initial version =head1 MAINTAINERMaypole Developers AUTHORSPeter Speltz, Aaron TrevenaAUTHORS EMERITUSSimon Cozens, Tony BowdenTODOTesting - 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 QUERIESPlease direct all correspondence regarding this module to: Maypole list.COPYRIGHT AND LICENSECopyright 2003-2004 by Simon Cozens / Tony BowdenThis library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. SEE ALSOClass::DBI, Class::DBI::FromCGI, HTML::Element.
Visit the GSP FreeBSD Man Page Interface. |