Commit | Line | Data |
ddccc6a2 |
1 | package Reaction::UI::ViewPort::Field::Mutable::ChooseMany; |
2 | |
3 | use Reaction::Class; |
4 | |
5 | my $listify = sub{ |
1734a92a |
6 | return [] unless defined($_[0]); |
ddccc6a2 |
7 | return ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]]; |
8 | }; |
9 | |
81393881 |
10 | use namespace::clean -except => [ qw(meta) ]; |
7b5e71ad |
11 | use MooseX::Types::Moose qw/ArrayRef/; |
81393881 |
12 | extends 'Reaction::UI::ViewPort::Field'; |
13 | |
22a2b243 |
14 | with 'Reaction::UI::ViewPort::Field::Role::Mutable' => { value_type => 'ArrayRef' }; |
81393881 |
15 | with 'Reaction::UI::ViewPort::Field::Role::Choices'; |
16 | |
17 | #MUST BE HERE, BELOW THE 'does', OR THE TRIGGER WILL NOT HAPPEN! |
22a2b243 |
18 | #has '+value' => (isa => ArrayRef); |
81393881 |
19 | |
20 | around value => sub { |
21 | my $orig = shift; |
22 | my $self = shift; |
23 | return $orig->($self) unless @_; |
24 | my $value = $listify->(shift); |
25 | $_ = $self->str_to_ident($_) for @$value; |
26 | my $checked = $self->attribute->check_valid_value($self->model, $value); |
27 | # i.e. fail if any of the values fail |
28 | confess "Not a valid set of values" |
29 | if (@$checked < @$value || grep { !defined($_) } @$checked); |
30 | $orig->($self, $checked); |
31 | }; |
32 | |
ddccc6a2 |
33 | |
81393881 |
34 | around _value_string_from_value => sub { |
35 | my $orig = shift; |
36 | my $self = shift; |
37 | join(", ", (map {$self->obj_to_name($_->{value}) } @{ $self->current_value_choices })); |
38 | }; |
39 | sub is_current_value { |
40 | my ($self, $check_value) = @_; |
41 | return unless $self->_model_has_value; |
42 | my @our_values = @{$self->value || []}; |
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 | }; |
46 | sub current_value_choices { |
47 | my $self = shift; |
48 | my @all = grep { $self->is_current_value($_->{value}) } @{$self->value_choices}; |
49 | return [ @all ]; |
50 | }; |
51 | sub available_value_choices { |
52 | my $self = shift; |
53 | my @all = grep { !$self->is_current_value($_->{value}) } @{$self->value_choices}; |
54 | return [ @all ]; |
ddccc6a2 |
55 | }; |
56 | |
81393881 |
57 | around handle_events => sub { |
58 | my $orig = shift; |
59 | my ($self, $events) = @_; |
60 | $events->{value} = [] if $events->{no_current_value}; |
61 | my $ev_value = $listify->($events->{value}); |
62 | if (delete $events->{add_all_values}) { |
63 | $events->{value} = [map {$self->obj_to_str($_)} @{$self->valid_values}]; |
64 | } elsif (exists $events->{add_values} && delete $events->{do_add_values}) { |
65 | my $add = $listify->(delete $events->{add_values}); |
66 | $events->{value} = [ @{$ev_value}, @$add ]; |
67 | } elsif (delete $events->{remove_all_values}) { |
68 | $events->{value} = []; |
69 | }elsif (exists $events->{remove_values} && delete $events->{do_remove_values}) { |
70 | my $remove = $listify->(delete $events->{remove_values}); |
71 | my %r = map { ($_ => 1) } @$remove; |
72 | $events->{value} = [ grep { !$r{$_} } @{$ev_value} ]; |
73 | } |
74 | |
75 | return $orig->(@_); |
76 | }; |
77 | |
78 | __PACKAGE__->meta->make_immutable; |
79 | |
80 | |
ddccc6a2 |
81 | 1; |
82 | |
83 | =head1 NAME |
84 | |
e516f7e6 |
85 | Reaction::UI::ViewPort::Field::Mutable::ChooseMany |
ddccc6a2 |
86 | |
87 | =head1 DESCRIPTION |
88 | |
89 | =head1 METHODS |
90 | |
91 | =head2 is_current_value |
92 | |
93 | =head2 current_values |
94 | |
95 | =head2 available_values |
96 | |
97 | =head2 available_value_names |
98 | |
99 | =head1 SEE ALSO |
100 | |
101 | =head2 L<Reaction::UI::ViewPort::Field> |
102 | |
103 | =head1 AUTHORS |
104 | |
105 | See L<Reaction::Class> for authors. |
106 | |
107 | =head1 LICENSE |
108 | |
109 | See L<Reaction::Class> for the license. |
110 | |
111 | =cut |