[Html-widget] Patch for RadioGroup to support fieldsets

Michael Gray mjg17 at eng.cam.ac.uk
Thu Aug 3 14:02:01 CEST 2006


I'm still struggling in my mind with HTML::Widget archictecture relating 
to full nested fieldset support.

Meanwhile, this patch (which includes tests) provides an alternate 
rendering behaviour for HTML::Widget::Element::RadioGroup, putting the 
radio buttons into a <fieldset> with a <legend> for the label.  From the 
docs:

  =head2 group_container

  Sets the container to be used for the radio group.  Currently
  understands 'span' and 'fieldset'.  'span' is the default and
  replicates the previous behaviour.  'fieldset' puts the radio buttons
  into a fieldset with class 'radiogroup'.  group_container() can be
  called as a class or instance method.

-- 
Michael
-------------- next part --------------
Index: lib/HTML/Widget/Element/RadioGroup.pm
===================================================================
--- lib/HTML/Widget/Element/RadioGroup.pm	(revision 44)
+++ lib/HTML/Widget/Element/RadioGroup.pm	(working copy)
@@ -3,7 +3,10 @@
 use warnings;
 use strict;
 use base 'HTML::Widget::Element';
+use Carp qw/croak/;
 
+__PACKAGE__->mk_classaccessor(group_container => 'span');
+
 __PACKAGE__->mk_accessors(qw/comment label values labels comments value _current_subelement/);
 
 =head1 NAME
@@ -46,6 +49,14 @@
 
 The labels for corresponding l<values>.
 
