Commit | Line | Data |
7adfd53f |
1 | package Reaction::UI::ViewPort::Field; |
2 | |
3 | use Reaction::Class; |
ddccc6a2 |
4 | use aliased 'Reaction::InterfaceModel::Object'; |
5 | use aliased 'Reaction::Meta::InterfaceModel::Object::ParameterAttribute'; |
7adfd53f |
6 | |
7 | class Field is 'Reaction::UI::ViewPort', which { |
8 | |
da57cbb2 |
9 | has value => (is => 'rw', lazy_build => 1); |
ddccc6a2 |
10 | has name => (is => 'rw', isa => 'Str', lazy_build => 1); |
11 | has label => (is => 'rw', isa => 'Str', lazy_build => 1); |
12 | has value_string => (is => 'rw', isa => 'Str', lazy_build => 1); |
7adfd53f |
13 | |
ddccc6a2 |
14 | has model => (is => 'ro', isa => Object, required => 1); |
15 | has attribute => (is => 'ro', isa => ParameterAttribute, required => 1); |
7adfd53f |
16 | |
ddccc6a2 |
17 | implements _build_name => as { shift->attribute->name }; |
7adfd53f |
18 | |
89939ff9 |
19 | implements _build_label => as { |
ddccc6a2 |
20 | join(' ', map { ucfirst } split('_', shift->name)); |
7adfd53f |
21 | }; |
22 | |
89939ff9 |
23 | implements _build_value => as { |
7adfd53f |
24 | my ($self) = @_; |
ddccc6a2 |
25 | my $reader = $self->attribute->get_read_method; |
656d19e9 |
26 | return $self->model->$reader; |
27 | }; |
28 | |
29 | implements _model_has_value => as { |
30 | my ($self) = @_; |
ddccc6a2 |
31 | my $predicate = $self->attribute->predicate; |
c03f75a7 |
32 | |
398c8477 |
33 | if (!$predicate || $self->model->$predicate |
80bb08dc |
34 | || ($self->attribute->is_lazy |
cbbaa612 |
35 | && !$self->attribute->is_lazy_fail) |
80bb08dc |
36 | ) { |
656d19e9 |
37 | # either model attribute has a value now or can build it |
38 | return 1; |
398c8477 |
39 | } |
656d19e9 |
40 | return 0; |
41 | }; |
42 | |
43 | implements _build_value_string => as { |
44 | my ($self) = @_; |
45 | # XXX need the defined test because the IM lazy builds from |
46 | # the model and DBIC can have nullable fields and DBIC doesn't |
47 | # have a way to tell us that doesn't force value inflation (extra |
48 | # SELECTs for belongs_to) so basically we're screwed. |
49 | return ($self->_model_has_value && defined($self->value) |
50 | ? $self->_value_string_from_value |
51 | : $self->_empty_string_value); |
52 | }; |
53 | |
54 | implements _value_string_from_value => as { |
55 | shift->value; |
7adfd53f |
56 | }; |
57 | |
656d19e9 |
58 | implements _empty_string_value => as { '' }; |
398c8477 |
59 | |
f25cb331 |
60 | implements value_is_required => as { |
61 | shift->attribute->is_required; |
62 | }; |
63 | |
7adfd53f |
64 | }; |
65 | |
66 | 1; |
2dba7201 |
67 | __END__; |
68 | |
69 | =head1 NAME |
70 | |
71 | Reaction::UI::ViewPort::Field |
72 | |
73 | =head1 DESCRIPTION |
74 | |
75 | =head1 ATTRIBUTES |
76 | |
77 | =head2 model |
78 | |
79 | =head2 attribute |
80 | |
81 | =head2 value |
82 | |
83 | =head2 name |
84 | |
85 | =head2 label |
86 | |
87 | =head2 value_string |
88 | |
89 | =head1 AUTHORS |
90 | |
91 | See L<Reaction::Class> for authors. |
92 | |
93 | =head1 LICENSE |
94 | |
95 | See L<Reaction::Class> for the license. |
96 | |
97 | =cut |