The attached patch allows more control over reversing the order of labels and fields, which I've found to be very useful. (Currently, the only option is reverse_multi, which is only for fields within a multi block.)

The patch adds two new options:

reverse_single, in _Field. If reverse_single is true, the label will appear after the field. (Unless the label tag is 'legend'; the legend always appears first within the container tag.) Defaults to false.

reverse_group, in Checkboxgroup and Radiogroup. If reverse_group is true, the label will appear after the field. Defaults to true.


The patch includes documentation and tests. The default values preserve existing behavior. All tests pass, for both string and template rendering.


Feedback appreciated!

thanks,
Ronald
diff -rN -x '*~' -u HTML-FormFu-0.05000/MANIFEST 
HTML-FormFu-0.05000.reverse/MANIFEST
--- HTML-FormFu-0.05000/MANIFEST        2009-05-26 10:22:20.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/MANIFEST        2009-07-02 20:01:23.000000000 
+0000
@@ -437,6 +437,7 @@
 t/elements/repeatable_counter_name.t
 t/elements/repeatable_counter_name.yml
 t/elements/reset.t
+t/elements/reverse_single.t
 t/elements/select.t
 t/elements/select_deflator_default.t
 t/elements/select_empty_first_label.t
diff -rN -x '*~' -u 
HTML-FormFu-0.05000/lib/HTML/FormFu/Element/Checkboxgroup.pm 
HTML-FormFu-0.05000.reverse/lib/HTML/FormFu/Element/Checkboxgroup.pm
--- HTML-FormFu-0.05000/lib/HTML/FormFu/Element/Checkboxgroup.pm        
2009-04-15 08:13:51.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/lib/HTML/FormFu/Element/Checkboxgroup.pm        
2009-07-02 19:32:33.000000000 +0000
@@ -8,7 +8,7 @@
 use HTML::FormFu::Util qw( append_xml_attribute process_attrs );
 use List::MoreUtils qw( any );
 
-__PACKAGE__->mk_item_accessors(qw/ input_type /);
+__PACKAGE__->mk_item_accessors(qw/ reverse_group input_type /);
 
 sub new {
     my $self = shift->next::method(@_);
@@ -18,6 +18,7 @@
     $self->label_tag('legend');
     $self->container_tag('fieldset');
     $self->multi_value(1);
+    $self->reverse_group(1);
     $self->input_type('checkbox');
 
     return $self;
@@ -112,6 +113,7 @@
 
     my $render = $self->next::method( {
             field_filename => $self->field_filename,
+            reverse_group  => $self->reverse_group,
             input_type     => $self->input_type,
             $args ? %$args : (),
         } );
@@ -140,38 +142,63 @@
 
             for my $item ( @{ $option->{group} } ) {
                 $html .= sprintf
-                    qq{<span%s>\n<input name="%s" type="%s" value="%s"%s />},
-                    process_attrs( $item->{container_attributes} ),
+                    "<span%s>\n",
+                    process_attrs( $item->{container_attributes} );
+
+                my $label = sprintf
+                    "<label%s>%s</label>\n",
+                    process_attrs( $item->{label_attributes} ),
+                    $item->{label},
+                    ;
+
+                my $input = sprintf
+                    qq{<input name="%s" type="%s" value="%s"%s />\n},
                     $render->{nested_name},
                     $render->{input_type},
                     $item->{value},
                     process_attrs( $item->{attributes} ),
                     ;
 
-                $html .= sprintf
-                    "\n<label%s>%s</label>\n</span>\n",
-                    process_attrs( $item->{label_attributes} ),
-                    $item->{label},
-                    ;
+                if ( $render->{reverse_group} ) {
+                    $html .= $input . $label;
+                }
+                else {
+                    $html .= $label . $input;
+                }
+
+                $html .= "</span>\n";
             }
 
             $html .= "</span>\n";
         }
         else {
             $html .= sprintf
-                qq{<span%s>\n<input name="%s" type="%s" value="%s"%s />},
-                process_attrs( $option->{container_attributes} ),
+                "<span%s>\n",
+                process_attrs( $option->{container_attributes} )
+                ;
+
+            my $label = sprintf
+                "<label%s>%s</label>\n",
+                process_attrs( $option->{label_attributes} ),
+                $option->{label},
+                ;
+
+            my $input = sprintf
+                qq{<input name="%s" type="%s" value="%s"%s />\n},
                 $render->{nested_name},
                 $render->{input_type},
                 $option->{value},
                 process_attrs( $option->{attributes} ),
                 ;
 
-            $html .= sprintf
-                "\n<label%s>%s</label>\n</span>\n",
-                process_attrs( $option->{label_attributes} ),
-                $option->{label},
-                ;
+            if ( $render->{reverse_group} ) {
+                $html .= $input . $label;
+            }
+            else {
+                $html .= $label . $input;
+            }
+
+            $html .= "</span>\n";
         }
     }
 
