Commit | Line | Data |
7adfd53f |
1 | package Reaction::UI::ViewPort::Field::ChooseMany; |
2 | |
3 | use Reaction::Class; |
4 | |
5 | class ChooseMany is 'Reaction::UI::ViewPort::Field::ChooseOne', which { |
6 | |
6ab43711 |
7 | #has '+layout' => (default => 'dual_select_group'); |
7adfd53f |
8 | has '+value' => (isa => 'ArrayRef'); |
f670cfd0 |
9 | |
7adfd53f |
10 | my $listify = sub { # quick utility function, $listify->($arg) |
11 | return (defined($_[0]) |
12 | ? (ref($_[0]) eq 'ARRAY' |
13 | ? $_[0] # \@arr => \@arr |
14 | : [$_[0]]) # $scalar => [$scalar] |
15 | : []); # undef => [] |
16 | }; |
f670cfd0 |
17 | |
7adfd53f |
18 | around value => sub { |
19 | my $orig = shift; |
20 | my $self = shift; |
21 | if (@_) { |
22 | my $value = $listify->(shift); |
23 | if (defined $value) { |
f670cfd0 |
24 | $_ = $self->str_to_ident($_) for @$value; |
7adfd53f |
25 | my $checked = $self->attribute->check_valid_value($self->action, $value); |
26 | # i.e. fail if any of the values fail |
f670cfd0 |
27 | confess "Not a valid set of values" |
28 | if (@$checked < @$value || grep { !defined($_) } @$checked); |
7adfd53f |
29 | |
30 | $value = $checked; |
31 | } |
32 | $orig->($self, $value); |
33 | } else { |
34 | $orig->($self); |
35 | } |
36 | }; |
f670cfd0 |
37 | |
1734a92a |
38 | implements _empty_value => as { [] }; |
f670cfd0 |
39 | |
7adfd53f |
40 | implements is_current_value => as { |
41 | my ($self, $check_value) = @_; |
42 | my @our_values = @{$self->value||[]}; |
7adfd53f |
43 | $check_value = $self->obj_to_str($check_value) if ref($check_value); |
44 | return grep { $self->obj_to_str($_) eq $check_value } @our_values; |
45 | }; |
f670cfd0 |
46 | |
9de685fc |
47 | implements current_value_choices => as { |
7adfd53f |
48 | my $self = shift; |
9de685fc |
49 | my @all = grep { $self->is_current_value($_->{value}) } @{$self->value_choices}; |
7adfd53f |
50 | return [ @all ]; |
51 | }; |
f670cfd0 |
52 | |
9de685fc |
53 | implements available_value_choices => as { |
7adfd53f |
54 | my $self = shift; |
9de685fc |
55 | my @all = grep { !$self->is_current_value($_->{value}) } @{$self->value_choices}; |
7adfd53f |
56 | return [ @all ]; |
57 | }; |
f670cfd0 |
58 | |
7adfd53f |
59 | around handle_events => sub { |
60 | my $orig = shift; |
61 | my ($self, $events) = @_; |
62 | my $ev_value = $listify->($events->{value}); |
63 | if (delete $events->{add_all_values}) { |
f670cfd0 |
64 | $events->{value} = [map {$self->obj_to_str($_)} @{$self->valid_values}]; |
9de685fc |
65 | } elsif (exists $events->{add_values} && delete $events->{do_add_values}) { |
7adfd53f |
66 | my $add = $listify->(delete $events->{add_values}); |
67 | $events->{value} = [ @{$ev_value}, @$add ]; |
9de685fc |
68 | } elsif (delete $events->{remove_all_values}) { |
7adfd53f |
69 | $events->{value} = []; |
9de685fc |
70 | }elsif (exists $events->{remove_values} && delete $events->{do_remove_values}) { |
7adfd53f |
71 | my $remove = $listify->(delete $events->{remove_values}); |
72 | my %r = map { ($_ => 1) } @$remove; |
73 | $events->{value} = [ grep { !$r{$_} } @{$ev_value} ]; |
74 | } |
75 | return $orig->(@_); |
76 | }; |
77 | |
78 | }; |
79 | |
80 | 1; |
81 | |
82 | =head1 NAME |
83 | |
84 | Reaction::UI::ViewPort::Field::ChooseMany |
85 | |
86 | =head1 DESCRIPTION |
87 | |
88 | =head1 METHODS |
89 | |
90 | =head2 is_current_value |
91 | |
92 | =head2 current_values |
93 | |
94 | =head2 available_values |
95 | |
96 | =head2 available_value_names |
97 | |
98 | =head1 SEE ALSO |
99 | |
100 | =head2 L<Reaction::UI::ViewPort::Field> |
101 | |
102 | =head1 AUTHORS |
103 | |
104 | See L<Reaction::Class> for authors. |
105 | |
106 | =head1 LICENSE |
107 | |
108 | See L<Reaction::Class> for the license. |
109 | |
110 | =cut |