X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=lib%2FMaypole%2FModel%2FCDBI%2FAsForm.pm;h=f1fe978b1c36e7273f883d54a364cda003ec97ae;hb=c3973978e1373a262d13da63c9e9ecfde4b72cc7;hp=9feed0d6fcaaf09f1f1f35d26ac1f3d5e6aef2d6;hpb=f8e4b72969011ae26de5b52a212a9e5498c58c14;p=maypole.git diff --git a/lib/Maypole/Model/CDBI/AsForm.pm b/lib/Maypole/Model/CDBI/AsForm.pm index 9feed0d..f1fe978 100644 --- a/lib/Maypole/Model/CDBI/AsForm.pm +++ b/lib/Maypole/Model/CDBI/AsForm.pm @@ -25,7 +25,7 @@ our $OLD_STYLE = 0; # pjs -- Added new methods to @EXPORT our @EXPORT = qw( - to_cgi to_field make_element_foreign search_inputs unselect_element + to_cgi to_field foreign_input_delimiter search_inputs unselect_element _field_from_how _field_from_relationship _field_from_column _to_textarea _to_textfield _to_select _select_guts _to_foreign_inputs _to_enum_select _to_bool_select @@ -33,7 +33,7 @@ our @EXPORT = _options_from_objects _options_from_arrays _options_from_hashes _options_from_array _options_from_hash ); - + our $VERSION = '.10'; =head1 NAME @@ -229,7 +229,9 @@ sub to_cgi { my ($class, @columns) = @_; # pjs -- added columns arg my $args = {}; if (not @columns) { - @columns = $class->columns; + @columns = $class->columns; + # Eventually after stabalization, we could add display_columns + #keys map { $_ => 1 } ($class->display_columns, $class->columns); } else { if ( ref $columns[-1] eq 'HASH' ) { $args = pop @columns; } @@ -240,8 +242,10 @@ sub to_cgi { =head2 to_field($field [, $how][, $args]) This maps an individual column to a form element. The C argument -can be used to force the field type into any you want. It tells AsForm how -to make the input ie-- forces it to use the method "_to_$how". +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. Override them at will. + If C 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. @@ -430,7 +434,8 @@ sub _field_from_relationship { if (not $rel_meta->{args}{no_select} and not $args->{no_select}) { $args->{class} = $fclass; - $args->{items} = $self->$field; + my @itms = $self->$field; # need list not iterator + $args->{items} = \@itms; return $self->_to_select($field, $args); } return; @@ -647,7 +652,7 @@ sub _to_textfield { sub _to_select { my ($self, $col, $args) = @_; $args ||= {}; -# Do we have items already ? Go no further. + # Do we have items already ? Go no further. if ($args->{items} and ref $args->{items}) { my $a = $self->_select_guts($col, $args); $OLD_STYLE && return $a->as_HTML; @@ -655,7 +660,7 @@ sub _to_select { return $a; } -# Else what are we making a select box out of ? + # Else what are we making a select box out of ? # No Column parameter -- means making a select box of args->class or self # Using all rows from class's table if (not $col) { @@ -673,7 +678,7 @@ sub _to_select { # related objects pre selected if object # "Has many" -- Issues: - # 1) want to select one from list if self is an object + # 1) want to select one or many from list if self is an object # Thats about all we can do really, # 2) except for mapping which is TODO and would # do something like add to and take away from list of permissions for @@ -681,7 +686,8 @@ sub _to_select { # Hasmany select one from list if ref self if ($rel_meta->{name} =~ /has_many/i and ref $self) { - $args->{items} = [ $self->$col ]; + my @itms = $self->$col; # need list not iterator + $args->{items} = \@itms; my $a = $self->_select_guts($col, $args); $OLD_STYLE && return $a->as_HTML; return $a; @@ -1024,12 +1030,15 @@ Below handles these formats for the "selected" slot in the arguments hash: sub _hash_selected { my ($args) = shift; my $selected = $args->{value} || $args->{selected}; - return $selected unless $selected and ref $selected ne 'HASH'; - #warn "Selected dump : " . Dumper($selected); + #warn "**** SELECTED is $selected ****"; my $type = ref $selected; + return $selected unless $selected and $type ne 'HASH'; + #warn "Selected dump : " . Dumper($selected); # Single Object if ($type and $type ne 'ARRAY') { - return {$selected->id => 1}; + my $id = $selected->id; + $id =~ s/^0*//; + return {$id => 1}; } # Single Scalar id elsif (not $type) { @@ -1085,6 +1094,7 @@ sub _select_guts { my ($self, $col, $args) = @_; #$nullable, $selected_id, $values) = @_; #$args->{stringify} ||= 'stringify_selectbox'; + $args->{selected} = _hash_selected($args) if defined $args->{selected}; my $name = $args->{name} || $col; my $a = HTML::Element->new('select', name => $name); @@ -1157,8 +1167,10 @@ sub _options_from_objects { my $stringify = $args->{stringify} || ''; my @res; for (@$items) { - my $opt = HTML::Element->new("option", value => $_->id); - $opt->attr(selected => "selected") if $selected->{$_->id}; + my $id = $_->id; + my $opt = HTML::Element->new("option", value => $id); + $id =~ s/^0*//; # leading zeros no good in hash key + $opt->attr(selected => "selected") if $selected->{$id}; my $content = $stringify ? $_->stringify : "$_"; $opt->push_content($content); push @res, $opt; @@ -1307,52 +1319,48 @@ sub _to_radio { _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. The format is "accessor__AsForeign_colname". +can be processed generically. It uses foreign_input_delimiter. -So if an Employee is a Person who has_own Address and you call +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") + Employee->to_field("person"); -then you will get inputs for the Person as well as their Address (by default, +will get inputs for the Person as well as their Address (by default, override _field_from_relationship to change logic) named like this: - person__AsForeign__address__AsForeign__street - person__AsForeign__address__AsForeign__city - person__AsForeign__address__AsForeign__state - person__AsForeign__address__AsForeign__zip + 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, create the person and put the person id in the employee->person data slot and then create the employee with that data. - -Overriede make_element_foreign to change how you want a foreign param labeled. - -=head2 make_element_foreign - - $class->make_element_foreign($accessor, $element); - -Makes an HTML::Element type object foreign elemen representing the -class's accessor. (IE this in an input element for $class->accessor :) ) +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. =cut -sub make_element_foreign { - my ($self, $accssr, $element) = @_; - $element->attr( name => $accssr . "__AsForeign__" . $element->attr('name')); -} - - - sub _rename_foreign_input { my ($self, $accssr, $element) = @_; + my $del = $self->foreign_input_delimiter; + if ( ref $element ne 'HASH' ) { - # my $new_name = $accssr . "__AsForeign__" . $input->attr('name'); - $self->make_element_foreign($accssr, $element); + # my $new_name = $accssr . "__AF__" . $input->attr('name'); + $element->attr( name => $accssr . $del . $element->attr('name')); } else { $self->_rename_foreign_input($accssr, $element->{$_}) foreach (keys %$element); } } + +=head2 foreign_input_delimiter + +This tells AsForm what to use to delmit forieign_input names with. The name has the form -- $foreign_accessor. $DELIMITER . $foreign_column + +=cut + +sub foreign_input_delimiter { '__AF__' }; + =head2 _box($value) This functions computes the dimensions of a textarea based on the value @@ -1360,9 +1368,10 @@ or the defaults. =cut -our ($min_rows, $max_rows, $min_cols, $max_cols) = (2 => 50, 20 => 100); sub _box { + + my ($min_rows, $max_rows, $min_cols, $max_cols) = (2 => 50, 20 => 100); my $text = shift; if ($text) { my @rows = split /^/, $text;