@@ -235,6 +262,18 @@
       name: foo
       auto_id: "%n_%c"
 
+=head2 reverse_group
+
+If true, then the label for each checkbox in the checkbox group should
+be rendered to the right of the field control.  Otherwise, the label
+is rendered to the left of the field control.
+
+The default value is C<true>, causing each label to be rendered to the
+right of its field control (or to be explicit: the markup for the
+label comes after the field control in the source).
+
+Default Value: C<true>
+
 =head1 SEE ALSO
 
 Is a sub-class of, and inherits methods from 
diff -rN -x '*~' -u HTML-FormFu-0.05000/lib/HTML/FormFu/Element/Radiogroup.pm 
HTML-FormFu-0.05000.reverse/lib/HTML/FormFu/Element/Radiogroup.pm
--- HTML-FormFu-0.05000/lib/HTML/FormFu/Element/Radiogroup.pm   2009-04-15 
08:13:51.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/lib/HTML/FormFu/Element/Radiogroup.pm   
2009-07-02 16:05:57.000000000 +0000
@@ -75,6 +75,10 @@
       name: foo
       auto_id: "%n_%c"
 
+=head2 reverse_group
+
+See L<HTML::FormFu::Element::Checkboxgroup/reverse_group>.
+
 =head1 SEE ALSO
 
 Is a sub-class of, and inherits methods from 
diff -rN -x '*~' -u HTML-FormFu-0.05000/lib/HTML/FormFu/Element/_Field.pm 
HTML-FormFu-0.05000.reverse/lib/HTML/FormFu/Element/_Field.pm
--- HTML-FormFu-0.05000/lib/HTML/FormFu/Element/_Field.pm       2009-05-26 
10:12:24.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/lib/HTML/FormFu/Element/_Field.pm       
2009-07-02 19:17:34.000000000 +0000
@@ -49,7 +49,8 @@
         label_filename              label_tag
         retain_default              force_default
         javascript                  non_param
-        reverse_multi               multi_value
+        reverse_single              reverse_multi
+        multi_value
         original_name               original_nested_name
 ) );
 
@@ -614,6 +615,7 @@
             label_filename       => $self->label_filename,
             label_tag            => $self->label_tag,
             container_tag        => $self->container_tag,
+            reverse_single       => $self->reverse_single,
             reverse_multi        => $self->reverse_multi,
             javascript           => $self->javascript,
             $args ? %$args : (),
@@ -923,7 +925,8 @@
         }
     }
 
