port actionform, field widgets to declarative system
matthewt [Fri, 14 Dec 2007 21:10:01 +0000 (21:10 +0000)]
21 files changed:
lib/Reaction/UI/ViewPort/Field.pm
lib/Reaction/UI/Widget/ActionForm.pm
lib/Reaction/UI/Widget/Field.pm
lib/Reaction/UI/Widget/Field/Boolean.pm
lib/Reaction/UI/Widget/Field/ChooseMany.pm
lib/Reaction/UI/Widget/Field/ChooseOne.pm
lib/Reaction/UI/Widget/Field/DateTime.pm
lib/Reaction/UI/Widget/Field/HiddenArray.pm
lib/Reaction/UI/Widget/Field/Password.pm
lib/Reaction/UI/Widget/ListView.pm
share/skin/default/layout/action_form.tt
share/skin/default/layout/field.tt [new file with mode: 0644]
share/skin/default/layout/field/boolean.tt
share/skin/default/layout/field/choose_many.tt
share/skin/default/layout/field/choose_one.tt
share/skin/default/layout/field/date_time.tt
share/skin/default/layout/field/hidden_array.tt
share/skin/default/layout/field/password.tt
share/skin/default/layout/field/string.tt
share/skin/default/layout/field/text.tt
share/skin/default/layout/list_view.tt

index f0fa0f0..1712c75 100644 (file)
@@ -64,6 +64,8 @@ class Field is 'Reaction::UI::ViewPort', which {
     $self->needs_sync(1) if $self->has_attribute;
   };
 
