+ $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),
+ '</select>',
+ );
+ 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 ''
+ ? '<label>'.$self->tag(input => $_)." $label</label>"
+ : $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;
+ }