package Rose::HTML::Form::Field::Group::OnOff;
use strict;
use Carp();
use Rose::HTML::Util();
use base 'Rose::HTML::Form::Field::Group';
our $VERSION = '0.606';
our $Debug = undef;
sub resync_name
{
my($self) = shift;
$self->SUPER::resync_name();
# Resync item names too
my $name = $self->local_name;
foreach my $item ($self->items)
{
$item->name($name);
}
}
sub name
{
my($self) = shift;
if(@_)
{
$self->local_name(shift);
my $name = $self->local_name;
# All items in the group must have the same name
foreach my $item ($self->items)
{
$item->name($name);
}
}
my $name = $self->html_attr('name');
# The name HTML attr will be an empty string if it's a required attr,
# so use length() and not defined()
no warnings 'uninitialized';
unless(length $name)
{
return $self->html_attr('name', $self->fq_name);
}
return $name;
}
sub defaults
{
my($self) = shift;
if(@_)
{
if(@_ == 1 && ref $_[0] eq 'ARRAY')
{
$self->{'defaults'} = { map { $_ => 1 } @{$_[0]} };
}
elsif(defined $_[0])
{
$self->{'defaults'} = { map { $_ => 1 } @_ };
}
else
{
$self->{'defaults'} = { };
}
$self->init_items;
}
return (wantarray) ? sort keys %{$self->{'defaults'}} : [ sort keys %{$self->{'defaults'}} ];
}
*default = \&defaults;
*default_value = \&defaults;
*default_values = \&defaults;
sub default_values_hash { (wantarray) ? %{$_[0]->{'defaults'}} : $_[0]->{'defaults'} }
sub _args_to_items
{
my($self) = shift;
my $items = $self->SUPER::_args_to_items(@_);
# All items in the group must have the same name
foreach my $item (@$items)
{
$item->name($self->local_name);
#$item->name($self->name);
}
return (wantarray) ? @$items : $items;
}
sub item
{
my($self, $value) = @_;
my $group_class = $self->_item_group_class;
# Dumb linear search for now
foreach my $item ($self->items)
{
if($item->isa($group_class))
{
foreach my $subitem ($item->items)
{
return $subitem if($subitem->html_attr('value') eq $value);
}
}
else
{
return $item if($item->html_attr('value') eq $value);
}
}
return undef;
}
sub item_group
{
my($self, $label) = @_;
my $group_class = $self->_item_group_class;
# Dumb linear search for now
foreach my $item ($self->items)
{
return $item if($item->isa($group_class) && $item->label eq $label);
}
return undef;
}
sub is_selected
{
my($self, $value) = @_;
# Dumb linear search for now
foreach my $item ($self->items)
{
if($item->html_attr('value') eq $value && $item->internal_value)
{
return 1;
}
}
return 0;
}
*is_checked = \&is_selected;
sub is_empty
{
my($self) = shift;
foreach my $item ($self->items)
{
return 0 if($item->is_on);
}
return 1;
}
sub add_values
{
my($self) = shift;
$self->input_value($self->internal_value, @_);
}
sub add_value { shift->add_values(@_) }
sub input_value
{
my($self) = shift;
my %values;
if(@_)
{
$self->clear();
$self->is_cleared(0);
if(@_ == 1 && ref $_[0] eq 'ARRAY')
{
%values = map { $_ => 1 } @{$_[0]};
}
elsif(@_ && defined $_[0])
{
%values = map { $_ => 1 } @_;
}
unless(%values)
{
$self->clear();
$self->is_cleared(0);
}
else
{
$self->{'values'} = \%values;
$self->init_items;
}
if(my $parent = $self->parent_field)
{
if($parent->_is_full)
{
$parent->is_cleared(0);
}
if($self->auto_invalidate_parent)
{
$parent->invalidate_value;
}
}
}
else
{
if(keys %{$self->{'values'}})
{
my $group_class = $self->_item_group_class;
foreach my $item ($self->items)
{
if($item->isa($group_class))
{
foreach my $value ($item->internal_value)
{
$values{$value} = 1;
}
}
else
{
if($item->is_on)
{
$values{$item->html_attr('value')} = 1;
}
}
}
}
}
return (wantarray) ? sort keys %values : [ sort keys %values ];
}
sub value_labels
{
my($self) = shift;
my @labels;
foreach my $value ($self->internal_value)
{
next unless(defined $value);
push(@labels, $self->item($value)->label);
}
return wantarray ? @labels : \@labels;
}
sub value_label
{
my($self) = shift;
unless(@_)
{
return $self->value_labels->[0];
}
my $value = shift;
# Dumb linear search for now
foreach my $item ($self->items)
{
if($item->html_attr('value') eq $value)
{
return $item-label(@_) if(@_);
return ($item->label) ? $item->label : $value;
}
}
return undef;
}
#sub value_label { shift->value_labels->[0] }
sub value { shift->input_value(@_) }
sub values { shift->input_value(@_) }
sub is_on { Carp::croak "Override in subclass!" }
sub internal_value
{
my($self) = shift;
my @values;
my $group_class = $self->_item_group_class;
foreach my $item ($self->items)
{
if($item->isa($group_class))
{
push(@values, $item->internal_value) if(defined $item->internal_value);
}
else
{
push(@values, $item->value) if($item->is_on);
}
}
@values = sort @values; # Makes tests easier to write... :-/
return wantarray ? @values : \@values;
}
*output_value = \&internal_value;
sub input_values_hash { (wantarray) ? %{$_[0]->{'values'}} : $_[0]->{'values'} }
sub has_value
{
my($self, $find_value) = @_;
foreach my $value ($self->output_value)
{
return 1 if($value eq $find_value);
}
return 0;
}
sub init_items
{
my($self) = shift;
my $values = $self->input_values_hash || {};
if(%$values)
{
my $group_class = $self->_item_group_class;
foreach my $item ($self->items)
{
local $item->{'auto_invalidate_parent'} = $self->auto_invalidate_parent;
if($item->isa($group_class))
{
foreach my $subitem ($item->items)
{
if(exists $values->{$subitem->html_attr('value')})
{
$subitem->input_value(1);
}
else
{
$subitem->input_value(0);
}
}
}
else
{
if(exists $values->{$item->html_attr('value')})
{
$item->input_value(1);
}
else
{
$item->input_value(0);
}
}
}
}
elsif(!$self->is_cleared)
{
my $defaults = $self->default_values_hash;
foreach my $item ($self->items)
{
my $value = $item->html_attr('value');
if(defined $value && exists $defaults->{$value})
{
$item->default_value(1);
}
else
{
$item->default_value(0);
}
}
}
}
1;