]> git.decadent.org.uk Git - maypole.git/blobdiff - lib/Maypole/Model/CDBI/AsForm.pm
Fixed FromCGI and AsForm some more. No official tests in crud.t yet but
[maypole.git] / lib / Maypole / Model / CDBI / AsForm.pm
index 9feed0d6fcaaf09f1f1f35d26ac1f3d5e6aef2d6..f1fe978b1c36e7273f883d54a364cda003ec97ae 100644 (file)
@@ -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<how> 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<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.
@@ -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;