I have a form where I need to put the label before the input for some radio groups, and the label after the input for a checkbox. I found a post in the archives that mentioned reverse_multi:

http://lists.scsys.co.uk/pipermail/html-formfu/2008-March/001016.html


Based on that idea, I've created a patch that does the following:

Makes Radiogroup and Checkboxgroup honor reverse_multi. If reverse_multi is true, which is now the default for those classes, the labels for the radio and checkbox fields will follow the fields (matching the current behavior). If reverse_multi is false, the labels will precede the fields.

Adds a reverse attribute to _Field, which defaults to false. If reverse is true, the label will follow the field; otherwise it will precede the field. However, if the label tag is 'legend', then reverse is ignored and the legend appears in the usual place.

Adds some tests for the new behavior.


The one quirk in this implementation:

If a Radiogroup or Checkboxgroup is included within a Multi, then reverse_multi would, I think, affect both the individual field labels and the overall group label. This could be avoided by adding a new attribute specifically for the individual field labels in a group (e.g. reverse_group).


Is this an acceptable patch?  Feedback, please!

thanks,
Ronald


diff -rN -x '*~' -u 
HTML-FormFu-0.03001.orig/lib/HTML/FormFu/Element/Checkboxgroup.pm 
HTML-FormFu-0.03001/lib/HTML/FormFu/Element/Checkboxgroup.pm
--- HTML-FormFu-0.03001.orig/lib/HTML/FormFu/Element/Checkboxgroup.pm   
2008-06-05 10:02:41.000000000 -0400
+++ HTML-FormFu-0.03001/lib/HTML/FormFu/Element/Checkboxgroup.pm        
2008-07-07 11:12:27.000000000 -0400
@@ -14,6 +14,7 @@
     $self->label_tag('legend');
     $self->container_tag('fieldset');
     $self->multi_value(1);
+    $self->reverse_multi(1);
 
     return $self;
 }
@@ -130,31 +131,67 @@
                 process_attrs( $option->{attributes} );
 
             for my $item ( @{ $option->{group} } ) {
-                $html .= sprintf
-                    qq{<span>\n<input name="%s" type="checkbox" value="%s"%s 
/>},
-                    $render->{nested_name},
-                    $item->{value},
-                    process_attrs( $item->{attributes} );
+                $html .= "<span>\n";
 
-                $html .= sprintf
-                    "\n<label%s>%s</label>\n</span>\n",
-                    process_attrs( $item->{label_attributes} ),
-                    $item->{label};
+                if ( $render->{reverse_multi} ) {
+                    $html .= sprintf
+                        qq{<input name="%s" type="checkbox" value="%s"%s />\n},
+                        $render->{nested_name},
+                        $item->{value},
+                        process_attrs( $item->{attributes} );
+
+                    $html .= sprintf
+                        "<label%s>%s</label>\n",
+                        process_attrs( $item->{label_attributes} ),
+                        $item->{label};
+                }
+                else {
+                    $html .= sprintf
+                        "<label%s>%s</label>\n",
+                        process_attrs( $item->{label_attributes} ),
+                        $item->{label};
+
+                    $html .= sprintf
+                        qq{<input name="%s" type="checkbox" value="%s"%s />\n},
+                        $render->{nested_name},
+                        $item->{value},
+                        process_attrs( $item->{attributes} );
+                }
+
+                $html .= "</span>\n";
             }
 
             $html .= "</span>\n";
         }
         else {
-            $html .= sprintf
-                qq{<span>\n<input name="%s" type="checkbox" value="%s"%s />},
-                $render->{nested_name},
-                $option->{value},
-                process_attrs( $option->{attributes} );
+            $html .= "<span>\n";
 
-            $html .= sprintf
-                "\n<label%s>%s</label>\n</span>\n",
-                process_attrs( $option->{label_attributes} ),
-                $option->{label};
+            if ( $render->{reverse_multi} ) {
+                $html .= sprintf
+                    qq{<input name="%s" type="checkbox" value="%s"%s />\n},
+                    $render->{nested_name},
+                    $option->{value},
+                    process_attrs( $option->{attributes} );
+
+                $html .= sprintf
+                    "<label%s>%s</label>\n",
+                    process_attrs( $option->{label_attributes} ),
+                    $option->{label};
+            }
+            else {
+                $html .= sprintf
+                    "<label%s>%s</label>\n",
+                    process_attrs( $option->{label_attributes} ),
+                    $option->{label};
+
+                $html .= sprintf
+                    qq{<input name="%s" type="checkbox" value="%s"%s />\n},
+                    $render->{nested_name},
+                    $option->{value},
+                    process_attrs( $option->{attributes} );
+            }
+
+            $html .= "</span>\n";
         }
     }
 
