From: Mischa Poslawsky Date: Fri, 25 Jul 2008 14:11:42 +0000 (+0200) Subject: extended select() support X-Git-Url: http://git.shiar.net/perl/html-form-simple.git/commitdiff_plain/be81b5d559a8ed87ee6493f27b698343fada60c4 extended select() support - Default values. - Keep options seperate in list context. - Input types (checkbox, radio). - Various tests. - Shorthand methods check() and radio(). --- diff --git a/lib/HTML/Form/Simple.pm b/lib/HTML/Form/Simple.pm index 6e84888..57b2a91 100644 --- a/lib/HTML/Form/Simple.pm +++ b/lib/HTML/Form/Simple.pm @@ -28,7 +28,7 @@ sub tag { # add booleans delete $attr->{$_} and $return .= ' '.$_ - for qw(disabled readonly); + for qw(selected checked disabled readonly); $return .= sprintf ' %s="%s"', $_, $self->quote($attr->{$_}) for sort grep { defined $attr->{$_} } keys %$attr; @@ -107,15 +107,92 @@ sub select { if (ref $value eq 'HASH') { $attr = $value; + $value = delete $attr->{value}; } else { $attr ||= {}; + delete $attr->{value}; } $attr->{name} = $name; + $attr->{id} = $attr->{name} unless defined $attr->{id}; + $attr->{type} = 'select' unless defined $attr->{type}; + + my @options = map { ref $_ ? $_ : {value => $_} } @$rows; + + if ($attr->{type} eq 'select') { + delete $attr->{type}; + if (defined $value) { + for (@options) { + $_->{selected} = 1 if defined $_->{value} and $_->{value} eq $value; + } + } + my @return = ( + $self->tag(select => $attr), + (map { $self->tag(option => $_) } @options), + '', + ); + return wantarray ? @return : join('', @return); + } + else { + if (defined $attr->{id}) { + defined $_->{id} or defined $_->{value} and $_->{id} = $attr->{id}.'_'.$_->{value} + for @options; + } + if (defined $attr->{label}) { + defined $_->{value} and not defined $_->{label} + and $_->{label} = $attr->{label}->{$_->{value}} + for @options; + delete $attr->{label}; + } + if (defined $value) { + for (@options) { + $_->{checked} = 1 if defined $_->{value} and $_->{value} eq $value; + } + } + $_ = {%$attr, %$_} for @options; + my @return = map { + my $label = delete $_->{label}; + defined $label && $label ne '' + ? '" + : $self->tag(input => $_) + } @options; + return wantarray ? @return : join('', @return); + } +} + +sub radio { + my ($self, $name, $value, $attr) = @_; + + if (ref $value eq 'HASH') { + $attr = $value; + } + else { + $attr ||= {}; + $attr->{value} = $value; + } - return $self->tag(select => $attr) . join('', - map { $self->tag(option => (ref $_ ? $_ : {value => $_})) } @$rows - ) . ''; + $self->select($name, [$attr], {type => 'radio'}); +} + +sub check { + my ($self, $name, $label, $checked, $attr) = @_; + + if (ref $label eq 'HASH') { + $attr = $label; + undef $label; + } + elsif (ref $checked eq 'HASH') { + $attr = $checked; + $attr->{label} = $label; + } + else { + $attr ||= {}; + $attr->{checked} = $checked; + $attr->{label} = $label; + } + $attr->{value} = '1' unless exists $attr->{value}; + + $self->select($name, [$attr], {type => 'checkbox'}); } 1; @@ -135,9 +212,15 @@ HTML::Form::Simple [ Message => $input->text( msg => 'Textarea default', {rows => 4, style => 'background:red'} ) ], - [ Colour => $input->select( + [ Gender => join ' or ', $input->radio( + sex => ['m', 'f'] + ) ], + [ Colour => scalar $input->select( favcolour => [qw(Blue Green Red)], 'Green' ) ], + [ Options => $input->check( + spam => 'Receive weekly newsletter' + ) ], ); say $input->stop; # diff --git a/t/html.t b/t/html.t index e023997..d12d6ef 100644 --- a/t/html.t +++ b/t/html.t @@ -5,7 +5,7 @@ use warnings; use Test::More; -plan tests => 31; +plan tests => 43; use_ok('HTML::Form::Simple'); @@ -176,29 +176,139 @@ is( # select -is( - $form->select, - '', # malformed html: at least 1 option required +is_deeply( + [ $form->select ], + [ qw() ], # malformed html: at least 1 option required 'empty select' ); -is( - $form->select(undef, [], '', {name => ''}), - '', +is_deeply( + [ $form->select(undef, [], '', {name => '', class => ''}) ], + [ qw() ], 'explicit empty select' ); -is( - $form->select(undef, [undef]), - '', +is_deeply( + [ $form->select(undef, [undef]) ], + [ qw() ], 'minimal select' ); -is( - $form->select(foo => [1..2]), - '', +is_deeply( + [ $form->select(foo => [1, 2]) ], + [ + '' + ], 'select contents' ); +is_deeply( + [ $form->select(foo => [1, 2], 3) ], + [ + '' + ], + 'select invalid default' +); + +is_deeply( + [ $form->select(undef, [1, 2], 2) ], + [ + '' + ], + 'select default' +); + +is_deeply( + [ + $form->select(foo => [ + '<">', {value => 2, disabled => 1, selected => 0, class => 1}, {selected => 1} + ], '2', {id => '', class => 'a 1}) + ], + [ + '' + ], + 'complex select' +); + +is( + scalar $form->select(foo => [1, 2]), + '', + 'select scalar' +); + +# radio + +is_deeply( + [ $form->select(foo => [1], {type => 'radio'}) ], + [ '' ], + 'input select' +); + +is_deeply( + [ + $form->select(foo => [ + 1, {value => 2, name => '', label => ''}, {value => 3, id => '', type => ''} + ], {type => 'checkbox', label => {3 => 'test', 2 => 'ignore'}, value => '1'}) + ], + [ + '', + '', + '', + ], + 'input selects' +); + +is( + $form->radio(foo => 1), + '', + 'radio method' +); + +is( + $form->radio(undef, {checked => 1}), + '', + 'simple radio button' +); + +is( + $form->check('foo'), + '', + 'check method' +); + +is( + $form->check(foo => 'test', {value => undef}), + '', + 'check parameters' +); + +is( + $form->check(undef, '', 1), + '', + 'simple checkbox' +); + +TODO: { + local $TODO = 'shorthand'; +is_deeply( + [ $form->check(undef, ['', '<">']) ], + [ + '', + '', + ], + 'multiple checkboxes' +); +}; + #TODO