-    if ( defined $render->{label} && $render->{label_tag} ne 'legend' ) {
+    if ( defined $render->{label} && $render->{label_tag} ne 'legend' &&
+         !$render->{reverse_single} ) {
         $html .= sprintf "\n%s", $self->_string_label($render);
     }
 
@@ -956,6 +959,11 @@
 
     my $html = '';
 
+    if ( defined $render->{label} && $render->{label_tag} ne 'legend' &&
+         $render->{reverse_single} ) {
+        $html .= sprintf "\n%s", $self->_string_label($render);
+    }
+
     if ( defined $render->{comment} ) {
         $html .= sprintf "\n<span%s>\n%s\n</span>",
             process_attrs( $render->{comment_attributes} ),
@@ -1318,11 +1326,28 @@
 
 Default Value: C<false>
 
+=head2 reverse_single
+
+If true, then the field's label should be rendered to the right of the
+field control.  (When the field is used within a
+L<Multi|HTML::FormFu::Element::Multi> block, the position of the label
+is controlled by the L</reverse_multi> option instead.)
+
+The default value is C<false>, causing the label to be rendered to the left
+of the field control (or to be explicit: the markup for the label comes
+before the field control in the source).
+
+Exception: If the label tag is 'legend', then the reverse attribute is
+ignored; the legend always appears as the first tag within the
+container tag.
+
+Default Value: C<false>
+
 =head2 reverse_multi
 
 If true, then when the field is used within a 
 L<Multi|HTML::FormFu::Element::Multi> block, the field's label should be 
-rendered to the right of the field control
+rendered to the right of the field control.
 
 The default value is C<false>, causing the label to be rendered to the left
 of the field control (or to be explicit: the markup for the label comes 
diff -rN -x '*~' -u 
HTML-FormFu-0.05000/share/templates/tt/xhtml/checkboxgroup_tag 
HTML-FormFu-0.05000.reverse/share/templates/tt/xhtml/checkboxgroup_tag
--- HTML-FormFu-0.05000/share/templates/tt/xhtml/checkboxgroup_tag      
2009-05-18 14:45:16.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/share/templates/tt/xhtml/checkboxgroup_tag      
2009-07-02 19:46:04.000000000 +0000
@@ -1,12 +1,14 @@
 <span[% process_attrs(self.attributes) %]>
 [% FOREACH option = self.options %][% IF option.group %]<span[% 
process_attrs(option.attributes) %]>
 [% FOREACH item = option.group %]<span[% 
process_attrs(item.container_attributes) %]>
-<input name="[% self.nested_name %]" type="[% self.input_type %]" value="[% 
item.value %]"[% process_attrs(item.attributes) %] />
-<label[% process_attrs(item.label_attributes) %]>[% item.label %]</label>
+[% IF self.reverse_group %]<input name="[% self.nested_name %]" type="[% 
self.input_type %]" value="[% item.value %]"[% process_attrs(item.attributes) 
%] />
+<label[% process_attrs(item.label_attributes) %]>[% item.label%]</label>[% 
ELSE %]<label[% process_attrs(item.label_attributes) %]>[% item.label%]</label>
+<input name="[% self.nested_name %]" type="[% self.input_type %]" value="[% 
item.value %]"[% process_attrs(item.attributes) %] />[% END %]
 </span>
 [% END %]</span>
 [% ELSE %]<span[% process_attrs(option.container_attributes) %]>
-<input name="[% self.nested_name %]" type="[% self.input_type %]" value="[% 
option.value %]"[% process_attrs(option.attributes) %] />
-<label[% process_attrs(option.label_attributes) %]>[% option.label %]</label>
+[% IF self.reverse_group %]<input name="[% self.nested_name %]" type="[% 
self.input_type %]" value="[% option.value %]"[% 
process_attrs(option.attributes) %] />
+<label[% process_attrs(option.label_attributes) %]>[% option.label 
%]</label>[% ELSE %]<label[% process_attrs(option.label_attributes) %]>[% 
option.label %]</label>
+<input name="[% self.nested_name %]" type="[% self.input_type %]" value="[% 
option.value %]"[% process_attrs(option.attributes) %] />[% END %]
 </span>
 [% END %][% END %]</span>
\ No newline at end of file
diff -rN -x '*~' -u HTML-FormFu-0.05000/share/templates/tt/xhtml/field 
HTML-FormFu-0.05000.reverse/share/templates/tt/xhtml/field
--- HTML-FormFu-0.05000/share/templates/tt/xhtml/field  2009-05-18 
14:45:16.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/share/templates/tt/xhtml/field  2009-07-02 
19:41:53.000000000 +0000
@@ -1,8 +1,9 @@
 [% IF self.container_tag.defined %]<[% self.container_tag %][% 
process_attrs(self.container_attributes) %]>[% END %][% IF self.label.defined 
&& self.label_tag == 'legend' %]
 [% INCLUDE $self.label_filename %][% END %][% IF self.errors %][% FOREACH 
error = self.errors %]
-<span class="error_message [% error.class %]">[% error.message %]</span>[% END 
%][% END %][% IF self.label.defined && self.label_tag != 'legend' %]
+<span class="error_message [% error.class %]">[% error.message %]</span>[% END 
%][% END %][% IF self.label.defined && self.label_tag != 'legend' && 
!self.reverse_single %]
 [% INCLUDE $self.label_filename %][% END %][% IF self.container_tag.defined %]
