]> git.decadent.org.uk Git - maypole.git/blobdiff - lib/Maypole/Model/CDBI/AsForm.pm
ajt updates, fixed AsForm to pass pod and podcoverage tests, also removed usless...
[maypole.git] / lib / Maypole / Model / CDBI / AsForm.pm
index ef67a06e14ef4c8fd6ec0c2957da8a1e17773876..66ccaf6d507a703f2e3f8e14e126bbbf096487ca 100644 (file)
@@ -11,8 +11,6 @@ package Maypole::Model::CDBI::AsForm;
 #                  -- $class->to_field($has_many_col); # foreign inputs  
 #  $class->search_inputs; /
 
-use 5.006;
-
 use strict;
 use warnings;
 
@@ -32,18 +30,10 @@ our @EXPORT =
                _to_foreign_inputs _to_enum_select _to_bool_select
                _to_hidden _to_link_hidden _rename_foreign_input _to_readonly
                _options_from_objects _options_from_arrays _options_from_hashes 
-               _options_from_scalars _to_select_or_create
+               _options_from_array _options_from_hash _to_select_or_create
     );
-                               
-our @EXPORTOK = 
-       qw( 
-               
-        
-       );
-                                 
-                                 
 
-our $VERSION = '.10'; 
+our $VERSION = '.10';
 
 =head1 NAME
 
@@ -117,13 +107,15 @@ example usages.
   $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.
+
+=over
+
 =item name -- the name the element will have , this trumps the derived name.
 
   $beer->to_field('brewery', 'readonly', {
                name => 'brewery_id'
   });
