test_requires 'Test::Class' => '0.31';
test_requires 'Test::WWW::Mechanize::Catalyst' => '0.51';
test_requires 'Test::Memory::Cycle' => '1.04';
-test_requires 'SQL::Translator' => '0.09004';
+test_requires 'SQL::Translator' => '0.11002';
install_share;
use base 'Reaction::UI::Controller::Collection::CRUD';
use Reaction::Class;
+use aliased 'Reaction::UI::ViewPort::SearchableListViewContainer';
+use aliased 'ComponentUI::TestModel::Foo::SearchSpec';
+use aliased 'ComponentUI::TestModel::Foo::Action::SearchSpec::Update';
+
__PACKAGE__->config(
model_name => 'TestModel',
collection_name => 'Foo',
);
}
-# sub _build_action_viewport_args {
-# my $self = shift;
-# my $args = $self->next::method(@_);
-# # $args->{list}{action_prototypes}{delete_all}{label} = 'Delete All Records';
-# return $args;
-# }
+override _build_action_viewport_map => sub {
+ my $map = super();
+ $map->{list} = SearchableListViewContainer;
+ return $map;
+};
+
+override _build_action_viewport_args => sub {
+ my $args = super();
+ $args->{list}{spec_class} = SearchSpec;
+ $args->{list}{action_class} = Update;
+ return $args;
+};
1;
+
+__END__;
--- /dev/null
+package ComponentUI::TestModel::Foo::Action::SearchSpec::Update;
+use Reaction::Class;
+use namespace::autoclean;
+
+use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+
+extends 'Reaction::InterfaceModel::Action';
+with 'Reaction::InterfaceModel::Search::UpdateSpec';
+
+has 'first_name' => (isa => NonEmptySimpleStr, is => 'rw', required => 0);
+has 'last_name' => (isa => NonEmptySimpleStr, is => 'rw', required => 0);
+
+sub _reflection_info {{ normal => [qw/first_name last_name/] }}
+
+1;
--- /dev/null
+package ComponentUI::TestModel::Foo::SearchSpec;
+use Reaction::Class;
+use namespace::autoclean;
+
+use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+
+with 'Reaction::InterfaceModel::Search::Spec';
+
+has 'first_name' => (isa => NonEmptySimpleStr, is => 'rw', required => 0);
+has 'last_name' => (isa => NonEmptySimpleStr, is => 'rw', required => 0);
+
+sub _build__search_spec {
+ my($self) = @_;
+ my %search;
+ $search{first_name} = $self->first_name if $self->has_first_name;
+ $search{last_name} = $self->last_name if $self->has_last_name;
+ return [\%search];
+}
+
+# no special packing/unpacking required for Foo
+sub _to_string_pack_value { $_[1] }
+sub _from_string_unpack_value { $_[1] }
+
+1;
sub next_import_package { 'Moose' }
+__PACKAGE__->meta->make_immutable;
+
1;
#---------#---------#---------#---------#---------#---------#---------#--------#
extends 'Moose::Object';
+__PACKAGE__->meta->make_immutable;
+
no Moose;
1;
sub build_per_context_instance {
my ($self, $c, @args) = @_;
- my $newself = $self->new($self->_application, {%$self, context => $c, @args});
+ my $class = ref($self) || $self;
+ my $newself = $class->new($self->_application, {%$self, context => $c, @args});
return $newself;
}
};
sub _load_skin_config {
my ($self, $args) = @_;
+ my $class = ref($self) || $self;
my $base = $self->skin_dir;
my $lst = sub { (ref $_[0] eq 'ARRAY') ? $_[0] : [$_[0]] };
my @files = (
})}
);
if (my $super_name = $cfg{extends}) {
- my $super = $self->new(
+ my $super = $class->new(
name => $super_name,
view => $self->view,
skin_base_dir => $args->{skin_base_dir},
with 'Reaction::UI::ViewPort::Collection::Role::UseSearchSpec';
with 'Reaction::UI::ViewPort::Collection::Role::Order';
-with 'Reaction::UI::ViewPort::Collection::Role::Pager';
-with 'Reaction::UI::ViewPort::Role::Actions';
__PACKAGE__->meta->make_immutable;
my $uri = $proto->{uri} or confess('uri is required in prototype action');
my $label = exists $proto->{label} ? $proto->{label} : $proto_name;
my $layout = exists $proto->{layout} ? $proto->{layout} : 'uri';
+ my $layout_args = exists $proto->{layout_args} ? $proto->{layout_args} : {};
my $action = Reaction::UI::ViewPort::URI->new(
location => join ('-', $loc, 'action', $i++),
uri => ( ref($uri) eq 'CODE' ? $uri->($target, $ctx) : $uri ),
display => ( ref($label) eq 'CODE' ? $label->($target, $ctx) : $label ),
layout => ( ref($layout) eq 'CODE' ? $layout->($target, $ctx) : $layout ),
+ layout_args => ( ref($layout_args) eq 'CODE' ? $layout_args->($target, $ctx) : $layout_args ),
);
push(@act, $action);
}
};
override child_event_sinks => method () {
- ((map $self->$_, 'listview', 'search_form'), super);
+ ((map $self->$_, 'search_form', 'listview'), super);
};
1;
=for layout widget
-<div class="action_form">
- <form action="[% action %]" id="[% form_id %]" method="[% method %]" enctype="multipart/form-data">
- [% header %]
- [% container_list %]
- [% buttons %]
- [% footer %]
- </form>
-</div>
+<form action="[% action %]" id="[% form_id %]" method="[% method %]" enctype="multipart/form-data">
+ [% header %]
+ [% container_list %]
+ [% buttons %]
+ [% footer %]
+</form>
=for layout header
=for layout body
-<div class="collection_members">
- [% members %]
-</div>
+[% members %]
=for layout footer
=for layout list
-<div class="array_list">
<ul>
-[% content %]
+ [% content %]
</ul>
-</div>
=for layout item
=for layout list
-<div class="collection_list">
<ul>
-[% call_next %]
+ [% call_next %]
</ul>
-</div>
=for layout item
=for layout field
-<div class="field_container_field">
- [% call_next %]
-</div>
+[% call_next %]
=cut
=for layout widget
-<div class="[% field_class %]">[% label_fragment %] [% field %] [% message_fragment %]</div>
+[% label_fragment %] [% field %] [% message_fragment %]
=for layout label
=for layout field
-<div class="choose_many_field">
<table>
<tr>
<td> [% available_values %] </td>
</td>
</tr>
</table>
-</div>
=for layout available_values
=for layout action_buttons
-<div class="choose_many_buttons">
- <input type="submit" value=">>" name="[% event_id_add_all_values %]" />
- <input type="submit" value=">" name="[% event_id_do_add_values %]" />
- <input type="submit" value="<" name="[% event_id_do_remove_values %]" />
- <input type="submit" value="<<" name="[% event_id_remove_all_values %]" />
-</div>
+<input type="submit" value=">>" name="[% event_id_add_all_values %]" />
+<input type="submit" value=">" name="[% event_id_do_add_values %]" />
+<input type="submit" value="<" name="[% event_id_do_remove_values %]" />
+<input type="submit" value="<<" name="[% event_id_remove_all_values %]" />
=for layout message
=extends NEXT
+=for layout widget
+
+<div class="action_form">
+ [% call_next %]
+</div>
+
=for layout container
[% call_next %] <br />
<span class="field_array_label"><strong > [% content | html %]: </strong></span>
+=for layout list
+
+<div class="array_list">
+ [% call_next %]
+</div>
+
=cut
<span class="field_collection_label_box"><strong> [% label %]: </strong></span>
+=for layout list
+
+<div class="collection_list">
+ [% call_next %]
+</div>
+
=cut
=extends NEXT
+=for layout widget
+
+<div class="[% field_class %]">[% call_next %]</div>
+
=for layout message
[% call_next %]<br />
[% message_fragment %]
[% field %]
+=for layout field
+
+<div class="choose_many_field">
+ [% call_next %]
+</div>
+
=for layout action_buttons
<div class="choose_many_buttons">
-<input type="submit" value=">>" name="[% event_id_add_all_values %]" /> <br />
-<input type="submit" value=">" name="[% event_id_do_add_values %]" /> <br />
-<input type="submit" value="<" name="[% event_id_do_remove_values %]" /> <br />
-<input type="submit" value="<<" name="[% event_id_remove_all_values %]" /> <br />
+ [% call_next %]
</div>
=cut