-[% END %][% content %][% IF self.comment.defined %]
+[% END %][% content %][% IF self.label.defined && self.label_tag != 'legend' 
&& self.reverse_single %]
+[% INCLUDE $self.label_filename %][% END %][% IF self.comment.defined %]
 <span[% process_attrs(self.comment_attributes) %]>
 [% self.comment %]
 </span>[% END %][% IF self.container_tag.defined %]
diff -rN -x '*~' -u HTML-FormFu-0.05000/t/elements/checkboxgroup.t 
HTML-FormFu-0.05000.reverse/t/elements/checkboxgroup.t
--- HTML-FormFu-0.05000/t/elements/checkboxgroup.t      2009-03-10 
09:00:28.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/t/elements/checkboxgroup.t      2009-07-02 
18:27:53.000000000 +0000
@@ -1,24 +1,28 @@
 use strict;
 use warnings;
 
-use Test::More tests => 4;
+use Test::More tests => 5;
 
 use HTML::FormFu;
 
 my $form = HTML::FormFu->new({ tt_args => { INCLUDE_PATH => 
'share/templates/tt/xhtml' } });
 
-my $field = $form->element('Checkboxgroup')->name('foo')->value(2)
+my $field1 = $form->element('Checkboxgroup')->name('foo')->value(2)
     ->options( [ [ 1 => 'One' ], [ 2 => 'Two' ] ] );
 
+# add element to test non-reversed labels
+my $field2 = $form->element('Checkboxgroup')->name('foo2')
+    ->options( [ [ 'a' => 'A' ], [ 'b' => 'B' ] ] )->reverse_group(0);
+
 # add more elements to test accessor output