@@ -218,6 +255,10 @@
       name: foo
       auto_id: "%n_%c"
 
+=head2 reverse_multi
+
+Overrides the default value, so it's C<true>.
+
 =head1 SEE ALSO
 
 Is a sub-class of, and inherits methods from 
diff -rN -x '*~' -u 
HTML-FormFu-0.03001.orig/lib/HTML/FormFu/Element/Radiogroup.pm 
HTML-FormFu-0.03001/lib/HTML/FormFu/Element/Radiogroup.pm
--- HTML-FormFu-0.03001.orig/lib/HTML/FormFu/Element/Radiogroup.pm      
2008-06-05 09:49:12.000000000 -0400
+++ HTML-FormFu-0.03001/lib/HTML/FormFu/Element/Radiogroup.pm   2008-07-07 
11:11:27.000000000 -0400
@@ -15,6 +15,7 @@
     $self->field_filename('radiogroup_tag');
     $self->label_tag('legend');
     $self->container_tag('fieldset');
+    $self->reverse_multi(1);
 
     return $self;
 }
@@ -125,31 +126,67 @@
                 process_attrs( $option->{attributes} );
 
             for my $item ( @{ $option->{group} } ) {
-                $html .= sprintf
-                    qq{<span>\n<input name="%s" type="radio" value="%s"%s />},
-                    $render->{nested_name},
-                    $item->{value},
-                    process_attrs( $item->{attributes} );
+                $html .= "<span>\n";
 
-                $html .= sprintf
-                    "\n<label%s>%s</label>\n</span>\n",
-                    process_attrs( $item->{label_attributes} ),
-                    $item->{label};
+                if ( $render->{reverse_multi} ) {
+                    $html .= sprintf
+                        qq{<input name="%s" type="radio" value="%s"%s />\n},
+                        $render->{nested_name},
+                        $item->{value},
+                        process_attrs( $item->{attributes} );
+
+                    $html .= sprintf
+                        "<label%s>%s</label>\n",
+                        process_attrs( $item->{label_attributes} ),
+                        $item->{label};
+                }
+                else {
+                    $html .= sprintf
+                        "<label%s>%s</label>\n",
+                        process_attrs( $item->{label_attributes} ),
+                        $item->{label};
+
+                    $html .= sprintf
+                        qq{<input name="%s" type="radio" value="%s"%s />\n},
+                        $render->{nested_name},
+                        $item->{value},
+                        process_attrs( $item->{attributes} );
+                }
+
+                $html .= "</span>\n";
             }
 
             $html .= "</span>\n";
         }
         else {
-            $html .= sprintf
-                qq{<span>\n<input name="%s" type="radio" value="%s"%s />},
-                $render->{nested_name},
-                $option->{value},
-                process_attrs( $option->{attributes} );
+            $html .= "<span>\n";
 
-            $html .= sprintf
-                "\n<label%s>%s</label>\n</span>\n",
-                process_attrs( $option->{label_attributes} ),
-                $option->{label};
+            if ( $render->{reverse_multi} ) {
+                $html .= sprintf
+                    qq{<input name="%s" type="radio" value="%s"%s />\n},
+                    $render->{nested_name},
+                    $option->{value},
+                    process_attrs( $option->{attributes} );
+
+                $html .= sprintf
+                    "<label%s>%s</label>\n",
+                    process_attrs( $option->{label_attributes} ),
+                    $option->{label};
+            }
+            else {
+                $html .= sprintf
+                    "<label%s>%s</label>\n",
+                    process_attrs( $option->{label_attributes} ),
+                    $option->{label};
+
+                $html .= sprintf
+                    qq{<input name="%s" type="radio" value="%s"%s />\n},
+                    $render->{nested_name},
+                    $option->{value},
+                    process_attrs( $option->{attributes} );
+            }
+
+            $html .= "</span>\n";
         }
     }
 
