aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.PL3
-rw-r--r--lib/ComponentUI/Controller/TestModel/Foo.pm24
-rw-r--r--lib/ComponentUI/TestModel/Foo/Action/SearchSpec/Update.pm15
-rw-r--r--lib/ComponentUI/TestModel/Foo/SearchSpec.pm24
-rw-r--r--lib/Reaction/Class.pm2
-rw-r--r--lib/Reaction/InterfaceModel/Reflector/DBIC.pm2
-rw-r--r--lib/Reaction/Object.pm2
-rw-r--r--lib/Reaction/UI/Controller.pm11
-rw-r--r--lib/Reaction/UI/Skin.pm3
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm4
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/File.pm5
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm4
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm29
-rw-r--r--lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm17
-rw-r--r--lib/Reaction/UI/ViewPort/ListViewWithSearch.pm2
-rw-r--r--lib/Reaction/UI/ViewPort/Role/Actions.pm2
-rw-r--r--lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm2
-rw-r--r--lib/Reaction/UI/Widget/Field/Mutable/HiddenArray.pm4
-rw-r--r--share/skin/base/layout/action.tt14
-rw-r--r--share/skin/base/layout/collection.tt4
-rw-r--r--share/skin/base/layout/field/array.tt4
-rw-r--r--share/skin/base/layout/field/collection.tt4
-rw-r--r--share/skin/base/layout/field/container.tt4
-rw-r--r--share/skin/base/layout/field/mutable.tt5
-rw-r--r--share/skin/base/layout/field/mutable/choose_many.tt12
-rw-r--r--share/skin/base/layout/field/mutable/choose_one.tt3
-rw-r--r--share/skin/default/layout/action.tt6
-rw-r--r--share/skin/default/layout/field/array.tt6
-rw-r--r--share/skin/default/layout/field/collection.tt6
-rw-r--r--share/skin/default/layout/field/mutable.tt4
-rw-r--r--share/skin/default/layout/field/mutable/choose_many.tt11
31 files changed, 168 insertions, 70 deletions
diff --git a/Makefile.PL b/Makefile.PL
index 705461c..da2cb84 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -46,11 +46,12 @@ requires 'namespace::clean' => '0.11';
requires 'metaclass' => '0.81';
requires 'Method::Signatures::Simple' => '0.03';
requires 'signatures' => '0.05';
+requires 'MooseX::Role::Parameterized' => '0.13';
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;
diff --git a/lib/ComponentUI/Controller/TestModel/Foo.pm b/lib/ComponentUI/Controller/TestModel/Foo.pm
index 2fb994c..d636c6c 100644
--- a/lib/ComponentUI/Controller/TestModel/Foo.pm
+++ b/lib/ComponentUI/Controller/TestModel/Foo.pm
@@ -3,6 +3,10 @@ package ComponentUI::Controller::TestModel::Foo;
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',
@@ -49,11 +53,19 @@ for my $action (qw/view create update/){
);
}
-# 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;
+ $map;
+};
+
+sub _build_action_viewport_args {
+ my $self = shift;
+ my $args = $self->next::method(@_);
+ $args->{list}{action_prototypes}{delete_all}{label} = 'Delete All Records';
+ $args->{list}{spec_class} = SearchSpec;
+ $args->{list}{action_class} = Update;
+ return $args;
+}
1;
diff --git a/lib/ComponentUI/TestModel/Foo/Action/SearchSpec/Update.pm b/lib/ComponentUI/TestModel/Foo/Action/SearchSpec/Update.pm
new file mode 100644
index 0000000..97d2feb
--- /dev/null
+++ b/lib/ComponentUI/TestModel/Foo/Action/SearchSpec/Update.pm
@@ -0,0 +1,15 @@
+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;
diff --git a/lib/ComponentUI/TestModel/Foo/SearchSpec.pm b/lib/ComponentUI/TestModel/Foo/SearchSpec.pm
new file mode 100644
index 0000000..4664ec6
--- /dev/null
+++ b/lib/ComponentUI/TestModel/Foo/SearchSpec.pm
@@ -0,0 +1,24 @@
+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;
diff --git a/lib/Reaction/Class.pm b/lib/Reaction/Class.pm
index a57dcdf..9f61bbf 100644
--- a/lib/Reaction/Class.pm
+++ b/lib/Reaction/Class.pm
@@ -233,6 +233,8 @@ sub next_import {
sub next_import_package { 'Moose' }
+__PACKAGE__->meta->make_immutable;
+
1;
#---------#---------#---------#---------#---------#---------#---------#--------#
diff --git a/lib/Reaction/InterfaceModel/Reflector/DBIC.pm b/lib/Reaction/InterfaceModel/Reflector/DBIC.pm
index 38d9025..96bc262 100644
--- a/lib/Reaction/InterfaceModel/Reflector/DBIC.pm
+++ b/lib/Reaction/InterfaceModel/Reflector/DBIC.pm
@@ -153,7 +153,7 @@ sub reflect_schema {
superclasses => [$base],
( @$roles ? (roles => $roles) : ()),
);
-
+
# sources => undef, #default to qr/./
# sources => [], #default to nothing
# sources => qr//, #DWIM, treated as [qr//]
diff --git a/lib/Reaction/Object.pm b/lib/Reaction/Object.pm
index 7440bd3..de4c740 100644
--- a/lib/Reaction/Object.pm
+++ b/lib/Reaction/Object.pm
@@ -7,6 +7,8 @@ use Moose qw(extends);
extends 'Moose::Object';
+__PACKAGE__->meta->make_immutable;
+
no Moose;
1;
diff --git a/lib/Reaction/UI/Controller.pm b/lib/Reaction/UI/Controller.pm
index 8ed781f..f428941 100644
--- a/lib/Reaction/UI/Controller.pm
+++ b/lib/Reaction/UI/Controller.pm
@@ -11,7 +11,8 @@ with 'Catalyst::Component::InstancePerContext';
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;
}
@@ -135,7 +136,7 @@ controller configuration. For example to override the default number
of items in a CRUD list action:
__PACKAGE__->config(
- action => {
+ action => {
list => { ViewPort => { per_page => 50 } },
}
);
@@ -159,7 +160,7 @@ TODO: explain how next_action as a scalar gets converted to the redirect arrayre
=head2 pop_viewport_to $vp
Call L<Reaction::UI::FocusStack/pop_viewport> or
-L<Reaction::UI::FocusStack/pop_viewport_to> on
+L<Reaction::UI::FocusStack/pop_viewport_to> on
the C<< $c->stash->{focus_stack} >>.
=head2 redirect_to $c, $to, $captures, $args, $attrs
@@ -185,7 +186,7 @@ $args if not supplied.
=head2 make_context_closure
The purpose of this method is to prevent memory leaks.
-It weakens the context object, often denoted $c, and passes it as the
+It weakens the context object, often denoted $c, and passes it as the
first argument to the sub{} that is passed to the make_context_closure method.
In other words,
@@ -198,7 +199,7 @@ make_context_closure returns sub { $sub_you_gave_it->($weak_c, @_)
To further expound up this useful construct consider code written before
make_context_closure was created:
- on_apply_callback =>
+ on_apply_callback =>
sub {
$self->after_search( $c, @_ );
}
diff --git a/lib/Reaction/UI/Skin.pm b/lib/Reaction/UI/Skin.pm
index 237279d..0683258 100644
--- a/lib/Reaction/UI/Skin.pm
+++ b/lib/Reaction/UI/Skin.pm
@@ -71,6 +71,7 @@ sub _find_skin_dir {
};
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 = (
@@ -84,7 +85,7 @@ sub _load_skin_config {
})}
);
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},
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm
index 1b7a411..227ad33 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/ChooseMany.pm
@@ -11,11 +11,11 @@ use namespace::clean -except => [ qw(meta) ];
use MooseX::Types::Moose qw/ArrayRef/;
extends 'Reaction::UI::ViewPort::Field';
-with 'Reaction::UI::ViewPort::Field::Role::Mutable';
+with 'Reaction::UI::ViewPort::Field::Role::Mutable' => { value_type => 'ArrayRef' };
with 'Reaction::UI::ViewPort::Field::Role::Choices';
#MUST BE HERE, BELOW THE 'does', OR THE TRIGGER WILL NOT HAPPEN!
-has '+value' => (isa => ArrayRef);
+#has '+value' => (isa => ArrayRef);
around value => sub {
my $orig = shift;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm
index 4318eee..5c1b35d 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/File.pm
@@ -6,9 +6,8 @@ use Reaction::Class;
use namespace::clean -except => [ qw(meta) ];
extends 'Reaction::UI::ViewPort::Field';
-with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple';
-
-has '+value' => (isa => Upload);
+with 'Reaction::UI::ViewPort::Field::Role::Mutable::Simple'
+ => { value_type => Upload };
override apply_our_events => sub {
my ($self, $events) = @_;
diff --git a/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm b/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm
index 77df3de..a54dfc5 100644
--- a/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Mutable/HiddenArray.pm
@@ -6,9 +6,9 @@ use MooseX::Types::Moose qw/ArrayRef/;
extends 'Reaction::UI::ViewPort::Field';
-with 'Reaction::UI::ViewPort::Field::Role::Mutable';
+with 'Reaction::UI::ViewPort::Field::Role::Mutable' => { value_type => 'ArrayRef' };
-has '+value' => (isa => ArrayRef);
+#has '+value' => (isa => ArrayRef);
around value => sub {
my $orig = shift;
diff --git a/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm b/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm
index 94953f4..16ae93f 100644
--- a/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Role/Mutable.pm
@@ -1,26 +1,46 @@
package Reaction::UI::ViewPort::Field::Role::Mutable;
-use Reaction::Role;
+use MooseX::Role::Parameterized;
use aliased 'Reaction::InterfaceModel::Action';
use aliased 'Reaction::Meta::InterfaceModel::Action::ParameterAttribute';
use MooseX::Types::Moose qw/Int Str/;
-
use namespace::clean -except => [ qw(meta) ];
+=pod
+
+15:24 mst:» I'm not sure I understand why the +foo is overwriting my after'ed clear_value
+15:24 mst:» but I would argue it shouldn't do that
+15:25 @doy:» because has '+foo' is creating an entirely new attribute
+15:25 @doy:» and just copying the meta-attribute's attributes into it
+15:25 @doy:» so it's creating a new clearer sub in the subclass
+15:27 rafl:» mst: for that case, i tend to just parameterize the role on whatever i might want to override in its attribute definitions
+
+=cut
+
+parameter value_type => (
+ predicate => 'has_value_type'
+);
+
+role {
+
+my $p = shift;
+
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'),
+ is => 'rw', lazy_build => 1, trigger => sub { shift->adopt_value },
clearer => 'clear_value',
+ $p->has_value_type? (isa => $p->value_type) : ()
);
+
has needs_sync => (is => 'rw', isa => Int, default => 0); #should be bool?
has message => (is => 'rw', isa => Str, clearer => 'clear_message');
has is_modified => ( #sould be bool?
- is => 'ro', writer => '_set_modified',
+ is => 'ro', writer => '_set_modified',
required => 1, default => 1, init_arg => undef
);
@@ -111,6 +131,7 @@ sub sync_from_action {
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 e19fa61..d8ca473 100644
--- a/lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm
+++ b/lib/Reaction/UI/ViewPort/Field/Role/Mutable/Simple.pm
@@ -1,14 +1,23 @@
package Reaction::UI::ViewPort::Field::Role::Mutable::Simple;
-use Reaction::Role;
+use MooseX::Role::Parameterized;
use aliased 'Reaction::UI::ViewPort::Field::Role::Mutable';
use namespace::clean -except => [ qw(meta) ];
-with Mutable;
+
+parameter value_type => (
+ predicate => 'has_value_type'
+);
+
+role {
+
+my $p = shift;
+
+with Mutable, $p->has_value_type ? { value_type => $p->value_type } : ();
has value_string => (
- is => 'rw', lazy_build => 1, trigger_adopt('value_string'),
+ is => 'rw', lazy_build => 1, trigger => sub { shift->adopt_value_string },
clearer => 'clear_value',
);
@@ -44,6 +53,6 @@ around accept_events => sub { ('value_string', shift->(@_)) };
around force_events => sub { (value_string => '', shift->(@_)) };
-
+};
1;
diff --git a/lib/Reaction/UI/ViewPort/ListViewWithSearch.pm b/lib/Reaction/UI/ViewPort/ListViewWithSearch.pm
index ee5f738..c199f7d 100644
--- a/lib/Reaction/UI/ViewPort/ListViewWithSearch.pm
+++ b/lib/Reaction/UI/ViewPort/ListViewWithSearch.pm
@@ -6,8 +6,6 @@ extends 'Reaction::UI::ViewPort::Collection::Grid';
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;
diff --git a/lib/Reaction/UI/ViewPort/Role/Actions.pm b/lib/Reaction/UI/ViewPort/Role/Actions.pm
index 32c7bbb..ceb9bfe 100644
--- a/lib/Reaction/UI/ViewPort/Role/Actions.pm
+++ b/lib/Reaction/UI/ViewPort/Role/Actions.pm
@@ -67,7 +67,7 @@ sub _build_actions {
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 => $layout,
);
push(@act, $action);
}
diff --git a/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm b/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm
index d83941b..4468275 100644
--- a/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm
+++ b/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm
@@ -74,7 +74,7 @@ override BUILDARGS => sub {
};
override child_event_sinks => method () {
- ((map $self->$_, 'listview', 'search_form'), super);
+ ((map $self->$_, 'search_form', 'listview'), super);
};
1;
diff --git a/lib/Reaction/UI/Widget/Field/Mutable/HiddenArray.pm b/lib/Reaction/UI/Widget/Field/Mutable/HiddenArray.pm
index e4e1c10..a65f3cb 100644
--- a/lib/Reaction/UI/Widget/Field/Mutable/HiddenArray.pm
+++ b/lib/Reaction/UI/Widget/Field/Mutable/HiddenArray.pm
@@ -11,6 +11,10 @@ implements fragment hidden_list {
};
implements fragment hidden_field {
+ # this needs to go here in order to override the field_name from
+ # Widget::Field::Mutable::Simple which defaults to value_string and does not
+ # make sense for HiddenArray
+ arg field_name => event_id 'value';
arg field_value => $_;
};
diff --git a/share/skin/base/layout/action.tt b/share/skin/base/layout/action.tt
index b5cb708..dba41d0 100644
--- a/share/skin/base/layout/action.tt
+++ b/share/skin/base/layout/action.tt
@@ -1,13 +1,11 @@
=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
diff --git a/share/skin/base/layout/collection.tt b/share/skin/base/layout/collection.tt
index 6becfb1..da0cd2f 100644
--- a/share/skin/base/layout/collection.tt
+++ b/share/skin/base/layout/collection.tt
@@ -6,9 +6,7 @@
=for layout body
-<div class="collection_members">
- [% members %]
-</div>
+[% members %]
=for layout footer
diff --git a/share/skin/base/layout/field/array.tt b/share/skin/base/layout/field/array.tt
index cd9c0c2..ac62db7 100644
--- a/share/skin/base/layout/field/array.tt
+++ b/share/skin/base/layout/field/array.tt
@@ -9,11 +9,9 @@
=for layout list
-<div class="array_list">
<ul>
-[% content %]
+ [% content %]
</ul>
-</div>
=for layout item
diff --git a/share/skin/base/layout/field/collection.tt b/share/skin/base/layout/field/collection.tt
index 2203344..1f6ae9e 100644
--- a/share/skin/base/layout/field/collection.tt
+++ b/share/skin/base/layout/field/collection.tt
@@ -9,11 +9,9 @@
=for layout list
-<div class="collection_list">
<ul>
-[% call_next %]
+ [% call_next %]
</ul>
-</div>
=for layout item
diff --git a/share/skin/base/layout/field/container.tt b/share/skin/base/layout/field/container.tt
index c504e55..d9e0ced 100644
--- a/share/skin/base/layout/field/container.tt
+++ b/share/skin/base/layout/field/container.tt
@@ -11,8 +11,6 @@
=for layout field
-<div class="field_container_field">
- [% call_next %]
-</div>
+[% call_next %]
=cut
diff --git a/share/skin/base/layout/field/mutable.tt b/share/skin/base/layout/field/mutable.tt
index d21e979..c4ef2e1 100644
--- a/share/skin/base/layout/field/mutable.tt
+++ b/share/skin/base/layout/field/mutable.tt
@@ -1,6 +1,6 @@
=for layout widget
-<div class="[% field_class %]">[% label_fragment %] [% field %] [% message_fragment %]</div>
+[% label_fragment %] [% field %] [% message_fragment %]
=for layout label
@@ -18,8 +18,7 @@ class="required_field"
=for layout field
-<input type="[% field_type %]" name="[% field_name %]" id="[% field_id %]"
- [% field_body %] />
+<input type="[% field_type %]" name="[% field_name %]" id="[% field_id %]" [% field_body %] />
=for layout field_body
diff --git a/share/skin/base/layout/field/mutable/choose_many.tt b/share/skin/base/layout/field/mutable/choose_many.tt
index 51f315e..9d19fff 100644
--- a/share/skin/base/layout/field/mutable/choose_many.tt
+++ b/share/skin/base/layout/field/mutable/choose_many.tt
@@ -8,7 +8,6 @@
=for layout field
-<div class="choose_many_field">
<table>
<tr>
<td> [% available_values %] </td>
@@ -19,7 +18,6 @@
</td>
</tr>
</table>
-</div>
=for layout available_values
@@ -43,12 +41,10 @@
=for layout action_buttons
-<div class="choose_many_buttons">
- <input type="submit" value="&gt;&gt;" name="[% event_id_add_all_values %]" />
- <input type="submit" value="&gt;" name="[% event_id_do_add_values %]" />
- <input type="submit" value="&lt;" name="[% event_id_do_remove_values %]" />
- <input type="submit" value="&lt;&lt;" name="[% event_id_remove_all_values %]" />
-</div>
+<input type="submit" value="&gt;&gt;" name="[% event_id_add_all_values %]" />
+<input type="submit" value="&gt;" name="[% event_id_do_add_values %]" />
+<input type="submit" value="&lt;" name="[% event_id_do_remove_values %]" />
+<input type="submit" value="&lt;&lt;" name="[% event_id_remove_all_values %]" />
=for layout message
diff --git a/share/skin/base/layout/field/mutable/choose_one.tt b/share/skin/base/layout/field/mutable/choose_one.tt
index 0db3ffd..c366a86 100644
--- a/share/skin/base/layout/field/mutable/choose_one.tt
+++ b/share/skin/base/layout/field/mutable/choose_one.tt
@@ -15,8 +15,7 @@
=for layout option
- <option value="[% option_value %]" [% option_is_selected %]
- > [% option_name %]</option>
+ <option value="[% option_value %]" [% option_is_selected %]>[% option_name %]</option>
=for layout option_is_selected_yes
diff --git a/share/skin/default/layout/action.tt b/share/skin/default/layout/action.tt
index a18e51d..e1b003f 100644
--- a/share/skin/default/layout/action.tt
+++ b/share/skin/default/layout/action.tt
@@ -1,5 +1,11 @@
=extends NEXT
+=for layout widget
+
+<div class="action_form">
+ [% call_next %]
+</div>
+
=for layout container
[% call_next %] <br />
diff --git a/share/skin/default/layout/field/array.tt b/share/skin/default/layout/field/array.tt
index acb2cce..60c86b1 100644
--- a/share/skin/default/layout/field/array.tt
+++ b/share/skin/default/layout/field/array.tt
@@ -4,4 +4,10 @@
<span class="field_array_label"><strong > [% content | html %]: </strong></span>
+=for layout list
+
+<div class="array_list">
+ [% call_next %]
+</div>
+
=cut
diff --git a/share/skin/default/layout/field/collection.tt b/share/skin/default/layout/field/collection.tt
index f513e94..16789bf 100644
--- a/share/skin/default/layout/field/collection.tt
+++ b/share/skin/default/layout/field/collection.tt
@@ -4,4 +4,10 @@
<span class="field_collection_label_box"><strong> [% label %]: </strong></span>
+=for layout list
+
+<div class="collection_list">
+ [% call_next %]
+</div>
+
=cut
diff --git a/share/skin/default/layout/field/mutable.tt b/share/skin/default/layout/field/mutable.tt
index 615e14e..ec10a4c 100644
--- a/share/skin/default/layout/field/mutable.tt
+++ b/share/skin/default/layout/field/mutable.tt
@@ -1,5 +1,9 @@
=extends NEXT
+=for layout widget
+
+<div class="[% field_class %]">[% call_next %]</div>
+
=for layout message
[% call_next %]<br />
diff --git a/share/skin/default/layout/field/mutable/choose_many.tt b/share/skin/default/layout/field/mutable/choose_many.tt
index e01a1ba..117f39e 100644
--- a/share/skin/default/layout/field/mutable/choose_many.tt
+++ b/share/skin/default/layout/field/mutable/choose_many.tt
@@ -6,13 +6,16 @@
[% 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="&gt;&gt;" name="[% event_id_add_all_values %]" /> <br />
-<input type="submit" value="&gt;" name="[% event_id_do_add_values %]" /> <br />
-<input type="submit" value="&lt;" name="[% event_id_do_remove_values %]" /> <br />
-<input type="submit" value="&lt;&lt;" name="[% event_id_remove_all_values %]" /> <br />
+ [% call_next %]
</div>
=cut