-$form->element('Checkboxgroup')->name('foo2')->options( [
+$form->element('Checkboxgroup')->name('foo3')->options( [
         { label => 'Ein',  value => 1 },
         { label => 'Zwei', value => 2, attributes => { class => 'foobar' } },
     ] );
 $form->element('Checkboxgroup')->name('bar')->values( [qw/ one two three /] )
     ->value('two')->label('My Bar');
 
-my $field_xhtml = qq{<fieldset class="checkboxgroup">
+my $field1_xhtml = qq{<fieldset class="checkboxgroup">
 <span>
 <span>
 <input name="foo" type="checkbox" value="1" />
@@ -31,19 +35,35 @@
 </span>
 </fieldset>};
 
-is( "$field", $field_xhtml );
+is( "$field1", $field1_xhtml );
+
+my $field2_xhtml = qq{<fieldset class="checkboxgroup">
+<span>
+<span>
+<label>A</label>
+<input name="foo2" type="checkbox" value="a" />
+</span>
+<span>
+<label>B</label>
+<input name="foo2" type="checkbox" value="b" />
+</span>
+</span>
+</fieldset>};
+
+is( "$field2", $field2_xhtml );
 
 my $form_xhtml = <<EOF;
 <form action="" method="post">
-$field_xhtml
+$field1_xhtml
+$field2_xhtml
 <fieldset class="checkboxgroup">
 <span>
 <span>
-<input name="foo2" type="checkbox" value="1" />
+<input name="foo3" type="checkbox" value="1" />
 <label>Ein</label>
 </span>
 <span>
-<input name="foo2" type="checkbox" value="2" class="foobar" />
+<input name="foo3" type="checkbox" value="2" class="foobar" />
 <label>Zwei</label>
 </span>
 </span>
diff -rN -x '*~' -u HTML-FormFu-0.05000/t/elements/radiogroup.t 
HTML-FormFu-0.05000.reverse/t/elements/radiogroup.t
--- HTML-FormFu-0.05000/t/elements/radiogroup.t 2009-03-10 09:00:28.000000000 
+0000
+++ HTML-FormFu-0.05000.reverse/t/elements/radiogroup.t 2009-07-02 
18:29:49.000000000 +0000
@@ -1,17 +1,21 @@
 use strict;
 use warnings;
 
-use Test::More tests => 4;
+use Test::More tests => 5;
 
 use HTML::FormFu;
 
 my $form = HTML::FormFu->new({ tt_args => { INCLUDE_PATH => 
'share/templates/tt/xhtml' } });
 
-my $field = $form->element('Radiogroup')->name('foo')->value(2)
+my $field1 = $form->element('Radiogroup')->name('foo')->value(2)
     ->options( [ [ 1 => 'One' ], [ 2 => 'Two' ] ] );
 
+# add element to test non-reversed labels
+my $field2 = $form->element('Radiogroup')->name('foo2')
+    ->options( [ [ 'a' => 'A' ], [ 'b' => 'B' ] ] )->reverse_group(0);
+
 # add more elements to test accessor output
-$form->element('Radiogroup')->name('foo2')->options( [
+$form->element('Radiogroup')->name('foo3')->options( [
         { label => 'Ein',  value => 1 },
         { label => 'Zwei', value => 2, attributes => { class => 'foobar' }, 
container_attributes => { class => 'item 2' } },
     ] );
@@ -19,7 +23,7 @@
 $form->element('Radiogroup')->name('bar')->values( [qw/ one two three /] )
     ->value('two')->label('My Bar');
 
-my $field_xhtml = qq{<fieldset class="radiogroup">
+my $field1_xhtml = qq{<fieldset class="radiogroup">
 <span>
 <span>
 <input name="foo" type="radio" value="1" />
@@ -32,19 +36,35 @@
 </span>
 </fieldset>};
 
-is( "$field", $field_xhtml );
+is( "$field1", $field1_xhtml );
+
+my $field2_xhtml = qq{<fieldset class="radiogroup">
+<span>
+<span>
+<label>A</label>
+<input name="foo2" type="radio" value="a" />
+</span>
+<span>
+<label>B</label>
+<input name="foo2" type="radio" value="b" />
+</span>
+</span>
+</fieldset>};
+
+is( "$field2", $field2_xhtml );
 
 my $form_xhtml = <<EOF;
 <form action="" method="post">
-$field_xhtml
+$field1_xhtml
+$field2_xhtml
 <fieldset class="radiogroup">
 <span>
 <span>
-<input name="foo2" type="radio" value="1" />
+<input name="foo3" type="radio" value="1" />
 <label>Ein</label>
 </span>
 <span class="item 2">
-<input name="foo2" type="radio" value="2" class="foobar" />
+<input name="foo3" type="radio" value="2" class="foobar" />
 <label>Zwei</label>
 </span>
 </span>
diff -rN -x '*~' -u HTML-FormFu-0.05000/t/elements/reverse_single.t 
HTML-FormFu-0.05000.reverse/t/elements/reverse_single.t
--- HTML-FormFu-0.05000/t/elements/reverse_single.t     1970-01-01 
00:00:00.000000000 +0000
+++ HTML-FormFu-0.05000.reverse/t/elements/reverse_single.t     2009-07-02 
18:34:19.000000000 +0000
@@ -0,0 +1,18 @@
+use strict;
+use warnings;
+
+use Test::More tests => 1;
+
+use HTML::FormFu;
+
+my $form = HTML::FormFu->new({ tt_args => { INCLUDE_PATH => 
'share/templates/tt/xhtml' } });
+
+my $field = $form->element('Text')->name('foo')->label('My Foo')
+    ->reverse_single(1);
+
+my $field_xhtml = qq{<div class="text label">
+<input name="foo" type="text" />
+<label>My Foo</label>
+</div>};
+
+is( "$field", $field_xhtml );
_______________________________________________
HTML-FormFu mailing list
HTML-FormFu@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu

Reply via email to