@@ -216,6 +253,10 @@
       name: foo
       auto_id: "%n_%c"
 
+=head2 reverse_multi
+
+Overrides the default value, so it's C<true>.
+
 =head1 SEE ALSO
 
 Is a sub-class of, and inherits methods from 
diff -rN -x '*~' -u HTML-FormFu-0.03001.orig/lib/HTML/FormFu/Element/_Field.pm 
HTML-FormFu-0.03001/lib/HTML/FormFu/Element/_Field.pm
--- HTML-FormFu-0.03001.orig/lib/HTML/FormFu/Element/_Field.pm  2008-06-05 
10:01:40.000000000 -0400
+++ HTML-FormFu-0.03001/lib/HTML/FormFu/Element/_Field.pm       2008-07-07 
12:10:33.000000000 -0400
@@ -37,7 +37,7 @@
         _constraints _filters _inflators _deflators _validators _transformers
         _plugins _errors container_tag
         field_filename label_filename label_tag retain_default force_default
-        javascript non_param reverse_multi multi_value original_name /
+        javascript non_param reverse reverse_multi multi_value original_name /
 );
 
 __PACKAGE__->mk_output_accessors(qw/ comment label value /);
@@ -476,6 +476,7 @@
             label_filename       => $self->label_filename,
             label_tag            => $self->label_tag,
             container_tag        => $self->container_tag,
+            reverse              => $self->reverse,
             reverse_multi        => $self->reverse_multi,
             javascript           => $self->javascript,
             @_ ? %{ $_[0] } : () } );
@@ -781,7 +782,8 @@
         }
     }
 
-    if ( defined $render->{label} && $render->{label_tag} ne 'legend' ) {
+    if ( defined $render->{label} && $render->{label_tag} ne 'legend' &&
+         !$render->{reverse} ) {
         $html .= "\n" . $self->_string_label($render);
     }
 
@@ -813,6 +815,11 @@
 
     my $html = '';
 
+    if ( defined $render->{label} && $render->{label_tag} ne 'legend' &&
+         $render->{reverse} ) {
+        $html .= "\n" . $self->_string_label($render);
+    }
+
     if ( defined $render->{comment} ) {
         $html .= sprintf "\n<span%s>\n%s\n</span>",
             process_attrs( $render->{comment_attributes} ),
@@ -1162,11 +1169,29 @@
 
 Default Value: C<false>
 
+=head2 reverse
+
+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).
+
+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.
+
+For L<Radiogroup|HTML::FormFu::Element::Radiogroup> and
+L<Checkboxgroup|HTML::FormFu::Element::Checkboxgroup> elements,
+controls the placement of the labels for the individual radio or
+checkbox fields.
 
 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.03001.orig/share/templates/tt/xhtml/checkboxgroup_tag 
HTML-FormFu-0.03001/share/templates/tt/xhtml/checkboxgroup_tag
--- HTML-FormFu-0.03001.orig/share/templates/tt/xhtml/checkboxgroup_tag 
2008-05-29 05:23:14.000000000 -0400
+++ HTML-FormFu-0.03001/share/templates/tt/xhtml/checkboxgroup_tag      
2008-07-07 11:41:00.000000000 -0400
@@ -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>
-<input name="[% self.nested_name %]" type="checkbox" value="[% item.value 
%]"[% process_attrs(item.attributes) %] />
-<label[% process_attrs(item.label_attributes) %]>[% item.label %]</label>
+[% IF self.reverse_multi %]<input name="[% self.nested_name %]" 
type="checkbox" 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="checkbox" value="[% item.value 
%]"[% process_attrs(item.attributes) %] />[% END %]
 </span>
 [% END %]</span>
 [% ELSE %]<span>
