start of new widgets for fields
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Field / ChooseOne.pm
CommitLineData
7adfd53f 1package Reaction::UI::ViewPort::Field::ChooseOne;
2
3use Reaction::Class;
4use URI;
5use Scalar::Util 'blessed';
6
7class 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
1001;
101
102=head1 NAME
103
104Reaction::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
132See L<Reaction::Class> for authors.
133
134=head1 LICENSE
135
136See L<Reaction::Class> for the license.
137
138=cut