Commit | Line | Data |
7adfd53f |
1 | package Reaction::UI::ViewPort::Field::ChooseOne; |
2 | |
3 | use Reaction::Class; |
4 | use URI; |
5 | use Scalar::Util 'blessed'; |
6 | |
7 | class ChooseOne is 'Reaction::UI::ViewPort::Field', which { |
8 | |
9 | has '+layout' => (default => 'select'); |
f670cfd0 |
10 | |
7adfd53f |
11 | has valid_value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1); |
f670cfd0 |
12 | |
7adfd53f |
13 | has valid_values => (isa => 'ArrayRef', is => 'ro', lazy_build => 1); |
f670cfd0 |
14 | |
7adfd53f |
15 | has name_to_value_map => (isa => 'HashRef', is => 'ro', lazy_build => 1); |
f670cfd0 |
16 | |
7adfd53f |
17 | has value_to_name_map => (isa => 'HashRef', is => 'ro', lazy_build => 1); |
f670cfd0 |
18 | |
7adfd53f |
19 | has value_map_method => ( |
20 | isa => 'Str', is => 'ro', required => 1, default => sub { 'display_name' }, |
21 | ); |
f670cfd0 |
22 | |
7adfd53f |
23 | around value => sub { |
24 | my $orig = shift; |
25 | my $self = shift; |
26 | if (@_) { |
27 | my $value = shift; |
28 | if (defined $value) { |
29 | if (!ref $value) { |
30 | $value = $self->str_to_ident($value); |
31 | } |
32 | my $checked = $self->attribute->check_valid_value($self->action, $value); |
33 | confess "${value} is not a valid value" unless defined($checked); |
34 | $value = $checked; |
35 | } |
36 | $orig->($self, $value); |
37 | } else { |
38 | $orig->($self); |
39 | } |
40 | }; |
f670cfd0 |
41 | |
7adfd53f |
42 | implements build_valid_values => as { |
43 | my $self = shift; |
44 | return [ $self->attribute->all_valid_values($self->action) ]; |
45 | }; |
f670cfd0 |
46 | |
7adfd53f |
47 | implements build_valid_value_names => as { |
48 | my $self = shift; |
49 | my $all = $self->valid_values; |
50 | my $meth = $self->value_map_method; |
51 | my @names = map { $_->$meth } @$all; |
52 | return [ sort @names ]; |
53 | }; |
f670cfd0 |
54 | |
7adfd53f |
55 | implements build_name_to_value_map => as { |
56 | my $self = shift; |
57 | my $all = $self->valid_values; |
58 | my $meth = $self->value_map_method; |
59 | my %map; |
60 | $map{$_->$meth} = $self->obj_to_str($_) for @$all; |
61 | return \%map; |
62 | }; |
f670cfd0 |
63 | |
7adfd53f |
64 | implements build_value_to_name_map => as { |
65 | my $self = shift; |
66 | my $all = $self->valid_values; |
67 | my $meth = $self->value_map_method; |
68 | my %map; |
69 | $map{$self->obj_to_str($_)} = $_->$meth for @$all; |
70 | return \%map; |
71 | }; |
f670cfd0 |
72 | |
7adfd53f |
73 | implements is_current_value => as { |
74 | my ($self, $check_value) = @_; |
75 | my $our_value = $self->value; |
76 | return unless ref($our_value); |
77 | $check_value = $self->obj_to_str($check_value) if ref($check_value); |
78 | return $self->obj_to_str($our_value) eq $check_value; |
79 | }; |
80 | |
81 | implements str_to_ident => as { |
82 | my ($self, $str) = @_; |
83 | my $u = URI->new('','http'); |
84 | $u->query($str); |
85 | return { $u->query_form }; |
86 | }; |
87 | |
88 | implements obj_to_str => as { |
89 | my ($self, $obj) = @_; |
90 | return $obj unless ref($obj); |
91 | confess "${obj} not an object" unless blessed($obj); |
92 | my $ident = $obj->ident_condition; |
93 | my $u = URI->new('', 'http'); |
94 | $u->query_form(%$ident); |
95 | return $u->query; |
96 | }; |
97 | |
98 | }; |
99 | |
100 | 1; |
101 | |
102 | =head1 NAME |
103 | |
104 | Reaction::UI::ViewPort::Field::ChooseOne |
105 | |
106 | =head1 DESCRIPTION |
107 | |
108 | =head1 METHODS |
109 | |
110 | =head2 is_current_value |
111 | |
112 | =head2 value |
113 | |
114 | =head2 valid_values |
115 | |
116 | =head2 valid_value_names |
117 | |
118 | =head2 value_to_name_map |
119 | |
120 | =head2 name_to_value_map |
121 | |
122 | =head2 str_to_ident |
123 | |
124 | =head2 obj_to_str |
125 | |
126 | =head1 SEE ALSO |
127 | |
128 | =head2 L<Reaction::UI::ViewPort::Field> |
129 | |
130 | =head1 AUTHORS |
131 | |
132 | See L<Reaction::Class> for authors. |
133 | |
134 | =head1 LICENSE |
135 | |
136 | See L<Reaction::Class> for the license. |
137 | |
138 | =cut |