use strict; use warnings; package XHTML::Instrumented::Form::Select; use base 'XHTML::Instrumented::Form::ElementControl'; use Params::Validate qw( validate ARRAYREF ); use Carp qw(croak); use XHTML::Instrumented::Form::Option; sub name { my $self = shift; $self->{name}; } sub new { my $class = shift; my %p = validate(@_, { name => 1, type => 1, value => 0, required => 0, default => 0, values => 0, # multiple => 0, onclick => 0, onchange => 0, class => 0, data => { optional => 1, type => ARRAYREF, }, }); if ($p{type} eq 'select') { my $data = $p{data}; for my $option (@$data) { unless (defined $option->{value}) { $option->{value} = $option->{text}; } bless($option, 'XHTML::Instrumented::Form::Option'); } } bless({ %p }, $class); } sub set_select_data { my $self = shift; my @new; for my $option (@_) { unless (defined $option->{value}) { $option->{value} = $option->{text}; } unless (defined $option->{text}) { $option->{text} = $option->{value}; } use Data::Dumper; croak Dumper([@_]) . 'set_select_data' unless defined $option->{text}; push(@new, bless $option,'XHTML::Instrumented::Form::Option'); } $self->{data} = \@new; } sub set_default { my $self = shift; $self->{default} = shift; } sub options { my $self = shift; map({ $_; } (@{$self->{data} || []})); } sub elements { my $self = shift; map({ $_->{value} || $_->{text} } @{$self->{data} || []}); } sub values { my $self = shift; map({ $_->{value} || $_->{text} } @{$self->{values} || []}); } sub type { my $self = shift; $self->{type}; } sub exp_args { my $self = shift; die caller if ref $_[0]; my @extra = (); if ($self->{multiple}) { push(@extra, 'multiple', 'multiple'); } if (my $data = $self->{onclick}) { push(@extra, 'onclick', $data); } my $ret = $self->SUPER::exp_args(@_, name => $self->name, @extra); $ret; } sub expand_content { my $self = shift; $self->{value} ||= $self->{default}; require XHTML::Instrumented::Entry; for my $option (@{$self->{data}}) { if ($self->{value} && $option->{value} && $self->{value} eq $option->{value}) { $option->{selected} = 1; } } my $value = $self->{value} || $self->{default}; my @ret; if (@{$self->{data}||[]}) { @ret = map({ XHTML::Instrumented::Entry->new( tag => 'option', flags => {}, args => { $_->as_args }, data => [ $_->{text} ], ), } @{$self->{data}} ); } else { for my $entry (@_) { if (ref($entry)) { my $entry_value = $entry->{args}{value}; if ($value && $entry_value && $value eq $entry_value) { $entry->{args}{selected} = 'selected'; } push(@ret, $entry); } } } @ret; } sub set_value { my $self = shift; my $value = shift; die if @_; if (my $type = ref($value)) { die unless $type eq 'ARRAY'; if (@{$value} == 1) { $self->{value} = $value->[0]; } elsif (@{$value} == 0) { $self->{value} = ''; } else { die 'bad data ' . "@{$value}"; } } else { $self->{value} = $value; } $value = $self->{value}; if (defined $value) { for my $element (@{$self->{data} || []}) { delete $element->{selected}; if ($value eq ($element->value || '')) { $element->{selected} = 1; } } } } sub value { my $self = shift; $self->SUPER::value(); } 1; __END__ =head1 NAME XHTML::Instrumented::Form::Select - Object to hold select options. =head1 SYNOPSIS =head1 API This normally used by the Form::Select and Form::Checkbox objects to hold information about the Options available. =head2 Constructor =over =item new =back =head2 Methods =over =item name =item set_select_data =item set_default =item options =item elements =item values =item type =item exp_args =item expand_content =item set_value =item value =back =head2 Functions This object has no functions =head1 AUTHOR "G. Allen Morris III" =cut