aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Reaction/UI/ViewPort/Field
diff options
context:
space:
mode:
authormatthewt <matthewt@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2008-07-24 01:42:34 +0000
committermatthewt <matthewt@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2008-07-24 01:42:34 +0000
commit8139388160b0a38002b22ff95c3fee3d8380f156 (patch)
treed7610c5db84c2c996107adb36bca1fe8a2b0b7cb /lib/Reaction/UI/ViewPort/Field
parent2a4c89335368295f0fc55f79d2c8fd5e33afd212 (diff)
downloadreaction-8139388160b0a38002b22ff95c3fee3d8380f156.tar.gz
reaction-8139388160b0a38002b22ff95c3fee3d8380f156.zip
rclass stuff ripped out of everything but widget classes
Diffstat (limited to 'lib/Reaction/UI/ViewPort/Field')
-rw-r--r--lib/Reaction/UI/ViewPort/Field/.ToDo/File.pm28
-rw-r--r--lib/Reaction/UI/ViewPort/Field/.ToDo/TimeRange.pm155
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Array.pm28
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Boolean.pm12
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Collection.pm25
-rw-r--r--lib/Reaction/UI/ViewPort/Field/DateTime.pm26
-rw-r--r--lib/Reaction/UI/ViewPort/Field/File.pm30
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Integer.pm10
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/Array.pm21
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/Boolean.pm23
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm135
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/ChooseOne.pm74
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/DateTime.pm34
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/File.pm45
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm39
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/Integer.pm16
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/MatchingPasswords.pm65
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/Number.pm14
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/Password.pm16
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/String.pm16
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/Text.pm16
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Number.pm10
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Password.pm12
-rw-r--r--lib/Reaction/UI/ViewPort/Field/RelatedObject.pm24
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Role/Choices.pm84
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm157
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm49
-rw-r--r--lib/Reaction/UI/ViewPort/Field/String.pm10
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Text.pm10
-rw-r--r--lib/Reaction/UI/ViewPort/Field/TimeRange.pm155
30 files changed, 695 insertions, 644 deletions
diff --git a/lib/Reaction/UI/ViewPort/Field/.ToDo/File.pm b/lib/Reaction/UI/ViewPort/Field/.ToDo/File.pm
index c06f1a3..4df820d 100644
--- a/lib/Reaction/UI/ViewPort/Field/.ToDo/File.pm
+++ b/lib/Reaction/UI/ViewPort/Field/.ToDo/File.pm
@@ -3,23 +3,27 @@ package Reaction::UI::ViewPort::InterfaceModel::Field::File;
use Reaction::Class;
use Reaction::Types::File;
-class File is 'Reaction::UI::ViewPort::InterfaceModel::Field', which {
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::InterfaceModel::Field';
- has '+value' => (isa => 'File', required => 0);
- override apply_our_events => sub {
- my ($self, $ctx, $events) = @_;
- my $value_key = join(':', $self->location, 'value');
- if (my $upload = $ctx->req->upload($value_key)) {
- local $events->{$value_key} = $upload;
- return super();
- } else {
- return super();
- }
- };
+has '+value' => (isa => 'File', required => 0);
+
+override apply_our_events => sub {
+ my ($self, $ctx, $events) = @_;
+ my $value_key = join(':', $self->location, 'value');
+ if (my $upload = $ctx->req->upload($value_key)) {
+ local $events->{$value_key} = $upload;
+ return super();
+ } else {
+ return super();
+ }
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
=head1 NAME
diff --git a/lib/Reaction/UI/ViewPort/Field/.ToDo/TimeRange.pm b/lib/Reaction/UI/ViewPort/Field/.ToDo/TimeRange.pm
index 9d65f2e..b411152 100644
--- a/lib/Reaction/UI/ViewPort/Field/.ToDo/TimeRange.pm
+++ b/lib/Reaction/UI/ViewPort/Field/.ToDo/TimeRange.pm
@@ -6,89 +6,88 @@ use DateTime;
use DateTime::SpanSet;
use Time::ParseDate ();
-class TimeRange is 'Reaction::UI::ViewPort::InterfaceModel::Field', which {
-
- has '+value' => (isa => 'DateTime::SpanSet');
-
- #has '+layout' => (default => 'timerange');
-
- has value_string =>
- (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string'));
-
- has delete_label => (
- isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' },
- );
-
- has parent => (
- isa => 'Reaction::UI::ViewPort::TimeRangeCollection',
- is => 'ro',
- required => 1,
- is_weak_ref => 1
- );
-
- implements _build_value_string => as {
- my $self = shift;
- #return '' unless $self->has_value;
- #return $self->value_string;
- };
-
- implements value_array => as {
- my $self = shift;
- return split(',', $self->value_string);
- };
-
- implements adopt_value_string => as {
- my ($self) = @_;
- my @values = $self->value_array;
- for my $idx (0 .. 3) { # last value is repeat
- if (length $values[$idx]) {
- my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1);
- $values[$idx] = DateTime->from_epoch( epoch => $epoch );
- }
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::InterfaceModel::Field';
+
+
+
+has '+value' => (isa => 'DateTime::SpanSet');
+
+#has '+layout' => (default => 'timerange');
+
+has value_string =>
+ (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string'));
+
+has delete_label => (
+ isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' },
+);
+
+has parent => (
+ isa => 'Reaction::UI::ViewPort::TimeRangeCollection',
+ is => 'ro',
+ required => 1,
+ is_weak_ref => 1
+);
+sub _build_value_string {
+ my $self = shift;
+ #return '' unless $self->has_value;
+ #return $self->value_string;
+};
+sub value_array {
+ my $self = shift;
+ return split(',', $self->value_string);
+};
+sub adopt_value_string {
+ my ($self) = @_;
+ my @values = $self->value_array;
+ for my $idx (0 .. 3) { # last value is repeat
+ if (length $values[$idx]) {
+ my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1);
+ $values[$idx] = DateTime->from_epoch( epoch => $epoch );
}
- $self->value($self->range_to_spanset(@values));
- };
-
- implements range_to_spanset => as {
- my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_;
- my $spanset = DateTime::SpanSet->empty_set;
- if (!$pattern || $pattern eq 'none') {
- my $span = DateTime::Span->from_datetimes(
- start => $time_from, end => $time_to
- );
- $spanset = $spanset->union( $span );
- } else {
- my $duration = $time_to - $time_from;
- my %args = ( days => $time_from->day + 2,
- hours => $time_from->hour,
- minutes => $time_from->minute,
- seconds => $time_from->second );
-
- delete $args{'days'} if ($pattern eq 'daily');
- delete @args{qw/hours days/} if ($pattern eq 'hourly');
- $args{'days'} = $time_from->day if ($pattern eq 'monthly');
- my $start_set = DateTime::Event::Recurrence->$pattern( %args );
- my $iter = $start_set->iterator( start => $repeat_from, end => $repeat_to );
- while ( my $dt = $iter->next ) {
- my $endtime = $dt + $duration;
- my $new_span = DateTime::Span->from_datetimes(
- start => $dt,
- end => $endtime
- );
- $spanset = $spanset->union( $new_span );
- }
+ }
+ $self->value($self->range_to_spanset(@values));
+};
+sub range_to_spanset {
+ my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_;
+ my $spanset = DateTime::SpanSet->empty_set;
+ if (!$pattern || $pattern eq 'none') {
+ my $span = DateTime::Span->from_datetimes(
+ start => $time_from, end => $time_to
+ );
+ $spanset = $spanset->union( $span );
+ } else {
+ my $duration = $time_to - $time_from;
+ my %args = ( days => $time_from->day + 2,
+ hours => $time_from->hour,
+ minutes => $time_from->minute,
+ seconds => $time_from->second );
+
+ delete $args{'days'} if ($pattern eq 'daily');
+ delete @args{qw/hours days/} if ($pattern eq 'hourly');
+ $args{'days'} = $time_from->day if ($pattern eq 'monthly');
+ my $start_set = DateTime::Event::Recurrence->$pattern( %args );
+ my $iter = $start_set->iterator( start => $repeat_from, end => $repeat_to );
+ while ( my $dt = $iter->next ) {
+ my $endtime = $dt + $duration;
+ my $new_span = DateTime::Span->from_datetimes(
+ start => $dt,
+ end => $endtime
+ );
+ $spanset = $spanset->union( $new_span );
}
- return $spanset;
- };
+ }
+ return $spanset;
+};
+sub delete {
+ my ($self) = @_;
+ $self->parent->remove_range_vp($self);
+};
- implements delete => as {
- my ($self) = @_;
- $self->parent->remove_range_vp($self);
- };
+override accept_events => sub { ('value_string', 'delete', super()) };
- override accept_events => sub { ('value_string', 'delete', super()) };
+__PACKAGE__->meta->make_immutable;
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Array.pm b/lib/Reaction/UI/ViewPort/Field/Array.pm
index 92a735e..82e01d2 100644
--- a/lib/Reaction/UI/ViewPort/Field/Array.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Array.pm
@@ -4,22 +4,24 @@ use Reaction::Class;
use Scalar::Util 'blessed';
use aliased 'Reaction::UI::ViewPort::Field';
-class Array is Field, which {
- has '+value' => (isa => 'ArrayRef');
+use namespace::clean -except => [ qw(meta) ];
+extends Field;
- has value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
- has value_map_method => (
- isa => 'Str', is => 'ro', required => 1, default => sub { 'display_name' },
- );
- implements _build_value_names => as {
- my $self = shift;
- my $meth = $self->value_map_method;
- my @names = map { blessed($_) ? $_->$meth : $_ } @{ $self->value };
- return [ sort @names ];
- };
+has '+value' => (isa => 'ArrayRef');
- implements _empty_value => as { [] };
+has value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
+has value_map_method => (
+ isa => 'Str', is => 'ro', required => 1, default => sub { 'display_name' },
+);
+sub _build_value_names {
+ my $self = shift;
+ my $meth = $self->value_map_method;
+ my @names = map { blessed($_) ? $_->$meth : $_ } @{ $self->value };
+ return [ sort @names ];
};
+sub _empty_value { [] };
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Boolean.pm b/lib/Reaction/UI/ViewPort/Field/Boolean.pm
index cb6695e..53356ef 100644
--- a/lib/Reaction/UI/ViewPort/Field/Boolean.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Boolean.pm
@@ -3,10 +3,14 @@ package Reaction::UI::ViewPort::Field::Boolean;
use Reaction::Class;
use aliased 'Reaction::UI::ViewPort::Field';
-class Boolean, is Field, which {
- has '+value' => (isa => 'Bool');
+use namespace::clean -except => [ qw(meta) ];
+extends Field;
+
+
+has '+value' => (isa => 'Bool');
+
+override _empty_string_value => sub { 0 };
+__PACKAGE__->meta->make_immutable;
- override _empty_string_value => sub { 0 };
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Collection.pm b/lib/Reaction/UI/ViewPort/Field/Collection.pm
index b772e02..02dfa75 100644
--- a/lib/Reaction/UI/ViewPort/Field/Collection.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Collection.pm
@@ -4,20 +4,23 @@ use Reaction::Class;
use Scalar::Util 'blessed';
use aliased 'Reaction::UI::ViewPort::Field::Array';
-class Collection is Array, which {
+use namespace::clean -except => [ qw(meta) ];
+extends Array;
- has value => (
- is => 'rw', lazy_build => 1,
- isa => 'Reaction::InterfaceModel::Collection'
- );
- implements _build_value_names => as {
- my $self = shift;
- my $meth = $self->value_map_method;
- my @names = map { blessed($_) ? $_->$meth : $_ } $self->value->members;
- return [ sort @names ];
- };
+has value => (
+ is => 'rw', lazy_build => 1,
+ isa => 'Reaction::InterfaceModel::Collection'
+);
+sub _build_value_names {
+ my $self = shift;
+ my $meth = $self->value_map_method;
+ my @names = map { blessed($_) ? $_->$meth : $_ } $self->value->members;
+ return [ sort @names ];
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/DateTime.pm b/lib/Reaction/UI/ViewPort/Field/DateTime.pm
index bb896c7..46fbb60 100644
--- a/lib/Reaction/UI/ViewPort/Field/DateTime.pm
+++ b/lib/Reaction/UI/ViewPort/Field/DateTime.pm
@@ -5,20 +5,24 @@ use Reaction::Class;
use Reaction::Types::DateTime ();
use aliased 'Reaction::UI::ViewPort::Field';
-class DateTime is Field, which {
- has '+value' => (isa => Reaction::Types::DateTime::DateTime());
+use namespace::clean -except => [ qw(meta) ];
+extends Field;
- has value_string_default_format => (
- isa => 'Str', is => 'rw', required => 1, default => sub { "%F %H:%M:%S" }
- );
- around _value_string_from_value => sub {
- my $orig = shift;
- my $self = shift;
- my $format = $self->value_string_default_format;
- return $self->$orig(@_)->strftime($format);
- };
+has '+value' => (isa => Reaction::Types::DateTime::DateTime());
+has value_string_default_format => (
+ isa => 'Str', is => 'rw', required => 1, default => sub { "%F %H:%M:%S" }
+);
+
+around _value_string_from_value => sub {
+ my $orig = shift;
+ my $self = shift;
+ my $format = $self->value_string_default_format;
+ return $self->$orig(@_)->strftime($format);
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/File.pm b/lib/Reaction/UI/ViewPort/Field/File.pm
index dfe4dac..5d731e6 100644
--- a/lib/Reaction/UI/ViewPort/Field/File.pm
+++ b/lib/Reaction/UI/ViewPort/Field/File.pm
@@ -3,25 +3,27 @@ package Reaction::UI::ViewPort::Field::File;
use Reaction::Class;
use Reaction::Types::File;
-class File is 'Reaction::UI::ViewPort::Field', which {
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field';
- has '+value' => (isa => Reaction::Types::File::File());
- has uri => ( is => 'rw', lazy_build => 1);
- has action => (isa => 'CodeRef', is => 'rw', required => 1);
+has '+value' => (isa => Reaction::Types::File::File());
- implements _build_uri => as{
- my $self = shift;
- my $c = $self->ctx;
- my ($c_name, $a_name, @rest) = @{ $self->action->($self->model, $c) };
- $c->uri_for($c->controller($c_name)->action_for($a_name),@rest);
- };
+has uri => ( is => 'rw', lazy_build => 1);
- implements _value_string_from_value => as {
- shift->value->stringify;
- };
-
+has action => (isa => 'CodeRef', is => 'rw', required => 1);
+sub _build_uri {
+ my $self = shift;
+ my $c = $self->ctx;
+ my ($c_name, $a_name, @rest) = @{ $self->action->($self->model, $c) };
+ $c->uri_for($c->controller($c_name)->action_for($a_name),@rest);
};
+sub _value_string_from_value {
+ shift->value->stringify;
+};
+
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Integer.pm b/lib/Reaction/UI/ViewPort/Field/Integer.pm
index d3681cb..7064edb 100644
--- a/lib/Reaction/UI/ViewPort/Field/Integer.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Integer.pm
@@ -3,8 +3,12 @@ package Reaction::UI::ViewPort::Field::Integer;
use Reaction::Class;
use aliased 'Reaction::UI::ViewPort::Field';
-class Integer is Field, which {
- has '+value' => (isa => 'Int');
-};
+use namespace::clean -except => [ qw(meta) ];
+extends Field;
+
+
+has '+value' => (isa => 'Int');
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/Array.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/Array.pm
index 0bf0104..6f5129c 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/Array.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/Array.pm
@@ -2,17 +2,20 @@ package Reaction::UI::ViewPort::Field::Mutable::Array;
use Reaction::Class;
-class Array is 'Reaction::UI::ViewPort::Field::Array', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::Array';
- around value => sub {
- my $orig = shift;
- my $self = shift;
- return $orig->($self) unless @_;
- my $value = defined $_[0] ? $_[0] : [];
- $orig->($self, (ref $value eq 'ARRAY' ? $value : [ $value ]));
- };
+with 'Reaction::UI::ViewPort::Field::Role::Mutable';
+
+around value => sub {
+ my $orig = shift;
+ my $self = shift;
+ return $orig->($self) unless @_;
+ my $value = defined $_[0] ? $_[0] : [];
+ $orig->($self, (ref $value eq 'ARRAY' ? $value : [ $value ]));
};
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/Boolean.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/Boolean.pm
index dfd936e..9063fca 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/Boolean.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/Boolean.pm
@@ -2,19 +2,20 @@ package Reaction::UI::ViewPort::Field::Mutable::Boolean;
use Reaction::Class;
-class Boolean is 'Reaction::UI::ViewPort::Field::Boolean', which{
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::Boolean';
- implements adopt_value_string => as {
- my ($self) = @_;
- $self->value($self->value_string);
- };
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+sub adopt_value_string {
+ my ($self) = @_;
+ $self->value($self->value_string);
+};
+sub BUILD {
+ my($self) = @_;
+ $self->value(0) unless $self->_model_has_value;
+};
- implements BUILD => as {
- my($self) = @_;
- $self->value(0) unless $self->_model_has_value;
- };
+__PACKAGE__->meta->make_immutable;
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm
index b3dca44..0833c73 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm
@@ -7,77 +7,76 @@ my $listify = sub{
return ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]];
};
-class ChooseMany is 'Reaction::UI::ViewPort::Field', which {
-
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
- does 'Reaction::UI::ViewPort::Field::Role::Choices';
-
- #MUST BE HERE, BELOW THE 'does', OR THE TRIGGER WILL NOT HAPPEN!
- has '+value' => (isa => 'ArrayRef');
-
- around value => sub {
- my $orig = shift;
- my $self = shift;
- return $orig->($self) unless @_;
- my $value = $listify->(shift);
- $_ = $self->str_to_ident($_) for @$value;
- my $checked = $self->attribute->check_valid_value($self->model, $value);
- # i.e. fail if any of the values fail
- confess "Not a valid set of values"
- if (@$checked < @$value || grep { !defined($_) } @$checked);
- $orig->($self, $checked);
- };
-
-
- around _value_string_from_value => sub {
- my $orig = shift;
- my $self = shift;
- join(", ", (map {$self->obj_to_name($_->{value}) } @{ $self->current_value_choices }));
- };
-
- implements is_current_value => as {
- my ($self, $check_value) = @_;
- return unless $self->_model_has_value;
- my @our_values = @{$self->value || []};
- $check_value = $self->obj_to_str($check_value) if ref($check_value);
- return grep { $self->obj_to_str($_) eq $check_value } @our_values;
- };
-
- implements current_value_choices => as {
- my $self = shift;
- my @all = grep { $self->is_current_value($_->{value}) } @{$self->value_choices};
- return [ @all ];
- };
-
- implements available_value_choices => as {
- my $self = shift;
- my @all = grep { !$self->is_current_value($_->{value}) } @{$self->value_choices};
- return [ @all ];
- };
-
- around handle_events => sub {
- my $orig = shift;
- my ($self, $events) = @_;
- $events->{value} = [] if $events->{no_current_value};
- my $ev_value = $listify->($events->{value});
- if (delete $events->{add_all_values}) {
- $events->{value} = [map {$self->obj_to_str($_)} @{$self->valid_values}];
- } elsif (exists $events->{add_values} && delete $events->{do_add_values}) {
- my $add = $listify->(delete $events->{add_values});
- $events->{value} = [ @{$ev_value}, @$add ];
- } elsif (delete $events->{remove_all_values}) {
- $events->{value} = [];
- }elsif (exists $events->{remove_values} && delete $events->{do_remove_values}) {
- my $remove = $listify->(delete $events->{remove_values});
- my %r = map { ($_ => 1) } @$remove;
- $events->{value} = [ grep { !$r{$_} } @{$ev_value} ];
- }
-
- return $orig->(@_);
- };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field';
+
+with 'Reaction::UI::ViewPort::Field::Role::Mutable';
+with 'Reaction::UI::ViewPort::Field::Role::Choices';
+
+#MUST BE HERE, BELOW THE 'does', OR THE TRIGGER WILL NOT HAPPEN!
+has '+value' => (isa => 'ArrayRef');
+
+around value => sub {
+ my $orig = shift;
+ my $self = shift;
+ return $orig->($self) unless @_;
+ my $value = $listify->(shift);
+ $_ = $self->str_to_ident($_) for @$value;
+ my $checked = $self->attribute->check_valid_value($self->model, $value);
+ # i.e. fail if any of the values fail
+ confess "Not a valid set of values"
+ if (@$checked < @$value || grep { !defined($_) } @$checked);
+ $orig->($self, $checked);
+};
+
+around _value_string_from_value => sub {
+ my $orig = shift;
+ my $self = shift;
+ join(", ", (map {$self->obj_to_name($_->{value}) } @{ $self->current_value_choices }));
+};
+sub is_current_value {
+ my ($self, $check_value) = @_;
+ return unless $self->_model_has_value;
+ my @our_values = @{$self->value || []};
+ $check_value = $self->obj_to_str($check_value) if ref($check_value);
+ return grep { $self->obj_to_str($_) eq $check_value } @our_values;
+};
+sub current_value_choices {
+ my $self = shift;
+ my @all = grep { $self->is_current_value($_->{value}) } @{$self->value_choices};
+ return [ @all ];
+};
+sub available_value_choices {
+ my $self = shift;
+ my @all = grep { !$self->is_current_value($_->{value}) } @{$self->value_choices};
+ return [ @all ];
};
+around handle_events => sub {
+ my $orig = shift;
+ my ($self, $events) = @_;
+ $events->{value} = [] if $events->{no_current_value};
+ my $ev_value = $listify->($events->{value});
+ if (delete $events->{add_all_values}) {
+ $events->{value} = [map {$self->obj_to_str($_)} @{$self->valid_values}];
+ } elsif (exists $events->{add_values} && delete $events->{do_add_values}) {
+ my $add = $listify->(delete $events->{add_values});
+ $events->{value} = [ @{$ev_value}, @$add ];
+ } elsif (delete $events->{remove_all_values}) {
+ $events->{value} = [];
+ }elsif (exists $events->{remove_values} && delete $events->{do_remove_values}) {
+ my $remove = $listify->(delete $events->{remove_values});
+ my %r = map { ($_ => 1) } @$remove;
+ $events->{value} = [ grep { !$r{$_} } @{$ev_value} ];
+ }
+
+ return $orig->(@_);
+};
+
+__PACKAGE__->meta->make_immutable;
+
+
1;
=head1 NAME
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseOne.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseOne.pm
index f6b679a..dba1a6d 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseOne.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseOne.pm
@@ -3,45 +3,45 @@ package Reaction::UI::ViewPort::Field::Mutable::ChooseOne;
use Reaction::Class;
use Scalar::Util ();
-class ChooseOne is 'Reaction::UI::ViewPort::Field', which {
-
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
- does 'Reaction::UI::ViewPort::Field::Role::Choices';
-
- implements adopt_value_string => as {
- my ($self) = @_;
- my $value = $self->value_string;
- $value = $self->str_to_ident($value) if (!ref $value);
- my $attribute = $self->attribute;
- my $checked = $attribute->check_valid_value($self->model, $value);
- unless (defined $checked) {
- require Data::Dumper;
- my $serialised = Data::Dumper->new([ $value ])->Indent(0)->Dump;
- $serialised =~ s/^\$VAR1 = //; $serialised =~ s/;$//;
- confess "${serialised} is not a valid value for ${\$attribute->name} on "
- ."${\$attribute->associated_class->name}";
- }
- $self->value($checked);
- };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field';
+
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+with 'Reaction::UI::ViewPort::Field::Role::Choices';
+sub adopt_value_string {
+ my ($self) = @_;
+ my $value = $self->value_string;
+ $value = $self->str_to_ident($value) if (!ref $value);
+ my $attribute = $self->attribute;
+ my $checked = $attribute->check_valid_value($self->model, $value);
+ unless (defined $checked) {
+ require Data::Dumper;
+ my $serialised = Data::Dumper->new([ $value ])->Indent(0)->Dump;
+ $serialised =~ s/^\$VAR1 = //; $serialised =~ s/;$//;
+ confess "${serialised} is not a valid value for ${\$attribute->name} on "
+ ."${\$attribute->associated_class->name}";
+ }
+ $self->value($checked);
+};
- around _value_string_from_value => sub {
- my $orig = shift;
- my $self = shift;
- my $value = $self->$orig(@_);
- return $self->obj_to_name($value->{value}) if Scalar::Util::blessed($value);
- return $self->obj_to_name($value) if blessed $value;
- return "$value"; # force stringify. might work. probably won't.
- };
+around _value_string_from_value => sub {
+ my $orig = shift;
+ my $self = shift;
+ my $value = $self->$orig(@_);
+ return $self->obj_to_name($value->{value}) if Scalar::Util::blessed($value);
+ return $self->obj_to_name($value) if blessed $value;
+ return "$value"; # force stringify. might work. probably won't.
+};
+sub is_current_value {
+ my ($self, $check_value) = @_;
+ return unless $self->_model_has_value;
+ my $our_value = $self->value;
+ return unless defined($our_value);
+ $check_value = $self->obj_to_str($check_value) if ref($check_value);
+ return $self->obj_to_str($our_value) eq $check_value;
+};
- implements is_current_value => as {
- my ($self, $check_value) = @_;
- return unless $self->_model_has_value;
- my $our_value = $self->value;
- return unless defined($our_value);
- $check_value = $self->obj_to_str($check_value) if ref($check_value);
- return $self->obj_to_str($our_value) eq $check_value;
- };
+__PACKAGE__->meta->make_immutable;
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/DateTime.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/DateTime.pm
index 654f0d8..27181f5 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/DateTime.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/DateTime.pm
@@ -4,25 +4,25 @@ use Reaction::Class;
use Time::ParseDate;
use DateTime;
-class 'Reaction::UI::ViewPort::Field::Mutable::DateTime',
- is 'Reaction::UI::ViewPort::Field::DateTime', which {
-
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
-
- implements adopt_value_string => as {
- my ($self) = @_;
- my $value = $self->value_string;
- my ($epoch) = Time::ParseDate::parsedate($value);
- if (defined $epoch) {
- my $dt = 'DateTime'->from_epoch( epoch => $epoch );
- $self->value($dt);
- } else {
- $self->value($self->value_string);
- }
- };
-
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::DateTime';
+
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+sub adopt_value_string {
+ my ($self) = @_;
+ my $value = $self->value_string;
+ my ($epoch) = Time::ParseDate::parsedate($value);
+ if (defined $epoch) {
+ my $dt = 'DateTime'->from_epoch( epoch => $epoch );
+ $self->value($dt);
+ } else {
+ $self->value($self->value_string);
+ }
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm
index ffbcbc9..d6d05c2 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm
@@ -3,29 +3,30 @@ package Reaction::UI::ViewPort::Field::Mutable::File;
use Reaction::Types::File qw/Upload/;
use Reaction::Class;
-class File is 'Reaction::UI::ViewPort::Field', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
-
- has '+value' => (isa => Upload);
-
- override apply_our_events => sub {
- my ($self, $ctx, $events) = @_;
- my $value_key = $self->event_id_for('value_string');
- if (my $upload = $ctx->req->upload($value_key)) {
- local $events->{$value_key} = $upload;
- return super();
- } else {
- return super();
- }
- };
-
- implements adopt_value_string => sub {
- my($self) = @_;
- $self->value($self->value_string) if $self->value_string;
- };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field';
+
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+
+has '+value' => (isa => Upload);
+
+override apply_our_events => sub {
+ my ($self, $ctx, $events) = @_;
+ my $value_key = $self->event_id_for('value_string');
+ if (my $upload = $ctx->req->upload($value_key)) {
+ local $events->{$value_key} = $upload;
+ return super();
+ } else {
+ return super();
+ }
+};
+sub adopt_value_string {
+ my($self) = @_;
+ $self->value($self->value_string) if $self->value_string;
+};
+override _value_string_from_value => sub { '' };
- overrides _value_string_from_value => sub { '' };
+__PACKAGE__->meta->make_immutable;
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm
index e55836f..fa75e3c 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm
@@ -2,26 +2,27 @@ package Reaction::UI::ViewPort::Field::Mutable::HiddenArray;
use Reaction::Class;
-class HiddenArray is 'Reaction::UI::ViewPort::Field', which {
-
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
-
- has '+value' => (isa => 'ArrayRef');
-
- around value => sub {
- my $orig = shift;
- my $self = shift;
- if (@_) {
- #this hsould be done with coercions
- $orig->($self, (ref $_[0] eq 'ARRAY' ? $_[0] : [ $_[0] ]));
- $self->sync_to_action;
- } else {
- $orig->($self);
- }
- };
-
- implements _empty_value => as { [] };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field';
+
+with 'Reaction::UI::ViewPort::Field::Role::Mutable';
+
+has '+value' => (isa => 'ArrayRef');
+
+around value => sub {
+ my $orig = shift;
+ my $self = shift;
+ if (@_) {
+ #this hsould be done with coercions
+ $orig->($self, (ref $_[0] eq 'ARRAY' ? $_[0] : [ $_[0] ]));
+ $self->sync_to_action;
+ } else {
+ $orig->($self);
+ }
};
+sub _empty_value { [] };
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/Integer.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/Integer.pm
index 958150a..452e2ab 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/Integer.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/Integer.pm
@@ -2,14 +2,16 @@ package Reaction::UI::ViewPort::Field::Mutable::Integer;
use Reaction::Class;
-class Integer is 'Reaction::UI::ViewPort::Field::Integer', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
-
- implements adopt_value_string => as {
- my ($self) = @_;
- $self->value($self->value_string);
- };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::Integer';
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+sub adopt_value_string {
+ my ($self) = @_;
+ $self->value($self->value_string);
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/MatchingPasswords.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/MatchingPasswords.pm
index 6d9d8aa..0685f87 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/MatchingPasswords.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/MatchingPasswords.pm
@@ -3,38 +3,41 @@ package Reaction::UI::ViewPort::Field::Mutable::MatchingPasswords;
use Reaction::Class;
use aliased 'Reaction::UI::ViewPort::Field::Mutable::Password';
-class MatchingPasswords is Password, which {
-
- has check_value => (is => 'rw', isa => 'Str', );
- has check_label => (is => 'rw', isa => 'Str', lazy_build => 1);
-
- implements _build_check_label => as {
- my $orig_label = shift->label;
- return "Confirm ${orig_label}";
- };
-
- #maybe both check_value and value_string should have triggers ?
- #that way if one even happens before the other it would still work?
- around adopt_value_string => sub {
- my $orig = shift;
- my ($self) = @_;
- return $orig->(@_) if $self->check_value eq $self->value_string;
- $self->message("Passwords do not match");
- return;
- };
-
- #order is important check_value should happen before value here ...
- #i don't like how this works, it's unnecessarily fragile, but how else ?
- around accept_events => sub { ('check_value', shift->(@_)) };
-
- around can_sync_to_action => sub {
- my $orig = shift;
- my ($self) = @_;
- return $orig->(@_) if $self->check_value eq $self->value_string;
- $self->message("Passwords do not match");
- return;
- };
+use namespace::clean -except => [ qw(meta) ];
+extends Password;
+
+
+has check_value => (is => 'rw', isa => 'Str', );
+has check_label => (is => 'rw', isa => 'Str', lazy_build => 1);
+sub _build_check_label {
+ my $orig_label = shift->label;
+ return "Confirm ${orig_label}";
};
+#maybe both check_value and value_string should have triggers ?
+#that way if one even happens before the other it would still work?
+around adopt_value_string => sub {
+ my $orig = shift;
+ my ($self) = @_;
+ return $orig->(@_) if $self->check_value eq $self->value_string;
+ $self->message("Passwords do not match");
+ return;
+};
+
+#order is important check_value should happen before value here ...
+#i don't like how this works, it's unnecessarily fragile, but how else ?
+around accept_events => sub { ('check_value', shift->(@_)) };
+
+around can_sync_to_action => sub {
+ my $orig = shift;
+ my ($self) = @_;
+ return $orig->(@_) if $self->check_value eq $self->value_string;
+ $self->message("Passwords do not match");
+ return;
+};
+
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/Number.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/Number.pm
index d2be595..31416e4 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/Number.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/Number.pm
@@ -2,13 +2,15 @@ package Reaction::UI::ViewPort::Field::Mutable::Number;
use Reaction::Class;
-class Number is 'Reaction::UI::ViewPort::Field::Number', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::Number';
- implements adopt_value_string => as {
- my ($self) = @_;
- $self->value($self->value_string);
- };
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+sub adopt_value_string {
+ my ($self) = @_;
+ $self->value($self->value_string);
};
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/Password.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/Password.pm
index d009698..b89cc76 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/Password.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/Password.pm
@@ -2,14 +2,16 @@ package Reaction::UI::ViewPort::Field::Mutable::Password;
use Reaction::Class;
-class Password is 'Reaction::UI::ViewPort::Field::String', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
-
- implements adopt_value_string => as {
- my ($self) = @_;
- $self->value($self->value_string);
- };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::String';
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+sub adopt_value_string {
+ my ($self) = @_;
+ $self->value($self->value_string);
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/String.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/String.pm
index 11d5d14..ca6d73a 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/String.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/String.pm
@@ -2,14 +2,16 @@ package Reaction::UI::ViewPort::Field::Mutable::String;
use Reaction::Class;
-class String is 'Reaction::UI::ViewPort::Field::String', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
-
- implements adopt_value_string => as {
- my ($self) = @_;
- $self->value($self->value_string);
- };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::String';
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+sub adopt_value_string {
+ my ($self) = @_;
+ $self->value($self->value_string);
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/Text.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/Text.pm
index 09d2127..d4e6935 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/Text.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/Text.pm
@@ -2,14 +2,16 @@ package Reaction::UI::ViewPort::Field::Mutable::Text;
use Reaction::Class;
-class Text is 'Reaction::UI::ViewPort::Field::Text', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
-
- implements adopt_value_string => as {
- my ($self) = @_;
- $self->value($self->value_string);
- };
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::Text';
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+sub adopt_value_string {
+ my ($self) = @_;
+ $self->value($self->value_string);
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Number.pm b/lib/Reaction/UI/ViewPort/Field/Number.pm
index a5725fa..a7ccc55 100644
--- a/lib/Reaction/UI/ViewPort/Field/Number.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Number.pm
@@ -3,8 +3,12 @@ package Reaction::UI::ViewPort::Field::Number;
use Reaction::Class;
use aliased 'Reaction::UI::ViewPort::Field';
-class Number is Field, which {
- has '+value' => (isa => 'Num');
-};
+use namespace::clean -except => [ qw(meta) ];
+extends Field;
+
+
+has '+value' => (isa => 'Num');
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Password.pm b/lib/Reaction/UI/ViewPort/Field/Password.pm
index a80e71a..edb8fd2 100644
--- a/lib/Reaction/UI/ViewPort/Field/Password.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Password.pm
@@ -4,12 +4,16 @@ use Reaction::Class;
use Reaction::Types::Core qw(SimpleStr);
-class Password is 'Reaction::UI::ViewPort::Field::String', which {
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field::String';
- has '+value' => (isa => SimpleStr);
- #has '+layout' => (default => 'password');
-};
+
+has '+value' => (isa => SimpleStr);
+#has '+layout' => (default => 'password');
+
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/RelatedObject.pm b/lib/Reaction/UI/ViewPort/Field/RelatedObject.pm
index 3a3354f..ec5c883 100644
--- a/lib/Reaction/UI/ViewPort/Field/RelatedObject.pm
+++ b/lib/Reaction/UI/ViewPort/Field/RelatedObject.pm
@@ -3,19 +3,23 @@ package Reaction::UI::ViewPort::Field::RelatedObject;
use Reaction::Class;
use Scalar::Util 'blessed';
-class RelatedObject is 'Reaction::UI::ViewPort::Field', which {
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field';
- has value_map_method => (
- isa => 'Str', is => 'ro', required => 1, default => sub { 'display_name' },
- );
- around _value_string_from_value => sub {
- my $orig = shift;
- my $self = shift;
- my $meth = $self->value_map_method;
- return $self->$orig(@_)->$meth;
- };
+has value_map_method => (
+ isa => 'Str', is => 'ro', required => 1, default => sub { 'display_name' },
+);
+
+around _value_string_from_value => sub {
+ my $orig = shift;
+ my $self = shift;
+ my $meth = $self->value_map_method;
+ return $self->$orig(@_)->$meth;
};
+__PACKAGE__->meta->make_immutable;
+
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Role/Choices.pm b/lib/Reaction/UI/ViewPort/Field/Role/Choices.pm
index df8615d..fa329b7 100644
--- a/lib/Reaction/UI/ViewPort/Field/Role/Choices.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Role/Choices.pm
@@ -4,51 +4,47 @@ use Reaction::Role;
use URI;
use Scalar::Util 'blessed';
-role Choices, which {
-
- has valid_values => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
- has value_choices => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
- has value_map_method => (
- isa => 'Str', is => 'ro', required => 1, default => sub { 'display_name' },
- );
-
- implements str_to_ident => as {
- my ($self, $str) = @_;
- my $u = URI->new('','http');
- $u->query($str);
- return ($u->query_keywords ? ($u->query_keywords)[0] : { $u->query_form });
- };
-
- implements obj_to_str => as {
- my ($self, $obj) = @_;
- return $obj unless ref($obj);
- confess "${obj} not an object" unless blessed($obj);
- my $ident = $obj->ident_condition; #XXX DBIC ism that needs to go away
- my $u = URI->new('', 'http');
- $u->query_form(%$ident);
- return $u->query;
- };
-
- implements obj_to_name => as {
- my ($self, $obj) = @_;
- return $obj unless ref($obj);
- confess "${obj} not an object" unless blessed($obj);
- my $meth = $self->value_map_method;
- return $obj->$meth;
- };
-
- implements _build_valid_values => as {
- my $self = shift;
- return [ $self->attribute->all_valid_values($self->model) ];
- };
+use namespace::clean -except => [ qw(meta) ];
+
+
+has valid_values => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
+has value_choices => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
+has value_map_method => (
+ isa => 'Str', is => 'ro', required => 1, default => sub { 'display_name' },
+);
+sub str_to_ident {
+ my ($self, $str) = @_;
+ my $u = URI->new('','http');
+ $u->query($str);
+ return ($u->query_keywords ? ($u->query_keywords)[0] : { $u->query_form });
+};
+sub obj_to_str {
+ my ($self, $obj) = @_;
+ return $obj unless ref($obj);
+ confess "${obj} not an object" unless blessed($obj);
+ my $ident = $obj->ident_condition; #XXX DBIC ism that needs to go away
+ my $u = URI->new('', 'http');
+ $u->query_form(%$ident);
+ return $u->query;
+};
+sub obj_to_name {
+ my ($self, $obj) = @_;
+ return $obj unless ref($obj);
+ confess "${obj} not an object" unless blessed($obj);
+ my $meth = $self->value_map_method;
+ return $obj->$meth;
+};
+sub _build_valid_values {
+ my $self = shift;
+ return [ $self->attribute->all_valid_values($self->model) ];
+};
+sub _build_value_choices {
+ my $self = shift;
+ my @pairs = map{{value => $self->obj_to_str($_), name => $self->obj_to_name($_)}}
+ @{ $self->valid_values };
+ return [ sort { $a->{name} cmp $b->{name} } @pairs ];
+};
- implements _build_value_choices => sub{
- my $self = shift;
- my @pairs = map{{value => $self->obj_to_str($_), name => $self->obj_to_name($_)}}
- @{ $self->valid_values };
- return [ sort { $a->{name} cmp $b->{name} } @pairs ];
- };
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm b/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm
index e2304ef..b73114c 100644
--- a/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm
@@ -5,92 +5,89 @@ use Reaction::Role;
use aliased 'Reaction::InterfaceModel::Action';
use aliased 'Reaction::Meta::InterfaceModel::Action::ParameterAttribute';
-role Mutable, which {
- has model => (is => 'ro', isa => Action, required => 1);
- has attribute => (is => 'ro', isa => ParameterAttribute, required => 1);
-
- has value => (
- is => 'rw', lazy_build => 1, trigger_adopt('value'),
- clearer => 'clear_value',
- );
- has needs_sync => (is => 'rw', isa => 'Int', default => 0);
- #predicates are autmagically generated for lazy and non-required attrs
- has message => (is => 'rw', isa => 'Str', clearer => 'clear_message');
-
- after clear_value => sub {
- my $self = shift;
- $self->clear_message if $self->has_message;
- $self->needs_sync(1);
- };
-
- implements adopt_value => as {
- my ($self) = @_;
- $self->clear_message if $self->has_message;
- $self->needs_sync(1); # if $self->has_attribute;
- };
-
- implements can_sync_to_action => as {
- my $self = shift;
- return 1 unless $self->needs_sync;
- my $attr = $self->attribute;
-
- if ($self->has_value) {
- my $value = $self->value;
- if (my $tc = $attr->type_constraint) {
- $value = $tc->coercion->coerce($value) if ($tc->has_coercion);
- if (defined (my $error = $tc->validate($value))) {
- $self->message($error);
- return;
- }
+use namespace::clean -except => [ qw(meta) ];
+
+has model => (is => 'ro', isa => Action, required => 1);
+has attribute => (is => 'ro', isa => ParameterAttribute, required => 1);
+
+has value => (
+ is => 'rw', lazy_build => 1, trigger_adopt('value'),
+ clearer => 'clear_value',
+);
+has needs_sync => (is => 'rw', isa => 'Int', default => 0);
+#predicates are autmagically generated for lazy and non-required attrs
+has message => (is => 'rw', isa => 'Str', clearer => 'clear_message');
+
+after clear_value => sub {
+ my $self = shift;
+ $self->clear_message if $self->has_message;
+ $self->needs_sync(1);
+};
+sub adopt_value {
+ my ($self) = @_;
+ $self->clear_message if $self->has_message;
+ $self->needs_sync(1); # if $self->has_attribute;
+};
+sub can_sync_to_action {
+ my $self = shift;
+ return 1 unless $self->needs_sync;
+ my $attr = $self->attribute;
+
+ if ($self->has_value) {
+ my $value = $self->value;
+ if (my $tc = $attr->type_constraint) {
+ $value = $tc->coercion->coerce($value) if ($tc->has_coercion);
+ if (defined (my $error = $tc->validate($value))) {
+ $self->message($error);
+ return;
}
- } else {
- return if $attr->is_required;
}
- return 1;
- };
-
- implements sync_to_action => as {
- my ($self) = @_;
- return unless $self->needs_sync;
- return unless $self->can_sync_to_action;
-
- my $attr = $self->attribute;
-
- if ($self->has_value) {
- my $value = $self->value;
- if (my $tc = $attr->type_constraint) {
- #this will go away when we have moose dbic. until then though...
- $value = $tc->coercion->coerce($value) if ($tc->has_coercion);
- }
- my $writer = $attr->get_write_method;
- confess "No writer for attribute" unless defined($writer);
- $self->model->$writer($value);
- } else {
- my $predicate = $attr->get_predicate_method;
- confess "No predicate for attribute" unless defined($predicate);
- if ($self->model->$predicate) {
- my $clearer = $attr->get_clearer_method;
- confess "${predicate} returned true but no clearer for attribute"
- unless defined($clearer);
- $self->model->$clearer;
- }
+ } else {
+ return if $attr->is_required;
+ }
+ return 1;
+};
+sub sync_to_action {
+ my ($self) = @_;
+ return unless $self->needs_sync;
+ return unless $self->can_sync_to_action;
+
+ my $attr = $self->attribute;
+
+ if ($self->has_value) {
+ my $value = $self->value;
+ if (my $tc = $attr->type_constraint) {
+ #this will go away when we have moose dbic. until then though...
+ $value = $tc->coercion->coerce($value) if ($tc->has_coercion);
}
- $self->needs_sync(0);
- };
-
- implements sync_from_action => as {
- my ($self) = @_;
- return unless !$self->needs_sync; # && $self->has_attribute;
- if( !$self->has_message ){
- if(my $error = $self->model->error_for($self->attribute) ){
- $self->message( $error );
- }
+ my $writer = $attr->get_write_method;
+ confess "No writer for attribute" unless defined($writer);
+ $self->model->$writer($value);
+ } else {
+ my $predicate = $attr->get_predicate_method;
+ confess "No predicate for attribute" unless defined($predicate);
+ if ($self->model->$predicate) {
+ my $clearer = $attr->get_clearer_method;
+ confess "${predicate} returned true but no clearer for attribute"
+ unless defined($clearer);
+ $self->model->$clearer;
+ }
+ }
+ $self->needs_sync(0);
+};
+sub sync_from_action {
+ my ($self) = @_;
+ return unless !$self->needs_sync; # && $self->has_attribute;
+ if( !$self->has_message ){
+ if(my $error = $self->model->error_for($self->attribute) ){
+ $self->message( $error );
}
- };
+ }
+};
+
+around accept_events => sub { ('value', shift->(@_)) };
- around accept_events => sub { ('value', shift->(@_)) };
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm b/lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm
index 4244b31..e41f264 100644
--- a/lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm
@@ -4,35 +4,34 @@ use Reaction::Role;
use aliased 'Reaction::UI::ViewPort::Field::Role::Mutable';
-role Simple which {
-
- does Mutable;
-
- has value_string => (
- is => 'rw', lazy_build => 1, trigger_adopt('value_string'),
- clearer => 'clear_value',
- );
+use namespace::clean -except => [ qw(meta) ];
+with Mutable;
+
+has value_string => (
+ is => 'rw', lazy_build => 1, trigger_adopt('value_string'),
+ clearer => 'clear_value',
+);
+
+around value_string => sub {
+ my $orig = shift;
+ my $self = shift;
+ if (@_ && defined($_[0]) && !ref($_[0]) && $_[0] eq ''
+ && !$self->value_is_required) {
+ $self->clear_value;
+ return undef;
+ }
+ return $self->$orig(@_);
+};
- around value_string => sub {
- my $orig = shift;
- my $self = shift;
- if (@_ && defined($_[0]) && !ref($_[0]) && $_[0] eq ''
- && !$self->value_is_required) {
- $self->clear_value;
- return undef;
- }
- return $self->$orig(@_);
- };
+# the user needs to implement this because, honestly, you're always going
+# to need to do something custom and the only common thing really is
+# "you probably set $self->value at the end"
+requires 'adopt_value_string';
- # the user needs to implement this because, honestly, you're always going
- # to need to do something custom and the only common thing really is
- # "you probably set $self->value at the end"
- requires 'adopt_value_string';
+around accept_events => sub { ('value_string', shift->(@_)) };
- around accept_events => sub { ('value_string', shift->(@_)) };
+around force_events => sub { (value_string => '', shift->(@_)) };
- around force_events => sub { (value_string => '', shift->(@_)) };
-};
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/String.pm b/lib/Reaction/UI/ViewPort/Field/String.pm
index 9935ae5..ec7e295 100644
--- a/lib/Reaction/UI/ViewPort/Field/String.pm
+++ b/lib/Reaction/UI/ViewPort/Field/String.pm
@@ -3,8 +3,12 @@ package Reaction::UI::ViewPort::Field::String;
use Reaction::Class;
use aliased 'Reaction::UI::ViewPort::Field';
-class String is Field, which {
- has '+value' => (isa => 'Str');
-};
+use namespace::clean -except => [ qw(meta) ];
+extends Field;
+
+
+has '+value' => (isa => 'Str');
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/Text.pm b/lib/Reaction/UI/ViewPort/Field/Text.pm
index 3d19047..b0c90da 100644
--- a/lib/Reaction/UI/ViewPort/Field/Text.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Text.pm
@@ -3,8 +3,12 @@ package Reaction::UI::ViewPort::Field::Text;
use Reaction::Class;
use aliased 'Reaction::UI::ViewPort::Field';
-class Text is Field, which {
- has '+value' => (isa => 'Str');
-};
+use namespace::clean -except => [ qw(meta) ];
+extends Field;
+
+
+has '+value' => (isa => 'Str');
+__PACKAGE__->meta->make_immutable;
+
1;
diff --git a/lib/Reaction/UI/ViewPort/Field/TimeRange.pm b/lib/Reaction/UI/ViewPort/Field/TimeRange.pm
index ccf6e65..f227203 100644
--- a/lib/Reaction/UI/ViewPort/Field/TimeRange.pm
+++ b/lib/Reaction/UI/ViewPort/Field/TimeRange.pm
@@ -6,89 +6,88 @@ use DateTime;
use DateTime::SpanSet;
use Time::ParseDate ();
-class TimeRange is 'Reaction::UI::ViewPort::Field', which {
-
- has '+value' => (isa => SpanSet);
-
- #has '+layout' => (default => 'timerange');
-
- has value_string =>
- (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string'));
-
- has delete_label => (
- isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' },
- );
-
- has parent => (
- isa => 'Reaction::UI::ViewPort::TimeRangeCollection',
- is => 'ro',
- required => 1,
- is_weak_ref => 1
- );
-
- implements _build_value_string => as {
- my $self = shift;
- #return '' unless $self->has_value;
- #return $self->value_string;
- };
-
- implements value_array => as {
- my $self = shift;
- return split(',', $self->value_string);
- };
-
- implements adopt_value_string => as {
- my ($self) = @_;
- my @values = $self->value_array;
- for my $idx (0 .. 3) { # last value is repeat
- if (length $values[$idx]) {
- my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1);
- $values[$idx] = DateTime->from_epoch( epoch => $epoch );
- }
+use namespace::clean -except => [ qw(meta) ];
+extends 'Reaction::UI::ViewPort::Field';
+
+
+
+has '+value' => (isa => SpanSet);
+
+#has '+layout' => (default => 'timerange');
+
+has value_string =>
+ (isa => 'Str', is => 'rw', lazy_fail => 1, trigger_adopt('value_string'));
+
+has delete_label => (
+ isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' },
+);
+
+has parent => (
+ isa => 'Reaction::UI::ViewPort::TimeRangeCollection',
+ is => 'ro',
+ required => 1,
+ is_weak_ref => 1
+);
+sub _build_value_string {
+ my $self = shift;
+ #return '' unless $self->has_value;
+ #return $self->value_string;
+};
+sub value_array {
+ my $self = shift;
+ return split(',', $self->value_string);
+};
+sub adopt_value_string {
+ my ($self) = @_;
+ my @values = $self->value_array;
+ for my $idx (0 .. 3) { # last value is repeat
+ if (length $values[$idx]) {
+ my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1);
+ $values[$idx] = DateTime->from_epoch( epoch => $epoch );
}
- $self->value($self->range_to_spanset(@values));
- };
-
- implements range_to_spanset => as {
- my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_;
- my $spanset = DateTime::SpanSet->empty_set;
- if (!$pattern || $pattern eq 'none') {
- my $span = DateTime::Span->from_datetimes(
- start => $time_from, end => $time_to
- );
- $spanset = $spanset->union( $span );
- } else {
- my $duration = $time_to - $time_from;
- my %args = ( days => $time_from->day + 2,
- hours => $time_from->hour,
- minutes => $time_from->minute,
- seconds => $time_from->second );
-
- delete $args{'days'} if ($pattern eq 'daily');
- delete @args{qw/hours days/} if ($pattern eq 'hourly');
- $args{'days'} = $time_from->day if ($pattern eq 'monthly');
- my $start_set = DateTime::Event::Recurrence->$pattern( %args );
- my $iter = $start_set->iterator( start => $repeat_from, end => $repeat_to );
- while ( my $dt = $iter->next ) {
- my $endtime = $dt + $duration;
- my $new_span = DateTime::Span->from_datetimes(
- start => $dt,
- end => $endtime
- );
- $spanset = $spanset->union( $new_span );
- }
+ }
+ $self->value($self->range_to_spanset(@values));
+};
+sub range_to_spanset {
+ my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_;
+ my $spanset = DateTime::SpanSet->empty_set;
+ if (!$pattern || $pattern eq 'none') {
+ my $span = DateTime::Span->from_datetimes(
+ start => $time_from, end => $time_to
+ );
+ $spanset = $spanset->union( $span );
+ } else {
+ my $duration = $time_to - $time_from;
+ my %args = ( days => $time_from->day + 2,
+ hours => $time_from->hour,
+ minutes => $time_from->minute,
+ seconds => $time_from->second );
+
+ delete $args{'days'} if ($pattern eq 'daily');
+ delete @args{qw/hours days/} if ($pattern eq 'hourly');
+ $args{'days'} = $time_from->day if ($pattern eq 'monthly');
+ my $start_set = DateTime::Event::Recurrence->$pattern( %args );
+ my $iter = $start_set->iterator( start => $repeat_from, end => $repeat_to );
+ while ( my $dt = $iter->next ) {
+ my $endtime = $dt + $duration;
+ my $new_span = DateTime::Span->from_datetimes(
+ start => $dt,
+ end => $endtime
+ );
+ $spanset = $spanset->union( $new_span );
}
- return $spanset;
- };
+ }
+ return $spanset;
+};
+sub delete {
+ my ($self) = @_;
+ $self->parent->remove_range_vp($self);
+};
- implements delete => as {
- my ($self) = @_;
- $self->parent->remove_range_vp($self);
- };
+override accept_events => sub { ('value_string', 'delete', super()) };
- override accept_events => sub { ('value_string', 'delete', super()) };
+__PACKAGE__->meta->make_immutable;
-};
1;