package Rose::HTML::Form::Field::Option::Container; use strict; use Carp(); use base 'Rose::HTML::Form::Field::Group::OnOff'; use Rose::HTML::Form::Field::Group; require Rose::HTML::Form::Field::Option; require Rose::HTML::Form::Field::OptionGroup; our $VERSION = '0.606'; sub _item_class { shift->object_type_class_loaded('option') } sub _item_group_class { shift->object_type_class_loaded('option group') } sub _item_name { 'option' } sub _item_name_plural { 'options' } *options = \&Rose::HTML::Form::Field::Group::items; *options_localized = \&Rose::HTML::Form::Field::Group::items_localized; *option = \&Rose::HTML::Form::Field::Group::OnOff::item; *option_group = \&Rose::HTML::Form::Field::Group::OnOff::item_group; *visible_options = \&Rose::HTML::Form::Field::Group::visible_items; *add_options = \&Rose::HTML::Form::Field::Group::add_items; *add_option = \&add_options; *add_options_localized = \&Rose::HTML::Form::Field::Group::add_items_localized; *add_option_localized = \&add_options_localized; *add_options_localized = \&Rose::HTML::Form::Field::Group::add_items_localized; *add_option_localized = \&Rose::HTML::Form::Field::Group::add_item_localized; *choices = \&options; *choices_localized = \&options_localized; *_args_to_items = \&Rose::HTML::Form::Field::Group::_args_to_items; *show_all_options = \&Rose::HTML::Form::Field::Group::show_all_items; *hide_all_options = \&Rose::HTML::Form::Field::Group::hide_all_items; *delete_option = \&Rose::HTML::Form::Field::Group::delete_item; *delete_options = \&Rose::HTML::Form::Field::Group::delete_items; *delete_option_group = \&Rose::HTML::Form::Field::Group::delete_item_group; *delete_option_groups = \&Rose::HTML::Form::Field::Group::delete_item_groups; sub html_element { 'select' } sub xhtml_element { 'select' } #sub name { shift->html_attr('name', @_) } sub is_flat_group { 0 } sub is_empty { no warnings 'uninitialized'; return (grep { /\S/ } shift->internal_value) ? 0 : 1; } sub children { my($self) = shift; Carp::croak "Cannot set children() for an option container ($_[0]). Use options() instead." if(@_); return $self->options; } sub push_children { shift->add_items(@_) } sub push_child { shift->add_item(@_) } sub pop_children { shift->pop_items(@_) } sub pop_child { shift->pop_item(@_) } sub shift_children { shift->add_items(@_) } sub shift_child { shift->add_item(@_) } sub unshift_children { shift->unshift_items(@_) } sub unshift_child { shift->unshift_item(@_) } sub child { my($self, $index) = @_; my $items = $self->items || []; return $items->[$index]; } sub delete_child_at_index { my($self) = shift; Carp::croak "Missing array index" unless(@_); my $items = $self->items || []; no warnings; splice(@$items, $_[0], 1); } sub html_field { my($self) = shift; my $html; if($self->apply_error_class && defined $self->error) { my $class = $self->html_attr('class'); $self->html_attr(class => $class ? "$class error" : 'error'); $html = $self->start_html . "\n" . join("\n", map { $_->html_field } $self->visible_items) . "\n" . $self->end_html; $self->html_attr(class => $class); return $html; } else { return $self->start_html . "\n" . join("\n", map { $_->html_field } $self->visible_items) . "\n" . $self->end_html; } } sub xhtml_field { my($self) = shift; my $xhtml; if($self->apply_error_class && defined $self->error) { my $class = $self->html_attr('class'); $self->html_attr(class => $class ? "$class error" : 'error'); $xhtml = $self->start_xhtml . "\n" . join("\n", map { $_->xhtml_field } $self->visible_items) . "\n" . $self->end_xhtml; $self->html_attr(class => $class); return $xhtml; } else { return $self->start_xhtml . "\n" . join("\n", map { $_->xhtml_field } $self->visible_items) . "\n" . $self->end_xhtml; } } # sub html_field # { # my($self) = shift; # $self->contents("\n" . join("\n", map { $_->html_field } $self->visible_options) . "\n"); # return $self->_html_tag(@_); # } # # sub xhtml_field # { # my($self) = shift; # $self->contents("\n" . join("\n", map { $_->xhtml_field } $self->visible_options) . "\n"); # return $self->_xhtml_tag(@_); # } sub input_value { my($self) = shift; if(@_ && (@_ > 1 || (ref $_[0] eq 'ARRAY' && @{$_[0]} > 1)) && !$self->multiple) { Carp::croak "Attempt to select multiple values in a non-multiple " . ref($self); } my $values = $self->SUPER::input_value(@_); Carp::croak "Non-multiple ", ref($self), " has multiple values: ", join(', ', @$values) if(@$values > 1 && !$self->multiple); return wantarray ? @$values : $values; } sub hidden_fields { my($self) = shift; my @hidden; foreach my $item ($self->items) { if(defined $item->internal_value) { # Derek Watson suggests this conditional modifier, but # I've yet to see the error is works around... $hidden[-1]->name($self->name) if(push(@hidden, $item->hidden_field)); } } return (wantarray) ? @hidden : \@hidden; } sub hidden { my($self) = shift; if(@_) { if($self->{'_hidden'} = shift(@_) ? 1 : 0) { foreach my $option ($self->options) { $option->selected(undef); } } } return $self->{'_hidden'}; } sub hide { shift->hidden(1) } sub show { shift->hidden(0) } 1;