debug for button events - missed on last commit
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Action.pm
CommitLineData
ddccc6a2 1package Reaction::UI::ViewPort::Action;
2
3use Reaction::Class;
4
7b5e71ad 5use MooseX::Types::URI qw/Uri/;
e29819c4 6use MooseX::Types::Moose qw/Int Str/;
7b5e71ad 7use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
08451970 8
9use namespace::clean -except => [ qw(meta) ];
b343a983 10
11extends 'Reaction::UI::ViewPort::Object::Mutable';
08451970 12with 'Reaction::UI::ViewPort::Action::Role::OK';
13
e29819c4 14has message => (is => 'rw', isa => Str);
eb52e595 15has '+model' => (handles => [qw/error_message has_error_message/]);
e29819c4 16
b343a983 17#this has to fucking go. it BLOWS.
18has method => (
19 is => 'rw',
20 isa => NonEmptySimpleStr,
21 default => sub { 'post' }
22);
08451970 23
7b5e71ad 24has action => ( is => 'rw', isa => Uri );
25
08451970 26has changed => (
27 is => 'rw',
28 isa => Int,
29 reader => 'is_changed',
30 default => sub{0}
b343a983 31);
08451970 32
33sub can_apply {
34 my ($self) = @_;
35 foreach my $field ( @{ $self->fields } ) {
36 return 0 if $field->needs_sync;
37 # if e.g. a datetime field has an invalid value that can't be re-assembled
38 # into a datetime object, the action may be in a consistent state but
39 # not synchronized from the fields; in this case, we must not apply
40 }
41 return $self->model->can_apply;
42}
43
44sub do_apply {
45 shift->model->do_apply;
46}
47
48after apply_child_events => sub {
49 # interrupt here because fields will have been updated
50 my ($self) = @_;
51 $self->sync_action_from_fields;
52};
53
54sub sync_action_from_fields {
55 my ($self) = @_;
56 foreach my $field (@{$self->fields}) {
57 $field->sync_to_action; # get the field to populate the $action if possible
58 }
59 $self->model->sync_all;
60 foreach my $field (@{$self->fields}) {
61 $field->sync_from_action; # get errors from $action if applicable
62 }
63}
64
5aec9cb9 65after handle_events => sub {
66 my ($self, $events) = @_;
67 foreach my $event ($self->accept_events) {
68 unless (exists $events->{$event} ) {
69 # for <input type="image"... buttons
70 if ( exists $events->{"${event}.x"} && exists $events->{"${event}.y"} ) {
1ca3c638 71 $self->_dump_event($event, $events->{$event}) if DEBUG_EVENTS;
5aec9cb9 72 $self->$event($events->{$event});
73 }
74 }
75 }
76};
81393881 77
78__PACKAGE__->meta->make_immutable;
79
114916fc 801;
ddccc6a2 81
114916fc 82__END__;
ddccc6a2 83
08451970 84=head1 NAME
85
63bb30b4 86Reaction::UI::ViewPort::Action - Provide user with a form with OK, Apply and Close.
08451970 87
88=head1 SYNOPSIS
89
63bb30b4 90 $controller->push_viewport('Reaction::UI::ViewPort::Action',
91 model => $interface_model_action,
92 field_order => [qw( firstname lastname )],
93 excluded_fields => [qw( password )],
94 );
95
08451970 96=head1 DESCRIPTION
97
599c1172 98This subclass of L<Reaction::UI::ViewPort::Object::Mutable> is used for
99rendering a complete form supporting Apply, Close and OK.
08451970 100
101=head1 ATTRIBUTES
102
63bb30b4 103=head2 message
104
105=head2 model
106
107Inherited from L<Reaction::UI::ViewPort::Object::Mutable>. Must be a
108L<Reaction::InterfaceModel::Action>.
109
110Also handles C<error_message> and C<has_error_message> methods.
111
599c1172 112=head2 method
08451970 113
599c1172 114post / get
08451970 115
116=head2 changed
117
118Returns true if a field has been edited.
119
08451970 120=head1 METHODS
121
599c1172 122=head2 can_apply
08451970 123
63bb30b4 124Returns true if no field C<needs_sync> and the L</model> C<can_apply>.
125
599c1172 126=head2 do_apply
08451970 127
63bb30b4 128Delegates to C<do_apply> on the L</model>, which is a
129L<Reaction::InterfaceModel::Action>.
130
599c1172 131=head2 sync_action_from_fields
08451970 132
63bb30b4 133Firstly calls C<sync_to_action> on every L<Reaction::UI::ViewPort::Field::Mutable>
134in L<fields|Reaction::UI::ViewPort::Object/fields>. Then it calls C<sync_all> on
135the L<Reaction::InterfaceModel::Action> in L</model>. Next it will call
136C<sync_from_action> on every field to repopulate them from the L</model>.
137
138=head1 SUBCLASSING
139
140 package MyApp::UI::ViewPort::Action;
141 use Reaction::Class;
142 use MooseX::Types::Moose qw( Int );
143
144 use namespace::clean -except => 'meta';
145
146 extends 'Reaction::UI::ViewPort::Action';
147
148 has render_timestamp => (
149 is => 'ro',
150 isa => Int,
151 default => sub { time },
152 required => 1,
153 );
154
155 has '+field_order' => (default => sub {[qw( firstname lastname )]});
156
157 1;
158
599c1172 159=head1 SEE ALSO
08451970 160
599c1172 161L<Reaction::UI::ViewPort>
08451970 162
599c1172 163L<Reaction::UI::ViewPort::Object>
08451970 164
599c1172 165L<Reaction::UI::ViewPort::Object::Mutable>
08451970 166
599c1172 167L<Reaction::InterfaceModel::Action::Role::Apply>
08451970 168
599c1172 169L<Reaction::InterfaceModel::Action::Role::Close>
08451970 170
599c1172 171L<Reaction::InterfaceModel::Action::Role::OK>
08451970 172
173=head1 AUTHORS
174
175See L<Reaction::Class> for authors.
176
177=head1 LICENSE
178
179See L<Reaction::Class> for the license.
180
181=cut
182