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 | |
7 | has '+layout' => (default => 'dual_select_group'); |
f670cfd0 |
8 | |
7adfd53f |
9 | has '+value' => (isa => 'ArrayRef'); |
f670cfd0 |
10 | |
11 | has available_value_names => |
7adfd53f |
12 | (isa => 'ArrayRef', is => 'ro', lazy_build => 1); |
f670cfd0 |
13 | |
7adfd53f |
14 | has value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1); |
f670cfd0 |
15 | |
7adfd53f |
16 | my $listify = sub { # quick utility function, $listify->($arg) |
17 | return (defined($_[0]) |
18 | ? (ref($_[0]) eq 'ARRAY' |
19 | ? $_[0] # \@arr => \@arr |
20 | : [$_[0]]) # $scalar => [$scalar] |
21 | : []); # undef => [] |
22 | }; |
f670cfd0 |
23 | |
7adfd53f |
24 | around value => sub { |
25 | my $orig = shift; |
26 | my $self = shift; |
27 | if (@_) { |
28 | my $value = $listify->(shift); |
29 | if (defined $value) { |
f670cfd0 |
30 | $_ = $self->str_to_ident($_) for @$value; |
7adfd53f |
31 | my $checked = $self->attribute->check_valid_value($self->action, $value); |
32 | # i.e. fail if any of the values fail |
f670cfd0 |
33 | confess "Not a valid set of values" |
34 | if (@$checked < @$value || grep { !defined($_) } @$checked); |
7adfd53f |
35 | |
36 | $value = $checked; |
37 | } |
38 | $orig->($self, $value); |
39 | } else { |
40 | $orig->($self); |
41 | } |
42 | }; |
f670cfd0 |
43 | |
7adfd53f |
44 | override build_value => sub { |
45 | return super() || []; |
46 | }; |
f670cfd0 |
47 | |
7adfd53f |
48 | implements is_current_value => as { |
49 | my ($self, $check_value) = @_; |
50 | my @our_values = @{$self->value||[]}; |
51 | #$check_value = $check_value->id if ref($check_value); |
52 | #return grep { $_->id eq $check_value } @our_values; |
53 | $check_value = $self->obj_to_str($check_value) if ref($check_value); |
54 | return grep { $self->obj_to_str($_) eq $check_value } @our_values; |
55 | }; |
f670cfd0 |
56 | |
7adfd53f |
57 | implements current_values => as { |
58 | my $self = shift; |
59 | my @all = grep { $self->is_current_value($_) } @{$self->valid_values}; |
60 | return [ @all ]; |
61 | }; |
f670cfd0 |
62 | |
7adfd53f |
63 | implements available_values => as { |
64 | my $self = shift; |
65 | my @all = grep { !$self->is_current_value($_) } @{$self->valid_values}; |
66 | return [ @all ]; |
67 | }; |
f670cfd0 |
68 | |
7adfd53f |
69 | implements build_available_value_names => as { |
70 | my $self = shift; |
71 | my @all = @{$self->available_values}; |
72 | my $meth = $self->value_map_method; |
73 | my @names = map { $_->$meth } @all; |
74 | return [ sort @names ]; |
75 | }; |
f670cfd0 |
76 | |
7adfd53f |
77 | implements build_value_names => as { |
78 | my $self = shift; |
79 | my @all = @{$self->value||[]}; |
80 | my $meth = $self->value_map_method; |
81 | my @names = map { $_->$meth } @all; |
82 | return [ sort @names ]; |
83 | }; |
f670cfd0 |
84 | |
7adfd53f |
85 | around handle_events => sub { |
86 | my $orig = shift; |
87 | my ($self, $events) = @_; |
88 | my $ev_value = $listify->($events->{value}); |
89 | if (delete $events->{add_all_values}) { |
f670cfd0 |
90 | delete $events->{add_values}; |
91 | delete $events->{remove_values}; |
92 | $events->{value} = [map {$self->obj_to_str($_)} @{$self->valid_values}]; |
93 | } |
7adfd53f |
94 | if (delete $events->{do_add_values} && exists $events->{add_values}) { |
95 | my $add = $listify->(delete $events->{add_values}); |
96 | $events->{value} = [ @{$ev_value}, @$add ]; |
97 | } |
98 | if (delete $events->{remove_all_values}) { |
f670cfd0 |
99 | delete $events->{add_values}; |
100 | delete $events->{remove_values}; |
7adfd53f |
101 | $events->{value} = []; |
f670cfd0 |
102 | } |
7adfd53f |
103 | if (delete $events->{do_remove_values} && exists $events->{remove_values}) { |
104 | my $remove = $listify->(delete $events->{remove_values}); |
105 | my %r = map { ($_ => 1) } @$remove; |
106 | $events->{value} = [ grep { !$r{$_} } @{$ev_value} ]; |
107 | } |
108 | return $orig->(@_); |
109 | }; |
110 | |
111 | }; |
112 | |
113 | 1; |
114 | |
115 | =head1 NAME |
116 | |
117 | Reaction::UI::ViewPort::Field::ChooseMany |
118 | |
119 | =head1 DESCRIPTION |
120 | |
121 | =head1 METHODS |
122 | |
123 | =head2 is_current_value |
124 | |
125 | =head2 current_values |
126 | |
127 | =head2 available_values |
128 | |
129 | =head2 available_value_names |
130 | |
131 | =head1 SEE ALSO |
132 | |
133 | =head2 L<Reaction::UI::ViewPort::Field> |
134 | |
135 | =head1 AUTHORS |
136 | |
137 | See L<Reaction::Class> for authors. |
138 | |
139 | =head1 LICENSE |
140 | |
141 | See L<Reaction::Class> for the license. |
142 | |
143 | =cut |