+=head2 group_container
+
+Sets the container to be used for the radio group.  Currently
+understands 'span' and 'fieldset'.  'span' is the default and
+replicates the previous behaviour.  'fieldset' puts the radio buttons
+into a fieldset with class 'radiogroup'.  group_container() can be
+called as a class or instance method.
+
 =cut
 
 sub new {
@@ -92,7 +103,10 @@
 sub containerize {
     my ( $self, $w, $value, $errors ) = @_;
 
-    $value ||= $self->value || '';
+    # ||= broken if value is intentionally 0
+    # $value ||= $self->value || '';
+    $value = $self->value unless defined $value;
+    $value = '' unless defined $value;
 
     my $name = $self->name;
     my @values = @{ $self->values || [] };
@@ -120,17 +134,46 @@
 
     $self->_current_subelement( undef );
 
-    #my $error = $self->mk_error( $w, $errors );
+    my $error = $self->mk_error( $w, $errors );
 
-    # this should really be a legend attr for field
-    my $l = $self->mk_label( $w, $self->label, $self->comment, $errors );
-    $l->attr( for => undef ) if $l;
+    if ($self->group_container eq 'span') {
 
-    return $self->container({
-        element => HTML::Element->new('span')->push_content(@radios),
-        error => scalar $self->mk_error( $w, $errors ),
-		label => $l
-    });
+	my $l = $self->mk_label( $w, $self->label, $self->comment, $errors );
+	$l->attr( for => undef ) if $l;
+
+	return $self->container({
+	    element => HTML::Element->new('span')->push_content(@radios),
+	    error => scalar $error,
+	    label => $l
+	    });
+
+    } elsif ($self->group_container eq 'fieldset') {
+
+	my $fs = HTML::Element->new('fieldset', 
+				    class => 'radiogroup',
+				    id => $self->id($w));
+	if ($self->label) {
+	    my $l = HTML::Element->new('legend',
+				       id => $self->id($w) . '_legend');
+	    $l->push_content($self->label);
+	    $fs->push_content($l);
+	}
+	if ($self->comment) {
+	    my $c = HTML::Element->new('span',
+				       id => $self->id($w) . '_comment',
+				       class => 'label_comments',
+				       );
+	    $c->push_content($self->comment);
+	    $fs->push_content($c);
+	}
+	$fs->push_content(@radios);
+	return $self->container({
+	    element => $fs,
+	    error => scalar $error,
+	});
+    } else {
+	croak('Unknown group_container "', $self->group_container, '"');
+    }
 }
 
 sub id {
Index: t/element_radiogroup.t
===================================================================
--- t/element_radiogroup.t	(revision 44)
+++ t/element_radiogroup.t	(working copy)
@@ -1,4 +1,4 @@
-use Test::More tests => 3;
+use Test::More tests => 7;
 
 use_ok('HTML::Widget');
 
@@ -26,8 +26,50 @@
     my $query = HTMLWidget::TestLib->mock_query({ bar => 'opt2' });
 
     my $f = $w->process($query);
-    is( "$f", <<EOF, 'XML output is filled out form' );
+    is( "$f", <<EOF, 'XML output is filled out form (query)' );
 <form id="widget" method="post"><fieldset><span><label for="widget_bar_1" id="widget_bar_1_label"><input class="radio" id="widget_bar_1" name="bar" type="radio" value="opt1" />Opt1</label><label for="widget_bar_2" id="widget_bar_2_label"><input checked="checked" class="radio" id="widget_bar_2" name="bar" type="radio" value="opt2" />Opt2</label><label for="widget_bar_3" id="widget_bar_3_label"><input class="radio" id="widget_bar_3" name="bar" type="radio" value="opt3" />Opt3</label></span></fieldset></form>
 EOF
 }
 
+my $w2 = HTML::Widget->new;
+my $e = $w2->element( 'RadioGroup', 'bar' )->values([ 'opt1', 'opt2', 'opt3'])->value('opt1');
+$e->group_container('fieldset');
+
+# Without query
+{
+    my $f = $w2->process;
+    is( "$f", <<EOF, 'XML output is filled out form (fieldset)' );
+<form id="widget" method="post"><fieldset><fieldset class="radiogroup" id="widget_bar"><label for="widget_bar_1" id="widget_bar_1_label"><input checked="checked" class="radio" id="widget_bar_1" name="bar" type="radio" value="opt1" />Opt1</label><label for="widget_bar_2" id="widget_bar_2_label"><input class="radio" id="widget_bar_2" name="bar" type="radio" value="opt2" />Opt2</label><label for="widget_bar_3" id="widget_bar_3_label"><input class="radio" id="widget_bar_3" name="bar" type="radio" value="opt3" />Opt3</label></fieldset></fieldset></form>
+EOF
+}
+
+# This shouldn't upset anything
+HTML::Widget::Element::RadioGroup->group_container('span');
+
+# With mocked basic query
+{
+    my $query = HTMLWidget::TestLib->mock_query({ bar => 'opt2' });
+
+    my $f = $w2->process($query);
+    is( "$f", <<EOF, 'XML output is filled out form (fieldset query)' );
+<form id="widget" method="post"><fieldset><fieldset class="radiogroup" id="widget_bar"><label for="widget_bar_1" id="widget_bar_1_label"><input class="radio" id="widget_bar_1" name="bar" type="radio" value="opt1" />Opt1</label><label for="widget_bar_2" id="widget_bar_2_label"><input checked="checked" class="radio" id="widget_bar_2" name="bar" type="radio" value="opt2" />Opt2</label><label for="widget_bar_3" id="widget_bar_3_label"><input class="radio" id="widget_bar_3" name="bar" type="radio" value="opt3" />Opt3</label></fieldset></fieldset></form>
+EOF
+}
+
+# With label/legend
+$e->label('Choose');
+{
+    my $f = $w2->process;
+    is( "$f", <<EOF, 'XML output is filled out form (label)' );
+<form id="widget" method="post"><fieldset><fieldset class="radiogroup" id="widget_bar"><legend id="widget_bar_legend">Choose</legend><label for="widget_bar_1" id="widget_bar_1_label"><input checked="checked" class="radio" id="widget_bar_1" name="bar" type="radio" value="opt1" />Opt1</label><label for="widget_bar_2" id="widget_bar_2_label"><input class="radio" id="widget_bar_2" name="bar" type="radio" value="opt2" />Opt2</label><label for="widget_bar_3" id="widget_bar_3_label"><input class="radio" id="widget_bar_3" name="bar" type="radio" value="opt3" />Opt3</label></fieldset></fieldset></form>
+EOF
+}
+
+# With comment too
+$e->comment('Informed');
+{
+    my $f = $w2->process;
+    is( "$f", <<EOF, 'XML output is filled out form (label+comment)' );
+<form id="widget" method="post"><fieldset><fieldset class="radiogroup" id="widget_bar"><legend id="widget_bar_legend">Choose</legend><span class="label_comments" id="widget_bar_comment">Informed</span><label for="widget_bar_1" id="widget_bar_1_label"><input checked="checked" class="radio" id="widget_bar_1" name="bar" type="radio" value="opt1" />Opt1</label><label for="widget_bar_2" id="widget_bar_2_label"><input class="radio" id="widget_bar_2" name="bar" type="radio" value="opt2" />Opt2</label><label for="widget_bar_3" id="widget_bar_3_label"><input class="radio" id="widget_bar_3" name="bar" type="radio" value="opt3" />Opt3</label></fieldset></fieldset></form>
+EOF
+}


More information about the Html-widget mailing list