class ActionForm is 'Reaction::UI::ViewPort', which {
has action => (
- isa => 'Reaction::InterfaceModel::Action', is => 'ro', required => 1
- );
-
- has field_names => (isa => 'ArrayRef', is => 'rw', lazy_build => 1);
-
+ isa => 'Reaction::InterfaceModel::Action', is => 'ro', required => 1
+ );
+
+ has ordered_fields => (is => 'rw', isa => 'ArrayRef', lazy_build => 1);
+
has _field_map => (
- isa => 'HashRef', is => 'rw', init_arg => 'fields',
- predicate => '_has_field_map', set_or_lazy_build('field_map'),
- );
-
+ isa => 'HashRef', is => 'rw', init_arg => 'fields', lazy_build => 1,
+ );
+
has changed => (
- isa => 'Int', is => 'rw', reader => 'is_changed', default => sub { 0 }
- );
+ isa => 'Int', is => 'rw', reader => 'is_changed', default => sub { 0 }
+ );
has next_action => (
- isa => 'ArrayRef', is => 'rw', required => 0, predicate => 'has_next_action'
- );
-
+ isa => 'ArrayRef', is => 'rw', required => 0, predicate => 'has_next_action'
+ );
+
has on_apply_callback => (
- isa => 'CodeRef', is => 'rw', required => 0,
- predicate => 'has_on_apply_callback'
- );
-
+ isa => 'CodeRef', is => 'rw', required => 0,
+ predicate => 'has_on_apply_callback'
+ );
+
has ok_label => (
- isa => 'Str', is => 'rw', required => 1, default => sub { 'ok' }
- );
-
+ isa => 'Str', is => 'rw', required => 1, default => sub { 'ok' }
+ );
+
has apply_label => (
- isa => 'Str', is => 'rw', required => 1, default => sub { 'apply' }
- );
-
+ isa => 'Str', is => 'rw', required => 1, default => sub { 'apply' }
+ );
+
has close_label => (isa => 'Str', is => 'rw', lazy_fail => 1);
-
+
has close_label_close => (
- isa => 'Str', is => 'rw', required => 1, default => sub { 'close' }
- );
-
+ isa => 'Str', is => 'rw', required => 1, default => sub { 'close' }
+ );
+
has close_label_cancel => (
- isa => 'Str', is => 'rw', required => 1, default => sub { 'cancel' }
- );
-
+ isa => 'Str', is => 'rw', required => 1, default => sub { 'cancel' }
+ );
+
sub fields { shift->_field_map }
-
+
implements BUILD => as {
my ($self, $args) = @_;
unless ($self->_has_field_map) {
my @field_map;
my $action = $self->action;
foreach my $attr ($action->parameter_attributes) {
- push(@field_map, $self->build_fields_for($attr => $args));
+ push(@field_map, $self->_build_fields_for($attr => $args));
}
-
- my %field_map = @field_map;
- my @field_names = @{ $self->sort_by_spec(
- $args->{column_order}, [keys %field_map] )};
-
- $self->_field_map(\%field_map);
- $self->field_names(\@field_names);
+ $self->_field_map({ @field_map });
}
$self->close_label($self->close_label_close);
};
-
- implements build_fields_for => as {
+
+ implements _build_fields_for => as {
my ($self, $attr, $args) = @_;
my $attr_name = $attr->name;
#TODO: DOCUMENT ME!!!!!!!!!!!!!!!!!
- my $builder = "build_fields_for_name_${attr_name}";
+ my $builder = "_build_fields_for_name_${attr_name}";
my @fields;
if ($self->can($builder)) {
@fields = $self->$builder($attr, $args); # re-use coderef from can()
my $constraint = $attr->type_constraint;
my $base_name = $constraint->name;
my $tried_isa = 0;
- CONSTRAINT: while (defined($constraint)) {
+ CONSTRAINT: while (defined($constraint)) {
my $name = $constraint->name;
+ $name = $attr->_isa_metadata if($name eq '__ANON__');
if (eval { $name->can('meta') } && !$tried_isa++) {
foreach my $class ($name->meta->class_precedence_list) {
my $mangled_name = $class;
$mangled_name =~ s/:+/_/g;
- my $builder = "build_fields_for_type_${mangled_name}";
+ my $builder = "_build_fields_for_type_${mangled_name}";
if ($self->can($builder)) {
@fields = $self->$builder($attr, $args);
last CONSTRAINT;
}
my $mangled_name = $name;
$mangled_name =~ s/:+/_/g;
- my $builder = "build_fields_for_type_${mangled_name}";
+ my $builder = "_build_fields_for_type_${mangled_name}";
if ($self->can($builder)) {
@fields = $self->$builder($attr, $args);
last CONSTRAINT;
$constraint = $constraint->parent;
}
if (!defined($constraint)) {
- confess "Can't build field ${attr_name} of type ${base_name} without $builder method or build_fields_for_type_<type> method for type or any supertype";
+ confess "Can't build field ${attr_name} of type ${base_name} without $builder method or _build_fields_for_type_<type> method for type or any supertype";
}
} else {
confess "Can't build field ${attr} without $builder method or type constraint";
}
return @fields;
};
-
- implements build_field_map => as {
+
+ implements _build_field_map => as {
confess "Lazy field map building not supported by default";
};
-
+
+ implements _build_ordered_fields => as {
+ my $self = shift;
+ my $ordered = $self->sort_by_spec($self->column_order, [keys %{$self->_field_map}]);
+ return [@{$self->_field_map}{@$ordered}];
+ };
+
implements can_apply => as {
my ($self) = @_;
- foreach my $field (values %{$self->_field_map}) {
+ foreach my $field ( @{ $self->ordered_fields } ) {
return 0 if $field->needs_sync;
- # if e.g. a datetime field has an invalid value that can't be re-assembled
- # into a datetime object, the action may be in a consistent state but
- # not synchronized from the fields; in this case, we must not apply
+ # if e.g. a datetime field has an invalid value that can't be re-assembled
+ # into a datetime object, the action may be in a consistent state but
+ # not synchronized from the fields; in this case, we must not apply
}
return $self->action->can_apply;
};
-
+
implements do_apply => as {
my $self = shift;
return $self->action->do_apply;
};
-
+
implements ok => as {
my $self = shift;
if ($self->apply(@_)) {
$self->close(@_);
}
};
-
+
implements apply => as {
my $self = shift;
if ($self->can_apply && (my $result = $self->do_apply)) {
$self->changed(0);
$self->close_label($self->close_label_close);
- if ($self->has_on_apply_callback) {
- $self->on_apply_callback->($self => $result);
- }
+ $self->on_apply_callback->($self => $result) if $self->has_on_apply_callback;
return 1;
} else {
$self->changed(1);
return 0;
}
};
-
+
implements close => as {
my $self = shift;
my ($controller, $name, @args) = @{$self->next_action};
$controller->pop_viewport;
$controller->$name($self->action->ctx, @args);
};
-
+
sub can_close { 1 }
-
+
override accept_events => sub {
(($_[0]->has_next_action ? ('ok', 'close') : ()), 'apply', super());
}; # can't do a close-type operation if there's nowhere to go afterwards
-
+
override child_event_sinks => sub {
my ($self) = @_;
return ((grep { ref($_) =~ 'Hidden' } values %{$self->_field_map}),
(grep { ref($_) !~ 'Hidden' } values %{$self->_field_map}),
super());
};
-
+
after apply_child_events => sub {
# interrupt here because fields will have been updated
my ($self) = @_;
$self->sync_action_from_fields;
};
-
+
implements sync_action_from_fields => as {
my ($self) = @_;
my $field_map = $self->_field_map;
$field->sync_from_action; # get errors from $action if applicable
}
};
-
- implements build_simple_field => as {
+
+ implements _build_simple_field => as {
my ($self, $class, $attr, $args) = @_;
my $attr_name = $attr->name;
my %extra;
%extra = %$config;
}
my $field = $class->new(
- action => $self->action,
- attribute => $attr,
- name => $attr->name,
- location => join('-', $self->location, 'field', $attr->name),
- ctx => $self->ctx,
- %extra
- );
+ action => $self->action,
+ attribute => $attr,
+ name => $attr->name,
+ location => join('-', $self->location, 'field', $attr->name),
+ ctx => $self->ctx,
+ %extra
+ );
return ($attr_name => $field);
};
-
- implements build_fields_for_type_Num => as {
+
+ implements _build_fields_for_type_Num => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(Number, $attr, $args);
+ return $self->_build_simple_field(Number, $attr, $args);
};
-
- implements build_fields_for_type_Int => as {
+
+ implements _build_fields_for_type_Int => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(Number, $attr, $args);
+ return $self->_build_simple_field(Number, $attr, $args);
};
-
- implements build_fields_for_type_Bool => as {
+
+ implements _build_fields_for_type_Bool => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(Boolean, $attr, $args);
+ return $self->_build_simple_field(Boolean, $attr, $args);
};
-
- implements build_fields_for_type_File => as {
+
+ implements _build_fields_for_type_File => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(File, $attr, $args);
+ return $self->_build_simple_field(File, $attr, $args);
};
-
- implements build_fields_for_type_Str => as {
+
+ implements _build_fields_for_type_Str => as {
my ($self, $attr, $args) = @_;
if ($attr->has_valid_values) { # There's probably a better way to do this
- return $self->build_simple_field(ChooseOne, $attr, $args);
+ return $self->_build_simple_field(ChooseOne, $attr, $args);
}
- return $self->build_simple_field(Text, $attr, $args);
+ return $self->_build_simple_field(Text, $attr, $args);
};
-
- implements build_fields_for_type_SimpleStr => as {
+
+ implements _build_fields_for_type_SimpleStr => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(String, $attr, $args);
+ return $self->_build_simple_field(String, $attr, $args);
};
-
- implements build_fields_for_type_Password => as {
+
+ implements _build_fields_for_type_Password => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(Password, $attr, $args);
+ return $self->_build_simple_field(Password, $attr, $args);
};
-
- implements build_fields_for_type_DateTime => as {
+
+ implements _build_fields_for_type_DateTime => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(DateTime, $attr, $args);
+ return $self->_build_simple_field(DateTime, $attr, $args);
};
-
- implements build_fields_for_type_Enum => as {
+
+ implements _build_fields_for_type_Enum => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(ChooseOne, $attr, $args);
+ return $self->_build_simple_field(ChooseOne, $attr, $args);
};
-
- implements build_fields_for_type_DBIx_Class_Row => as {
+
+ #implements build_fields_for_type_Reaction_InterfaceModel_Object => as {
+ implements _build_fields_for_type_DBIx_Class_Row => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(ChooseOne, $attr, $args);
+ return $self->_build_simple_field(ChooseOne, $attr, $args);
};
-
- implements build_fields_for_type_ArrayRef => as {
+
+ implements _build_fields_for_type_ArrayRef => as {
my ($self, $attr, $args) = @_;
if ($attr->has_valid_values) {
- return $self->build_simple_field(ChooseMany, $attr, $args)
+ return $self->_build_simple_field(ChooseMany, $attr, $args)
} else {
- return $self->build_simple_field(HiddenArray, $attr, $args)
+ return $self->_build_simple_field(HiddenArray, $attr, $args)
}
};
-
- implements build_fields_for_type_DateTime_Spanset => as {
+
+ implements _build_fields_for_type_DateTime_Spanset => as {
my ($self, $attr, $args) = @_;
- return $self->build_simple_field(TimeRange, $attr, $args);
+ return $self->_build_simple_field(TimeRange, $attr, $args);
};
-
+
no Moose;
-
+
no strict 'refs';
delete ${__PACKAGE__ . '::'}{inner};
};
-1;
+ 1;
=head1 NAME
=head2 fields
-=head2 field_names
-
-Returns: Arrayref of field names.
-
=head2 can_apply
=head2 can_close