[html-formfu] Date field_order, new patch

Ronald J Kimball rkimball+formfu at pangeamedia.com
Mon Nov 3 19:14:35 GMT 2008


Attached is a revised patch for my proposed change to allow reordering =

the sub fields in a Date element.  This is accomplished using =

field_order, based on Deflator::CompoundDateTime, as Carl originally =

suggested.

The field_order must include each sub field (year, month, day) exactly =

once.  Although it could be useful to show only some of the sub fields =

(e.g. year, month for credit card expiration), doing so results in =

errors from the various DateTime inflators because of the missing values.

The patch includes tests for various field_order values, both valid and =

invalid.

(Original thread here: =

http://lists.scsys.co.uk/pipermail/html-formfu/2008-October/001436.html)

Ronald
-------------- next part --------------
diff -ruN HTML-FormFu-0.03005.orig/MANIFEST HTML-FormFu-0.03005/MANIFEST
--- HTML-FormFu-0.03005.orig/MANIFEST	2008-09-08 09:56:24.000000000 -0400
+++ HTML-FormFu-0.03005/MANIFEST	2008-11-03 13:50:55.000000000 -0500
@@ -344,6 +344,8 @@
 t/elements/content_button.t
 t/elements/date.t
 t/elements/date_default.t
+t/elements/date_order.t
+t/elements/date_order_error.t
 t/elements/date_natural.t
 t/elements/date_rename.t
 t/elements/field_default_empty_value.t
diff -ruN HTML-FormFu-0.03005.orig/lib/HTML/FormFu/Element/Date.pm HTML-For=
mFu-0.03005/lib/HTML/FormFu/Element/Date.pm
--- HTML-FormFu-0.03005.orig/lib/HTML/FormFu/Element/Date.pm	2008-09-05 05:=
01:34.000000000 -0400
+++ HTML-FormFu-0.03005/lib/HTML/FormFu/Element/Date.pm	2008-11-03 13:55:16=
.000000000 -0500
@@ -10,11 +10,19 @@
 use DateTime::Format::Natural;
 use DateTime::Locale;
 use Scalar::Util qw( blessed );
+use List::MoreUtils qw( none uniq );
 use Carp qw( croak );
 =

 __PACKAGE__->mk_attrs( qw( day  month  year ) );
 =

-__PACKAGE__->mk_item_accessors( qw( strftime auto_inflate default_natural =
) );
+__PACKAGE__->mk_item_accessors( qw(
+    strftime
+    auto_inflate
+    default_natural
+    field_order
+) );
+
+my @known_fields =3D qw( year month day );
 =

 *default =3D \&value;
 =

@@ -81,9 +89,22 @@
         if ( @{ $self->_elements } ) {
             $self->_date_defaults;
 =

-            $self->_elements->[0]->default( $self->day->{default} );
-            $self->_elements->[1]->default( $self->month->{default} );
-            $self->_elements->[2]->default( $self->year->{default} );
+            if ( defined( my $order =3D $self->field_order ) ) {
+                croak "invalid DateTime field_order"
+                    if @$order !=3D 3 || uniq(@$order) !=3D 3;
+                for my $i (0 .. $#$order) {
+                    my $order =3D $order->[$i];
+                    croak "unknown DateTime field_order name"
+                        if none { $order eq $_ } @known_fields;
+
+                    $self->_elements->[$i]->default( $self->$order->{defau=
lt} );
+                }
+            }
+            else {
+                $self->_elements->[0]->default( $self->day->{default} );
+                $self->_elements->[1]->default( $self->month->{default} );
+                $self->_elements->[2]->default( $self->year->{default} );
+            }
         }
 =

         return $self;
@@ -99,9 +120,23 @@
 =

     $self->_date_defaults;
 =

-    $self->_add_day;
-    $self->_add_month;
-    $self->_add_year;
+    if ( defined( my $order =3D $self->field_order ) ) {
+        croak "invalid DateTime field_order"
+            if @$order !=3D 3 || uniq(@$order) !=3D 3;
+        for my $order (@$order) {
+            croak "unknown DateTime field_order name"
+                if none { $order eq $_ } @known_fields;
+
+            my $method =3D "_add_$order";
+
+            $self->$method;
+        }
+    }
+    else {
+        $self->_add_day;
+        $self->_add_month;
+        $self->_add_year;
+    }
 =

     if ( $self->auto_inflate
         && !@{ $self->get_inflators( { type =3D> "DateTime" } ) } )
@@ -573,6 +608,13 @@
 =

 Default Value: 10
 =

+=3Dhead2 field_order
+
+Arguments: \@order
+
+Specify the order of the date fields in the rendered HTML.  If
+field_order is not specified, the order day, month, year is used.
+
 =3Dhead2 auto_inflate
 =

 If true, a L<DateTime Inflator|HTML::FormFu::Inflator::DateTime> will =

diff -ruN HTML-FormFu-0.03005.orig/t/elements/date_order.t HTML-FormFu-0.03=
005/t/elements/date_order.t
--- HTML-FormFu-0.03005.orig/t/elements/date_order.t	1969-12-31 19:00:00.00=
0000000 -0500
+++ HTML-FormFu-0.03005/t/elements/date_order.t	2008-10-02 18:06:27.0000000=
00 -0400
@@ -0,0 +1,317 @@
+use strict;
+use warnings;
+
+use Test::More tests =3D> 7;
+
+use HTML::FormFu;
+use DateTime;
+
+my $dt =3D DateTime->new( day =3D> 6, month =3D> 8, year =3D> 2007 );
+
+my $form =3D HTML::FormFu->new({ tt_args =3D> { INCLUDE_PATH =3D> 'share/t=
emplates/tt/xhtml' } });
+
+$form->element('Date')->name('foo')->strftime("%m/%d/%Y")
+    ->field_order( [ qw/ month day year / ])
+    ->day( { prefix =3D> '-- Day --', } )->month( {
+        prefix      =3D> '-- Month --',
+        short_names =3D> 1,
+    }
+    )->year( {
+        prefix =3D> '-- Year --',
+        list   =3D> [ 2007 .. 2017 ],
+    } )->default($dt)->auto_inflate(1)->constraint('Required');
+
+$form->element('Date')->name('bar')->default('14-08-2007')
+    ->field_order( [ qw/ year month day / ] )
+    ->year( { list =3D> [ 2007 .. 2017 ] } );
+
+$form->process;
+
+is( "$form", <<HTML );
+<form action=3D"" method=3D"post">
+<div class=3D"date">
+<span class=3D"elements">
+<select name=3D"foo_month">
+<option value=3D"">-- Month --</option>
+<option value=3D"1">Jan</option>
+<option value=3D"2">Feb</option>
+<option value=3D"3">Mar</option>
+<option value=3D"4">Apr</option>
+<option value=3D"5">May</option>
+<option value=3D"6">Jun</option>
+<option value=3D"7">Jul</option>
+<option value=3D"8" selected=3D"selected">Aug</option>
+<option value=3D"9">Sep</option>
+<option value=3D"10">Oct</option>
+<option value=3D"11">Nov</option>
+<option value=3D"12">Dec</option>
+</select>
+<select name=3D"foo_day">
+<option value=3D"">-- Day --</option>
+<option value=3D"1">1</option>
+<option value=3D"2">2</option>
+<option value=3D"3">3</option>
+<option value=3D"4">4</option>
+<option value=3D"5">5</option>
+<option value=3D"6" selected=3D"selected">6</option>
+<option value=3D"7">7</option>
+<option value=3D"8">8</option>
+<option value=3D"9">9</option>
+<option value=3D"10">10</option>
+<option value=3D"11">11</option>
+<option value=3D"12">12</option>
+<option value=3D"13">13</option>
+<option value=3D"14">14</option>
+<option value=3D"15">15</option>
+<option value=3D"16">16</option>
+<option value=3D"17">17</option>
+<option value=3D"18">18</option>
+<option value=3D"19">19</option>
+<option value=3D"20">20</option>
+<option value=3D"21">21</option>
+<option value=3D"22">22</option>
+<option value=3D"23">23</option>
+<option value=3D"24">24</option>
+<option value=3D"25">25</option>
+<option value=3D"26">26</option>
+<option value=3D"27">27</option>
+<option value=3D"28">28</option>
+<option value=3D"29">29</option>
+<option value=3D"30">30</option>
+<option value=3D"31">31</option>
+</select>
+<select name=3D"foo_year">
+<option value=3D"">-- Year --</option>
+<option value=3D"2007" selected=3D"selected">2007</option>
+<option value=3D"2008">2008</option>
+<option value=3D"2009">2009</option>
+<option value=3D"2010">2010</option>
+<option value=3D"2011">2011</option>
+<option value=3D"2012">2012</option>
+<option value=3D"2013">2013</option>
+<option value=3D"2014">2014</option>
+<option value=3D"2015">2015</option>
+<option value=3D"2016">2016</option>
+<option value=3D"2017">2017</option>
+</select>
+</span>
+</div>
+<div class=3D"date">
+<span class=3D"elements">
+<select name=3D"bar_year">
+<option value=3D"2007" selected=3D"selected">2007</option>
+<option value=3D"2008">2008</option>
+<option value=3D"2009">2009</option>
+<option value=3D"2010">2010</option>
+<option value=3D"2011">2011</option>
+<option value=3D"2012">2012</option>
+<option value=3D"2013">2013</option>
+<option value=3D"2014">2014</option>
+<option value=3D"2015">2015</option>
+<option value=3D"2016">2016</option>
+<option value=3D"2017">2017</option>
+</select>
+<select name=3D"bar_month">
+<option value=3D"1">January</option>
+<option value=3D"2">February</option>
+<option value=3D"3">March</option>
+<option value=3D"4">April</option>
+<option value=3D"5">May</option>
+<option value=3D"6">June</option>
+<option value=3D"7">July</option>
+<option value=3D"8" selected=3D"selected">August</option>
+<option value=3D"9">September</option>
+<option value=3D"10">October</option>
+<option value=3D"11">November</option>
+<option value=3D"12">December</option>
+</select>
+<select name=3D"bar_day">
+<option value=3D"1">1</option>
+<option value=3D"2">2</option>
+<option value=3D"3">3</option>
+<option value=3D"4">4</option>
+<option value=3D"5">5</option>
+<option value=3D"6">6</option>
+<option value=3D"7">7</option>
+<option value=3D"8">8</option>
+<option value=3D"9">9</option>
+<option value=3D"10">10</option>
+<option value=3D"11">11</option>
+<option value=3D"12">12</option>
+<option value=3D"13">13</option>
+<option value=3D"14" selected=3D"selected">14</option>
+<option value=3D"15">15</option>
+<option value=3D"16">16</option>
+<option value=3D"17">17</option>
+<option value=3D"18">18</option>
+<option value=3D"19">19</option>
+<option value=3D"20">20</option>
+<option value=3D"21">21</option>
+<option value=3D"22">22</option>
+<option value=3D"23">23</option>
+<option value=3D"24">24</option>
+<option value=3D"25">25</option>
+<option value=3D"26">26</option>
+<option value=3D"27">27</option>
+<option value=3D"28">28</option>
+<option value=3D"29">29</option>
+<option value=3D"30">30</option>
+<option value=3D"31">31</option>
+</select>
+</span>
+</div>
+</form>
+HTML
+
+$form->process( {
+        'foo_day', 30, 'foo_month', 6, 'foo_year', 2007,
+        'bar_day', 1,  'bar_month', 7, 'bar_year', 2007,
+    } );
+
+ok( $form->submitted_and_valid );
+
+my $foo =3D $form->param('foo');
+my $bar =3D $form->param('bar');
+
+isa_ok( $foo, 'DateTime' );
+ok( !ref $bar );
+
+is( $foo, "06/30/2007" );
+is( $bar, "01-07-2007" );
+
+is( "$form", <<HTML );
+<form action=3D"" method=3D"post">
+<div class=3D"date">
+<span class=3D"elements">
+<select name=3D"foo_month">
+<option value=3D"">-- Month --</option>
+<option value=3D"1">Jan</option>
+<option value=3D"2">Feb</option>
+<option value=3D"3">Mar</option>
+<option value=3D"4">Apr</option>
+<option value=3D"5">May</option>
+<option value=3D"6" selected=3D"selected">Jun</option>
+<option value=3D"7">Jul</option>
+<option value=3D"8">Aug</option>
+<option value=3D"9">Sep</option>
+<option value=3D"10">Oct</option>
+<option value=3D"11">Nov</option>
+<option value=3D"12">Dec</option>
+</select>
+<select name=3D"foo_day">
+<option value=3D"">-- Day --</option>
+<option value=3D"1">1</option>
+<option value=3D"2">2</option>
+<option value=3D"3">3</option>
+<option value=3D"4">4</option>
+<option value=3D"5">5</option>
+<option value=3D"6">6</option>
+<option value=3D"7">7</option>
+<option value=3D"8">8</option>
+<option value=3D"9">9</option>
+<option value=3D"10">10</option>
+<option value=3D"11">11</option>
+<option value=3D"12">12</option>
+<option value=3D"13">13</option>
+<option value=3D"14">14</option>
+<option value=3D"15">15</option>
+<option value=3D"16">16</option>
+<option value=3D"17">17</option>
+<option value=3D"18">18</option>
+<option value=3D"19">19</option>
+<option value=3D"20">20</option>
+<option value=3D"21">21</option>
+<option value=3D"22">22</option>
+<option value=3D"23">23</option>
+<option value=3D"24">24</option>
+<option value=3D"25">25</option>
+<option value=3D"26">26</option>
+<option value=3D"27">27</option>
+<option value=3D"28">28</option>
+<option value=3D"29">29</option>
+<option value=3D"30" selected=3D"selected">30</option>
+<option value=3D"31">31</option>
+</select>
+<select name=3D"foo_year">
+<option value=3D"">-- Year --</option>
+<option value=3D"2007" selected=3D"selected">2007</option>
+<option value=3D"2008">2008</option>
+<option value=3D"2009">2009</option>
+<option value=3D"2010">2010</option>
+<option value=3D"2011">2011</option>
+<option value=3D"2012">2012</option>
+<option value=3D"2013">2013</option>
+<option value=3D"2014">2014</option>
+<option value=3D"2015">2015</option>
+<option value=3D"2016">2016</option>
+<option value=3D"2017">2017</option>
+</select>
+</span>
+</div>
+<div class=3D"date">
+<span class=3D"elements">
+<select name=3D"bar_year">
+<option value=3D"2007" selected=3D"selected">2007</option>
+<option value=3D"2008">2008</option>
+<option value=3D"2009">2009</option>
+<option value=3D"2010">2010</option>
+<option value=3D"2011">2011</option>
+<option value=3D"2012">2012</option>
+<option value=3D"2013">2013</option>
+<option value=3D"2014">2014</option>
+<option value=3D"2015">2015</option>
+<option value=3D"2016">2016</option>
+<option value=3D"2017">2017</option>
+</select>
+<select name=3D"bar_month">
+<option value=3D"1">January</option>
+<option value=3D"2">February</option>
+<option value=3D"3">March</option>
+<option value=3D"4">April</option>
+<option value=3D"5">May</option>
+<option value=3D"6">June</option>
+<option value=3D"7" selected=3D"selected">July</option>
+<option value=3D"8">August</option>
+<option value=3D"9">September</option>
+<option value=3D"10">October</option>
+<option value=3D"11">November</option>
+<option value=3D"12">December</option>
+</select>
+<select name=3D"bar_day">
+<option value=3D"1" selected=3D"selected">1</option>
+<option value=3D"2">2</option>
+<option value=3D"3">3</option>
+<option value=3D"4">4</option>
+<option value=3D"5">5</option>
+<option value=3D"6">6</option>
+<option value=3D"7">7</option>
+<option value=3D"8">8</option>
+<option value=3D"9">9</option>
+<option value=3D"10">10</option>
+<option value=3D"11">11</option>
+<option value=3D"12">12</option>
+<option value=3D"13">13</option>
+<option value=3D"14">14</option>
+<option value=3D"15">15</option>
+<option value=3D"16">16</option>
+<option value=3D"17">17</option>
+<option value=3D"18">18</option>
+<option value=3D"19">19</option>
+<option value=3D"20">20</option>
+<option value=3D"21">21</option>
+<option value=3D"22">22</option>
+<option value=3D"23">23</option>
+<option value=3D"24">24</option>
+<option value=3D"25">25</option>
+<option value=3D"26">26</option>
+<option value=3D"27">27</option>
+<option value=3D"28">28</option>
+<option value=3D"29">29</option>
+<option value=3D"30">30</option>
+<option value=3D"31">31</option>
+</select>
+</span>
+</div>
+</form>
+HTML
+
diff -ruN HTML-FormFu-0.03005.orig/t/elements/date_order_error.t HTML-FormF=
u-0.03005/t/elements/date_order_error.t
--- HTML-FormFu-0.03005.orig/t/elements/date_order_error.t	1969-12-31 19:00=
:00.000000000 -0500
+++ HTML-FormFu-0.03005/t/elements/date_order_error.t	2008-11-03 13:46:00.0=
00000000 -0500
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+
+use Test::More tests =3D> 3;
+
+use HTML::FormFu;
+
+my $form =3D HTML::FormFu->new;
+
+eval { $form->element('Date')->field_order( [ qw/ month day foo / ] );
+       $form->process;
+     };
+
+ok($@);
+
+$form =3D HTML::FormFu->new;
+
+eval { $form->element('Date')->field_order( [ qw/ year / ] );
+       $form->process;
+     };
+
+ok($@);
+
+$form =3D HTML::FormFu->new;
+
+eval { my $element =3D $form->element('Date');
+       $form->process;
+       $element->field_order( [qw/ month month day / ] )->value('01-01-200=
7');
+     };
+
+ok($@);


More information about the HTML-FormFu mailing list