-<input name="[% self.nested_name %]" type="checkbox" value="[% option.value 
%]"[% process_attrs(option.attributes) %] />
-<label[% process_attrs(option.label_attributes) %]>[% option.label %]</label>
+[% IF self.reverse_multi %]<input name="[% self.nested_name %]" 
type="checkbox" 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="checkbox" 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.03001.orig/share/templates/tt/xhtml/field 
HTML-FormFu-0.03001/share/templates/tt/xhtml/field
--- HTML-FormFu-0.03001.orig/share/templates/tt/xhtml/field     2008-05-29 
05:23:14.000000000 -0400
+++ HTML-FormFu-0.03001/share/templates/tt/xhtml/field  2008-07-07 
10:52:37.000000000 -0400
@@ -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 %]
 [% 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 %]
+[% 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.03001.orig/share/templates/tt/xhtml/radiogroup_tag 
HTML-FormFu-0.03001/share/templates/tt/xhtml/radiogroup_tag
--- HTML-FormFu-0.03001.orig/share/templates/tt/xhtml/radiogroup_tag    
2008-05-29 05:23:14.000000000 -0400
+++ HTML-FormFu-0.03001/share/templates/tt/xhtml/radiogroup_tag 2008-07-07 
11:41:08.000000000 -0400
@@ -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>
-<input name="[% self.nested_name %]" type="radio" value="[% item.value %]"[% 
process_attrs(item.attributes) %] />
-<label[% process_attrs(item.label_attributes) %]>[% item.label %]</label>
+[% IF self.reverse_multi %]<input name="[% self.nested_name %]" type="radio" 
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="radio" value="[% item.value %]"[% 
process_attrs(item.attributes) %] />[% END %]
 </span>
 [% END %]</span>
 [% ELSE %]<span>
-<input name="[% self.nested_name %]" type="radio" value="[% option.value %]"[% 
process_attrs(option.attributes) %] />
-<label[% process_attrs(option.label_attributes) %]>[% option.label %]</label>
+[% IF self.reverse_multi %]<input name="[% self.nested_name %]" type="radio" 
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="radio" 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.03001.orig/t/elements/checkboxgroup.t 
HTML-FormFu-0.03001/t/elements/checkboxgroup.t
--- HTML-FormFu-0.03001.orig/t/elements/checkboxgroup.t 2008-05-29 
05:22:59.000000000 -0400
+++ HTML-FormFu-0.03001/t/elements/checkboxgroup.t      2008-07-07 
11:41:21.000000000 -0400
@@ -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_multi(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.03001.orig/t/elements/radiogroup.t 
HTML-FormFu-0.03001/t/elements/radiogroup.t
--- HTML-FormFu-0.03001.orig/t/elements/radiogroup.t    2008-05-29 
05:22:59.000000000 -0400
+++ HTML-FormFu-0.03001/t/elements/radiogroup.t 2008-07-07 11:51:57.000000000 
-0400
@@ -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('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_multi(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' } },
     ] );
 $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" />
@@ -31,19 +35,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>
-<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.03001.orig/t/elements/reverse.t 
HTML-FormFu-0.03001/t/elements/reverse.t
--- HTML-FormFu-0.03001.orig/t/elements/reverse.t       1969-12-31 
19:00:00.000000000 -0500
+++ HTML-FormFu-0.03001/t/elements/reverse.t    2008-07-07 11:56:17.000000000 
-0400
@@ -0,0 +1,17 @@
+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(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