+  implements value_string => as { shift->value };
+
   implements sync_to_action => as {
     my ($self) = @_;
     return unless $self->needs_sync && $self->has_attribute && $self->has_value;
index 2f587e9..858d218 100644 (file)
@@ -3,22 +3,42 @@ package Reaction::UI::Widget::ActionForm;
 use Reaction::UI::WidgetClass;
 
 class ActionForm, which {
-  fragment widget [ qw/header field_list buttons footer/ ]
-    => {id => sub { $_{viewport}->location } };
-
-  fragment field_list [field => over func('viewport','ordered_fields')];
-  fragment field  [ 'viewport' ];
-
-  #move button logic here
-  fragment buttons [ string {"DUMMY"} ],
-    { message => sub{ $_{viewport}->can('message') ? $_{viewport}->message : "" },
-      ok_label    => func(viewport => 'ok_label'),
-      close_label => func(viewport => 'close_label'),
-      apply_label => func(viewport => 'apply_label'),
-    };
-
-  fragment header  [ string {"DUMMY"} ];
-  fragment footer  [ string {"DUMMY"} ];
+
+  #implements fragment widget {
+  #  arg form_id => $_{viewport}->location;
+  #};
+
+  implements fragment field_list {
+    render field => over $_{viewport}->ordered_fields;
+  };
+
+  implements fragment field {
+    render 'viewport';
+  };
+
+  implements fragment ok_button_fragment {
+    if (grep { $_ eq 'ok' } $_{viewport}->accept_events) {
+      arg 'event_id' => event_id 'ok';
+      arg 'label' => $_{viewport}->ok_label;
+      render 'ok_button';
+    }
+  };
+
+  implements fragment apply_button_fragment {
+    if (grep { $_ eq 'apply' } $_{viewport}->accept_events) {
+      arg 'event_id' => event_id 'apply';
+      arg 'label' => $_{viewport}->apply_label;
+      render 'apply_button';
+    }
+  };
+
+  implements fragment cancel_button_fragment {
+    if (grep { $_ eq 'cancel' } $_{viewport}->accept_events) {
+      arg 'event_id' => event_id 'cancel';
+      arg 'label' => $_{viewport}->cancel_label;
+      render 'cancel_button';
+    }
+  };
 
 };
 
index 40ca595..9b22905 100644 (file)
@@ -4,15 +4,28 @@ use Reaction::UI::WidgetClass;
 
 class Field, which {
 
-  fragment widget [qw/label field message/
-                  => { id       => sub { $_{viewport}->event_id_for('value') },
-                       name     => sub { $_{viewport}->event_id_for('value') },
-                 ];
-
-  fragment field   [ string { $_{viewport}->value },   ];
-
-  fragment label   [ string { $_{viewport}->label   }, ];
-  fragment message [ string { $_{viewport}->message }, ];
+  before fragment widget {
+    arg 'field_id' => event_id 'value';
+    arg 'field_name' => event_id 'value';
+    arg 'field_type' => 'text';
+    if ($_{viewport}->can('value_string')) {
+      arg 'field_value' => $_{viewport}->value_string;
+    }
+  };
+
+  implements fragment message_fragment {
+    if (my $message = $_{viewport}->message) {
+      arg message => $message;
+      render 'message';
+    }
+  };
+
+  implements fragment label_fragment {
+    if (my $label = $_{viewport}->label) {
+      arg label => $label;
+      render 'label';
+    }
+  };
 
 };
 
index a4defcd..986d7b0 100644 (file)
@@ -4,6 +4,14 @@ use Reaction::UI::WidgetClass;
 
 class Boolean is 'Reaction::UI::Widget::Field', which {
 
+  implements fragment is_checked {
+    if ($_{viewport}->value) {
+      render 'is_checked_yes';
+    } else {
+      render 'is_checked_no';
+    }
+  };
+
 };
 
 1;
index 8520068..efb100d 100644 (file)
@@ -4,15 +4,36 @@ use Reaction::UI::WidgetClass;
 
 class ChooseMany is 'Reaction::UI::Widget::Field', which {
 
-  fragment field [qw/available_values action_buttons selected_values current_values/];
-
-  fragment current_values [ hidden_value => over func('viewport', 'current_value_choices')  ];
-  fragment hidden_value   [ string { $_->{value} } ];
-
-  fragment available_values [ option => over func('viewport', 'available_value_choices') ];
-  fragment selected_values  [ option => over func('viewport', 'current_value_choices')   ];
-  fragment option [string {"DUMMY"}], { v_value => sub {$_->{value}}, v_name => sub {$_->{name}} };
-  fragment action_buttons [ string {"DUMMY"} ];
+  implements fragment action_buttons {
+    foreach my $event (
+      qw(add_all_values do_add_values do_remove_values remove_all_values)
+        ) {
+      arg "event_id_${event}" => event_id $event;
+    }
+  };
+
+  implements fragment current_values {
+    render hidden_value => over $_{viewport}->current_value_choices;
+  };
+
+  implements fragment selected_values {
+    arg event_id_remove_values => event_id 'remove_values';
+    render value_option => over $_{viewport}->current_value_choices;
+  };
+
+  implements fragment available_values {
+    arg event_id_add_values => event_id 'add_values';
+    render value_option => over $_{viewport}->available_value_choices;
+  };
+
+  implements fragment value_option {
+    arg option_name => $_->{name};
+    arg option_value => $_->{value};
+  };
+
+  implements fragment hidden_value {
+    arg hidden_value => $_->{value};
+  };
 
 };
 
index c127cef..e9aa439 100644 (file)
@@ -4,15 +4,30 @@ use Reaction::UI::WidgetClass;
 
 class ChooseOne is 'Reaction::UI::Widget::Field', which {
 
-  fragment field  [ option => over func('viewport', 'value_choices') ],
-    { is_required => sub{ $_{viewport}->attribute->required } };
-
-  fragment option [string {"DUMMY"}],
-    {
-     v_value  => sub { $_->{value} },
-     v_name   => sub { $_->{name}  },
-     is_selected => sub { $_{viewport}->is_current_value($_->{value}) },
-    };
+  implements fragment option_is_required {
+    if ($_{viewport}->attribute->required) {
+      render 'options_is_required_yes';
+    } else {
+      render 'options_is_required_no';
+    }
+  };
+
+  implements fragment option_list {
+    render option => over $_{viewport}->value_choices;
+  };
+
+  implements fragment option {
+    arg option_name => $_->{name};
+    arg option_value => $_->{value};
+  };
+
+  implements fragment option_is_selected {
+    if ($_{viewport}->is_current_value($_->{value})) {
+      render 'option_is_selected_yes';
+    } else {
+      render 'option_is_selected_no';
+    }
+  };
 
 };
 
index 21e0069..d174d0f 100644 (file)
@@ -4,8 +4,6 @@ use Reaction::UI::WidgetClass;
 
 class DateTime is 'Reaction::UI::Widget::Field', which {
 
-  fragment field [ string { $_{viewport}->value_string }, ];
-
 };
 
 1;
index a7d4a2d..d64e4ca 100644 (file)
@@ -4,8 +4,13 @@ use Reaction::UI::WidgetClass;
 
 class HiddenArray is 'Reaction::UI::Widget::Field', which {
 
-  fragment field [ item => over func('viewport', 'value') ];
-  fragment item  [ string { $_ } ];
+  implements fragment hidden_list {
+    render hidden_field => over $_{viewport}->value;
+  };
+
+  implements fragment hidden_field {
+    arg field_value => $_;
+  };
 
 };
 
index 7525530..472f929 100644 (file)
@@ -4,6 +4,11 @@ use Reaction::UI::WidgetClass;
 
 class Password is 'Reaction::UI::Widget::Field', which {
 
+  around fragment widget {
+    call_next;
+    arg field_type => 'password';
+  };
+
 };
 
 1;
index 9562900..cfd8028 100644 (file)
@@ -4,6 +4,10 @@ use Reaction::UI::WidgetClass;
 
 class ListView is 'Reaction::UI::Widget::GridView', which {
 
+  after fragment widget {
+    arg pager_obj => $_{viewport}->pager;
+  };
+
   implements fragment actions {
     render action => over $_{viewport}->actions;
   };
@@ -28,7 +32,54 @@ class ListView is 'Reaction::UI::Widget::GridView', which {
   };
 
   implements fragment header_action_cell {
-    arg 'col_count' => $_{viewport}->object_action_count;
+    arg col_count => $_{viewport}->object_action_count;
+  };
+
+  implements fragment page_list {
+    render numbered_page_fragment
+      => over [ $_{pager_obj}->first_page .. $_{pager_obj}->last_page ];
+  };
+
+  implements fragment numbered_page_fragment {
+    arg page_uri => event_uri { page => $_ };
+    arg page_number => $_;
+    if ($_{pager_obj}->current_page == $_) {
+      render 'numbered_page_this_page';
+    } else {
+      render 'numbered_page';
+    }
+  };
+
+  implements fragment first_page {
+    arg page_uri => event_uri { page => $_{pager_obj}->first_page };
+    arg page_name => 'First';
+    render 'named_page';
+  };
+
+  implements fragment last_page {
+    arg page_uri => event_uri { page => $_{pager_obj}->last_page };
+    arg page_name => 'Last';
+    render 'named_page';
+  };
+
+  implements fragment next_page {
+    arg page_name => 'Next';
+    if (my $page = $_{pager_obj}->next_page) {
+      arg page_uri => event_uri { page => $page };
+      render 'named_page';
+    } else {
+      render 'named_page_no_page';
+    }
+  };
+
+  implements fragment previous_page {
+    arg page_name => 'Previous';
+    if (my $page = $_{pager_obj}->previous_page) {
+      arg page_uri => event_uri { page => $page };
+      render 'named_page';
+    } else {
+      render 'named_page_no_page';
+    }
   };
 
 };
index 473c4cd..fa71d79 100644 (file)
@@ -9,26 +9,39 @@
 
 =for layout header
 
-<h2>Le Header</h2>
+<!-- header -->
 
 =for layout field_list
 
-<p> [% content %] </p>
+<p> [% call_next %] </p>
 
 =for layout field
 
-[% content %] <br />
+[% call_next %] <br />
 
-=for layout buttons
+=for layout message_layout
 
-  [% IF message; %]
     <span>[% message %]</span> <br />
-  [% END; %]
 
-  [% allowed_events = viewport.accept_events; %]
-  [% IF allowed_events.grep('^ok$').size; %]
-    <input type="submit" name="[% viewport.event_id_for('ok')    | html%]" value="[% ok_label %]" />
-  [% END; %]
+=for layout buttons
+  [% message %]
+  [% ok_button_fragment %]
+  [% apply_button_fragment %]
+  [% cancel_button_fragment %]
+
+=for layout ok_button
+
+  <input type="submit" name="[% event_id %]" value="[% label %]" />
+
+=for layout apply_button
+
+  <input type="submit" name="[% event_id %]" value="[% label %]" />
+
+=for layout cancel_button
+
+  <input type="submit" name="[% event_id %]" value="[% label %]" />
+
+=for layout whut
 
   [% IF (viewport.ordered_fields.size != 0) && allowed_events.grep('^apply$').size; %]
     <input type="submit" name="[% viewport.event_id_for('apply') | html%]" value="[% apply_label %]" />
@@ -41,6 +54,6 @@
 
 =for layout footer
 
-  <h2>Le Footer</h2>
+  <!-- footer -->
 
 =cut
diff --git a/share/skin/default/layout/field.tt b/share/skin/default/layout/field.tt
new file mode 100644 (file)
index 0000000..fbda583
--- /dev/null
@@ -0,0 +1,26 @@
+=for layout widget
+
+[% label_fragment %] [% field %] [% message_fragment %] <br />
+
+=for layout label
+
+<label>[% label %]:</label>
+
+=for layout field
+
+FIELD GOES HERE
+
+=for layout message
+
+<span>[% message %]</span><br />
+
+=for layout field
+
+<input type="[% field_type %]" name="[% field_name %]" id="[% field_id %]"
+  [% field_body %] />
+
+=for layout field_body
+
+value="[% field_value %]"
+
+=cut
index 73b817e..b750116 100644 (file)
@@ -1,34 +1,13 @@
-=for layout widget
+=extends field
 
-[% label %] [% field %] [% message %] <br>
+=for layout field_body
 
-=for layout field
+value="1" [% is_checked %]
 
-[%
-   IF content;
-    checked = 'checked="checked"';
-   ELSE;
-    checked = "";
-   END;
-%]
+=for layout is_checked_yes
 
-<!-- We need a replacement for process_attrs -->
-<input type="checkbox" id="[% id | html %]" name="[% name | html %]" value="1" [% checked %] />
+checked="checked"
 
-=for layout label
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <label> [% content_str | html %]: </label>
-[% END; %]
-
-=for layout message
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <span> [% content_str | html %] </span> <br />
-[% END %]
+=for layout is_checked_no
 
 =cut
index 1479de8..ba4543a 100644 (file)
@@ -1,8 +1,10 @@
+=extends field
+
 =for layout widget
 
-[% label %]
+[% label_fragment %]
 <br />
-[% message %]
+[% message_fragment %]
 [% field %]
 
 =for layout field
 
 =for layout available_values
 
-<select size="10" multiple="multiple"  name="[% viewport.event_id_for('add_values') | html %]">
-  [% content %]
+<select size="10" multiple="multiple"  name="[% event_id_add_values %]">
+  [% call_next %]
 </select>
 
 =for layout selected_values
 
-<select size="10" multiple="multiple"  name="[% viewport.event_id_for('remove_values') | html %]">
-  [% content %]
+<select size="10" multiple="multiple"  name="[% event_id_remove_values %]">
+  [% call_next %]
 </select>
 
-=for layout current_values
-
-[% content %]
-
 =for layout hidden_value
 
-<input type="hidden" name="[% viewport.event_id_for('value') | html %]" value="[% content | html %]">
+<input type="hidden" name="[% field_name %]" value="[% hidden_value %]">
 
-=for layout option
+=for layout value_option
 
-<option value="[% v_value | html %]">[% v_name | html %]</option>
+<option value="[% option_value %]">[% option_name %]</option>
 
 =for layout action_buttons
 
-<input type="submit" value="&gt;&gt;" name="[% viewport.event_id_for('add_all_values') | html %]" /> <br />
-<input type="submit" value="&gt;" name="[% viewport.event_id_for('do_add_values') | html %]" /> <br />
-<input type="submit" value="&lt;" name="[% viewport.event_id_for('do_remove_values') | html %]" /> <br />
-<input type="submit" value="&lt;&lt;" name="[% viewport.event_id_for('remove_all_values') | html %]" /> <br />
-
-=for layout label
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <label> [% content_str | html %]: </label>
-[% END; %]
-
-=for layout message
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <span> [% content_str | html %] </span> <br />
-[% END %]
+<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 />
 
 =cut
index 2fd39d6..ec1814a 100644 (file)
@@ -1,42 +1,28 @@
-=for layout widget
-
-[% label %] [% field %] [% message %]
+=extends field
 
 =for layout field
 
 <!-- We need a replacement for process_attrs -->
-<select name="[% name | html %]" id="[% id | html %]">
-  [% IF is_required %]
-    <option value="">--</option>
-  [% END %]
-  [% content %]
+<select name="[% field_name %]" id="[% field_id %]">
+  [% option_is_required %]
+  [% option_list %]
 </select>
 
+=for layout option_is_required_yes
+
+=for layout option_is_required_no
+
+<option value="">--</option>
+
 =for layout option
 
-  [% IF is_selected;
-       selected = ' selected="selected"';
-     ELSE;
-       selected =  '';
-     END;
-  %]
-  <!-- I should convert this stuff to process_attrs to keep it cleaner -->
-  <option value="[% v_value | html%]" [% selected %]> [% v_name | html %]</option>
-
-=for layout label
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <label> [% content_str | html %]: </label>
-[% END; %]
-
-=for layout message
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <span> [% content_str | html %] </span> <br />
-[% END %]
+  <option value="[% option_value %]" [% option_is_selected %]
+    > [% option_name %]</option>
+
+=for options_is_selected_yes
+
+selected="selected"
+
+=for option_is_selected_no
 
 =cut
index 4dbd294..18ab448 100644 (file)
@@ -1,26 +1,3 @@
-=for layout widget
-
-[% label %] [% field %] [% message %]
-
-=for layout field
-
-<!-- We need a replacement for process_attrs -->
-<input type="text" name="[% name | html %]" id="[% id | html%]" value="[% content | html %]" />
-
-=for layout label
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <label> [% content_str | html %]: </label>
-[% END; %]
-
-=for layout message
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <span> [% content_str | html %] </span> <br />
-[% END %]
+=extends field
 
 =cut
index ebc06af..0f5e35d 100644 (file)
@@ -1,17 +1,9 @@
 =for layout widget
 
-[% field %]
+[% hidden_list %]
 
-=for layout field
+=for layout hidden_field
 
-[% item %]
-
-=for layout item
-
-<input type="hidden" name="[% name | html %]" value="[% content | html %]" />
-
-=for layout label
-
-=for layout message
+<input type="hidden" name="[% field_name %]" value="[% field_value %]" />
 
 =cut
index e29029a..18ab448 100644 (file)
@@ -1,26 +1,3 @@
-=for layout widget
-
-[% label %] [% field %] [% message %]
-
-=for layout field
-
-<!-- We need a replacement for process_attrs -->
-<input type="password" name="[% name | html %]" id="[% id | html %]" value="[% content | html %]" />
-
-=for layout label
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <label> [% content_str | html %]: </label>
-[% END; %]
-
-=for layout message
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <span> [% content_str | html %] </span> <br />
-[% END %]
+=extends field
 
 =cut
index 40f3789..18ab448 100644 (file)
@@ -1,26 +1,3 @@
-=for layout widget
-
-[% label %] [% field %] [% message %]
-
-=for layout field
-
-<!-- We need a replacement for process_attrs -->
-<input type="text" name="[% name | html %]" id="[% id | html %]" value="[% content | html %]" />
-
-=for layout label
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <label> [% content_str | html %]: </label>
-[% END; %]
-
-=for layout message
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <span> [% content_str | html %] </span> <br />
-[% END %]
+=extends field
 
 =cut
index b68ce67..e472cc8 100644 (file)
@@ -1,28 +1,9 @@
-=for layout widget
-
-[% label %] [% field %] [% message %]
+=extends field
 
 =for layout field
 
-<!-- We need a replacement for process_attrs -->
-<textarea name="[% name | html %]" id="[% id | html %]">
-  [% content | html %]
+<textarea name="[% field_name %]" id="[% field_id %]">
+  [% field_value %]
 </textarea>
 
-=for layout label
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <label> [% content_str | html %]: </label>
-[% END; %]
-
-=for layout message
-
-<!-- This conditional goes away when mst comes up with something better -->
-[% content_str = GET content; %]
-[% IF content_str.length; %]
-  <span> [% content_str | html %] </span> <br />
-[% END %]
-
 =cut
index d74e2b4..61e92a8 100644 (file)
 
 =for layout pager
 
-<p>Pager would be here. But it isn't.</p>
+<ul class="pager">
+  [% first_page %]
+  [% previous_page %]
+  [% page_list %]
+  [% next_page %]
+  [% last_page %]
+</ul>
+
+=for layout numbered_page_this_page
+
+<li> [% page_number %] </li>
+
+=for layout numbered_page
+
+<li> <a href="[% page_uri %]">[% page_number %]</a> </li>
+
+=for layout named_page
+
+<li> <a href="[% page_uri %]">[% page_name %]</a> </li>
+
+=for layout named_page_no_page
+
+<li> [% page_name %] </li>
 
 =cut