-  
+
 =item value -- the initial value the element will have, trumps derived value
 
   $beer->to_field('brewery', 'textfield', { 
@@ -199,12 +191,13 @@ static values. You can also specify these in the relationship arguments.
           constraint   => {location  => 'London'},
           'join'       => {'brewery_tablecolumn  => 'beer_obj_column'}, 
          );
-          
+
 =item no_hidden_constraints -- 
 
 Tell AsForm not to make hidden inputs for relationship constraints. It does
 this  sometimes when making foreign inputs . 
 
+=back
 
 =head2 to_cgi
 
@@ -362,6 +355,11 @@ sub search_inputs {
 }
 
 
+=head2 unselect_element
+
+  unselect any selected elemets in a HTML::Element select list widget
+
+=cut
 
 #
 sub unselect_element {
@@ -462,7 +460,8 @@ sub _field_from_relationship {
        }
        return;
 }
-                       
+
+
 =head2 _field_from_column($field, $args)
 
 Returns an input based on the column's characteristics, namely type, or nothing.
@@ -653,7 +652,7 @@ sub _to_select {
     my ($self, $col, $args) = @_;
     $args ||= {};
 # Do we have items already ? Go no further. 
-    if ($args->{items} and @{$args->{items}}) {  
+    if ($args->{items} and ref $args->{items}) {  
                my $a = $self->_select_guts($col,  $args);
        $OLD_STYLE && return $a->as_HTML;
                if ($args->{multiple}) { $a->attr('multiple', 'multiple');}
@@ -1083,9 +1082,12 @@ sub _hash_selected {
 Internal api  method to make the actual select box form elements.
 
 3 types of lists making for -- 
+  Hash, Array, 
   Array of CDBI objects.
   Array of scalars , 
-  Array or  Array refs with cols from class.
+  Array or  Array refs with cols from class,
+  Array of hashes 
+
 =cut
 
 
@@ -1106,37 +1108,39 @@ sub _select_guts {
         $a->push_content($null_element);
     }
 
-    my $items = $args->{items};
-    my $proto = $items->[0];
-    my $type  = ref $proto || '';
-
-    # Objects 
-    if (not $type) {
-               $a->push_content($self->_options_from_scalars($items, $args));
-       }
-       elsif($type !~ /ARRAY|HASH/i) {
-               # make select  of objects
-               $a->push_content($self->_options_from_objects($items, $args));
-       }
-    elsif ($type =~ /ARRAY/i) {
-               $a->push_content($self->_options_from_arrays($items, $args));
+       my $items = $args->{items};
+    my $type = ref $items;
+       my $proto = eval { ref $items->[0]; } || "";
+       warn "Type is $type, proto is $proto\n";
+    # Single Hash
+    if ($type eq 'HASH') {
+        $a->push_content($self->_options_from_hash($items, $args));
+    }
+    # Single Array
+    elsif ( $type eq 'ARRAY' and not ref $items->[0] ) {
+        $a->push_content($self->_options_from_array($items, $args));
+    }
+    # Array of Objects
+    elsif( $type eq 'ARRAY' and $proto !~ /ARRAY|HASH/i ) {
+        # make select  of objects
+        $a->push_content($self->_options_from_objects($items, $args));
     }
-    elsif ($type =~ /HASH/i) { 
-               $a->push_content($self->_options_from_hashes($items, $args));
+    # Array of Arrays
+    elsif ( $type eq 'ARRAY' and $proto eq 'ARRAY' ) {
+        $a->push_content($self->_options_from_arrays($items, $args));
     }
-    else { 
-               die "You passed a weird type of data structure to me. Here it is: $type";
+    # Array of Hashes
+    elsif ( $type eq 'ARRAY' and $proto eq 'HASH' ) {
+        $a->push_content($self->_options_from_hashes($items, $args));
+    }
+    else {
+        die "You passed a weird type of data structure to me. Here it is: " .
+       Dumper($items );
     }
 
     return $a;
 }
 
-               
-  
-  
-
-
-
 =head2 _options_from_objects ( $objects, $args);
 
 Private method to makes a options out of  objects. It attempts to call each
@@ -1181,20 +1185,39 @@ sub _options_from_arrays {
     return @res;
 }
 
-sub _options_from_scalars {
+
+sub _options_from_array {
     my ($self, $items, $args) = @_;
-       my $selected = $args->{selected} || {};
+    my $selected = $args->{selected} || {};
     my @res;
-       for (@$items) {
-               my $opt = HTML::Element->new("option", value => $_ );
-               #$opt->attr(selected => "selected") if $selected =~/^$id$/;
-               $opt->attr(selected => "selected") if $selected->{$_};
-               $opt->push_content( $_ );
-        push @res, $opt; 
+    for (@$items) {
+        my $opt = HTML::Element->new("option", value => $_ );
+        #$opt->attr(selected => "selected") if $selected =~/^$id$/;
+        $opt->attr(selected => "selected") if $selected->{$_};
+        $opt->push_content( $_ );
+        push @res, $opt;
+    }
+    return @res;
+}
+
+sub _options_from_hash {
+    my ($self, $items, $args) = @_;
+    my $selected = $args->{selected} || {};
+    my @res;
+
+    my @values = values %$items;
+    # hash Key is the option content  and the hash value is option value
+    for (sort keys %$items) {
+        my $opt = HTML::Element->new("option", value => $items->{$_} );
+        #$opt->attr(selected => "selected") if $selected =~/^$id$/;
+        $opt->attr(selected => "selected") if $selected->{$items->{$_}};
+        $opt->push_content( $_ );
+        push @res, $opt;
     }
     return @res;
 }
 
+
 sub _options_from_hashes {
     my ($self, $items, $args) = @_;
        my $selected = $args->{selected} || {};
@@ -1206,7 +1229,7 @@ sub _options_from_hashes {
                my $val = $_->{$pk};
                my $opt = HTML::Element->new("option", value => $val );
                $opt->attr(selected => "selected") if $selected->{$val};
-               my $content = $fclass and $stringify and $fclass->can($stringify) ? 
+               my $content = ($fclass and $stringify and $fclass->can($stringify)) ? 
                              $fclass->$stringify($_) : 
                                  join(' ', @$_);
                $opt->push_content( $content );
@@ -1223,12 +1246,9 @@ sub _to_select_or_create {
        my $create = $self->to_field($col, 'foreign_inputs', $args);
        $create->{'__select_or_create__'} = 
                $self->to_field('__select_or_create__',{ name => '__select_or_create__' , value => 1 } );
-               
        return ($select, $create);
 }
-               
-       
-       
+
 # 
 # checkboxes: if no data in hand (ie called as class method), replace
 # with a radio button, in order to allow this field to be left
@@ -1241,7 +1261,6 @@ sub _to_select_or_create {
 sub _to_checkbox {
     my ($self, $col, $args) = @_;
     my $nullable = eval {self->column_nullable($col)} || 0; 
-    
     return $self->_to_radio($col) if !ref($self) || $nullable;
     my $value = $self->$col;
     my $a = HTML::Element->new("input", type=> "checkbox", name => $col);
@@ -1326,7 +1345,8 @@ sub _rename_foreign_input {
                        foreach (keys %$element);
        }
 }
-=head2 _box($value) 
+
+=head2 _box($value)
 
 This functions computes the dimensions of a textarea based on the value 
 or the defaults.
@@ -1334,6 +1354,7 @@ or the defaults.
 =cut
 
 our ($min_rows, $max_rows, $min_cols, $max_cols) = (2 => 50, 20 => 100);
+
 sub _box
 {
     my $text = shift;