--- trunk/lib/Strix/View/User.pm 2008/07/09 16:38:48 71
+++ trunk/lib/Strix/View/User.pm 2008/07/11 13:11:36 97
@@ -1,6 +1,7 @@
package Strix::View::User;
use Data::Dump qw/dump/;
+use Carp qw/carp/;
use metaclass 'Moose::Meta::Class' => (
attribute_metaclass => 'Continuity::Meta::Attribute::FormField'
@@ -8,35 +9,191 @@
use Moose;
-extends 'Continuity::Widget';
+#extends 'Continuity::Widget';
+extends 'Frey::Web::Button';
#with 'BonusTypes';
-before main => sub {
- my ($self) = @_;
-# $self->add_button('Show ID' => sub {
-# print STDERR "ID = @{[$self->id]}!\n";
-# $self->next("id @{[$self->id]}!");
-# });
- $self->add_button('Edit' => sub {
- my $out = $self->renderer->{edit}->($self);
+use Moose::Util::TypeConstraints;
+
+enum 'Render_as' => qw( view edit none );
+has _render_as => ( is => 'rw', isa => 'Render_as', required => 1, default => 'view' );
+
+has _fey => (
+ is => 'rw',
+ label => 'Fey object',
+ isa => 'Strix::User',
+);
+
+enum 'Layouts' => qw( div table columns );
+has _layout => (
+ is => 'rw',
+ isa => 'Layouts',
+ default => 'div',
+ required => 1,
+);
+
+sub render_iterator {
+ confess "BACKWARD INCOMATIBLE CHANGE: render_iterator works ONLY with 2 params!" unless $#_ == 1;
+ my ($self, $iterator) = @_;
+ my %attrmap = %{ $self->meta->get_attribute_map };
+ my $out;
+ while( my ($name, $attr) = each %attrmap ) {
+ my $reader = $attr->get_read_method;
+ my $val = $self->$reader || '';
+ my $field_name = $self->field_name($name);
+ $out .= $iterator->( $name, $field_name, $attr->label, $val ) || ''; # || '' to shut warnings
+ }
+ return $out;
+}
+
+sub edit_delete_buttons {
+ my $self = shift;
+
+ return unless $self->_fey;
+
+ $self->add_button( 'Edit' => sub {
+ $self->remove_button( 'Delete' );
+ $self->rename_button( 'Edit' => 'Save' );
+ my $out = $self->render_edit;
my $f = $self->next($out);
- $self->set_from_hash($f, sub {
- warn "## inside set_from_hash ",dump( @_ );
- my $hash = shift || die "no hash?";
- warn "## hash = ",dump( $hash );
- $self->_fey->update( %$hash );
- });
+ my $hash = $self->set_from_hash($f);
+ warn "# Edit/Save hash = ",dump( $hash );
+ $self->_fey->update( %$hash ) if $hash;
+ $self->rename_button( 'Save' => 'Edit' );
+ $self->delete_button;
+ });
+ $self->delete_button;
+}
+
+sub delete_button {
+ my $self = shift;
+ $self->add_button('Delete' => sub {
+ $self->_fey->delete;
+ $self->next( qq|
Deleted id @{[$self->id]}!
|);
+ $self->_render_as( 'none' );
+# Strix::Schema->ClearObjectCaches(); # XXX important!
});
+}
+
+sub main {
+ my ( $self ) = @_;
+
+ if ( ! $self->_fey ) {
+ $self->add_button( 'Add' => sub {
+ my $f = shift;
+ my $hash = $self->set_from_hash($f);
+ delete( $hash->{id} ); # FIXME clear primary key
+ my $u = Strix::User->insert( %$hash );
+ warn "Inserted ",$u->id;
+ # XXX store object for later
+ $self->_fey( $u );
+ # put ID in widget, so that it know it's not new
+ $self->id( $u->id );
+ $self->_render_as( 'view' );
+ $self->edit_delete_buttons;
+ $self->remove_button( 'Add' );
+ });
+ }
+
+ $self->edit_delete_buttons;
+
+ warn "# ",$self->uuid, " [", $self->id ,"] _fey = ",dump( $self->_fey );
+
+ while(1) {
+ my $out;
+ if ( $self->_render_as eq 'edit' ) {
+ $out .= $self->render_edit;
+ } elsif ( $self->_render_as eq 'view' ) {
+ $out .= $self->render_view;
+ } else {
+ warn "no renderer ",dump( $self->_render_as ), " skipping...";
+ }
+
+ warn $@ if $@;
+ warn ">>> ",length($out),"\n";
+ my $f = $self->next($out);
+ $self->set_from_hash($f);
+ $self->exec_buttons($f);
+ }
};
+sub render_edit {
+ my $self = shift;
+ warn "# render_edit ",$self->id," ",$self->uuid, " ", $self->_layout, "\n";
+ my $out = $self->render_iterator( sub {
+ #warn "# edit render_iterator ",dump( @_ );
+ my ( $name, $field_name, $label, $val ) = @_;
+ return if $name =~ /^_/;
+ return qq|
+
+ $label |
+
+
+ |
+
+ | if $self->_layout eq 'table';
+ return qq|
+
+
+ |
+ | if $self->_layout eq 'columns';
+ return qq|
+
+ |;
+ });
+
+ return qq|$out| . $self->render_buttons . qq| |
| if $self->_layout eq 'columns';
+
+ $self->render_wrapper_class( $out, 'editform' );
+}
+
+sub render_view {
+ my $self = shift;
+ warn "# render_view ",$self->id," ",$self->uuid," ", $self->_layout,"\n";
+ my $out = $self->render_iterator( sub {
+ #warn "# view render_iterator ",dump( @_ );
+ my ( $name, $field_name, $label, $val ) = @_;
+ return if $name =~ /^_/;
+ return qq|$label | $val |
| if $self->_layout eq 'table';
+ return qq|$val | | if $self->_layout eq 'columns';
+ return qq|
+
+
+ |;
+ });
+ return qq|$out| . $self->render_buttons . qq| |
| if $self->_layout eq 'columns';
+ $self->render_wrapper_class( $out, 'view' );
+}
+
+sub render_wrapper_class {
+ my ( $self, $out, $class ) = @_;
+ if ( length($out) == 0 ) {
+ carp "no output, skipping";
+ return '';
+ }
+ $out =~ s/^\t+//mg; # XXX compress output
+ return $out . qq|| . $self->render_buttons . qq| |
| if $self->_layout eq 'table';
+ return qq|| . $out . $self->render_buttons . qq|
|;
+}
+
use Data::Dump qw/dump/;
use Strix::User;
my $m = Strix::User->meta;
foreach ( $m->get_attribute_list ) {
- warn ">> $_\n";
my $attr = $m->get_attribute( $_ );
+ warn ">> $_\n";
+
+ # FIXME primary key would have to be read-only!
has $_ => (
is => $attr->_is_metadata,
@@ -46,15 +203,4 @@
}
-has _foo => (
- is => 'rw',
- label => 'Foo',
-);
-
-has _fey => (
- is => 'rw',
- label => 'Fey object',
- isa => 'Strix::User',
-);
-
1;