use Reaction::Class;
class Boolean is 'Reaction::UI::ViewPort::Field::Boolean', which{
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+
+ implements adopt_value_string => as {
+ my ($self) = @_;
+ $self->value($self->value_string);
+ };
implements BUILD => as {
my($self) = @_;
class ChooseOne is 'Reaction::UI::ViewPort::Field', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
does 'Reaction::UI::ViewPort::Field::Role::Choices';
- around value => sub {
- my $orig = shift;
- my $self = shift;
- return $orig->($self) unless @_;
- my $value = shift;
- if (defined $value) {
- $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}";
- }
- $value = $checked;
+ 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}";
}
- $orig->($self, $value);
+ $self->value($checked);
};
around _value_string_from_value => sub {
return $self->obj_to_str($our_value) eq $check_value;
};
-
};
1;
class 'Reaction::UI::ViewPort::Field::Mutable::DateTime',
is 'Reaction::UI::ViewPort::Field::DateTime', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
-
- has value_string =>
- ( is => 'rw', isa => 'Str', lazy_build => 1, trigger_adopt('value_string') );
-
- 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(@_);
- };
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
implements adopt_value_string => as {
my ($self) = @_;
}
};
- around accept_events => sub { ('value_string', shift->(@_)) };
-
};
1;
use Reaction::Class;
class Integer is 'Reaction::UI::ViewPort::Field::Integer', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+
+ implements adopt_value_string => as {
+ my ($self) = @_;
+ $self->value($self->value_string);
+ };
+
};
1;
use Reaction::Class;
class Number is 'Reaction::UI::ViewPort::Field::Number', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+
+ implements adopt_value_string => as {
+ my ($self) = @_;
+ $self->value($self->value_string);
+ };
};
1;
use Reaction::Class;
class Password is 'Reaction::UI::ViewPort::Field::String', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+
+ implements adopt_value_string => as {
+ my ($self) = @_;
+ $self->value($self->value_string);
+ };
+
};
1;
use Reaction::Class;
class String is 'Reaction::UI::ViewPort::Field::String', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+
+ implements adopt_value_string => as {
+ my ($self) = @_;
+ $self->value($self->value_string);
+ };
+
};
1;
use Reaction::Class;
class Text is 'Reaction::UI::ViewPort::Field::Text', which {
- does 'Reaction::UI::ViewPort::Field::Role::Mutable';
+ does 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
+
+ implements adopt_value_string => as {
+ my ($self) = @_;
+ $self->value($self->value_string);
+ };
+
};
1;
clearer => 'clear_value',
);
has needs_sync => (is => 'rw', isa => 'Int', default => 0);
- has message => (is => 'rw', isa => 'Str');
+ has message => (is => 'rw', isa => 'Str');
after clear_value => sub {
shift->needs_sync(1);
--- /dev/null
+package Reaction::UI::ViewPort::Field::Role::Mutable::Simple;
+
+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',
+ );
+
+ 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';
+
+ around accept_events => sub { ('value_string', shift->(@_)) };
+
+};
+
+1;
class Mutable is 'Reaction::UI::Widget::Field', which {
before fragment widget {
- arg 'field_id' => event_id 'value';
- arg 'field_name' => event_id 'value' unless defined $_{field_name};
+ arg 'field_id' => event_id 'value_string';
+ arg 'field_name' => event_id 'value_string' unless defined $_{field_name};
arg 'field_type' => 'text';
};
implements fragment current_values {
my $current_choices = $_{viewport}->current_value_choices;
if( @$current_choices ){
+ arg field_name => event_id 'value';
render hidden_value => over $current_choices;
} else {
arg field_name => event_id 'no_current_value';