Mercurial > pub > Impl
diff Lib/IMPL/Web/TT/Form.pm @ 148:e6447ad85cb4
DOM objects now have a schema and schemaSource properties
RegExp now can launder data
Improved post to DOM transformation (multiple values a now supported)
Added new axes to navigation queries: ancestor and descendant
minor changes and bug fixes
author | wizard |
---|---|
date | Mon, 16 Aug 2010 08:26:44 +0400 |
parents | bd10093bb122 |
children | a9f4ba4783eb |
line wrap: on
line diff
--- a/Lib/IMPL/Web/TT/Form.pm Mon Aug 09 08:45:36 2010 +0400 +++ b/Lib/IMPL/Web/TT/Form.pm Mon Aug 16 08:26:44 2010 +0400 @@ -4,7 +4,8 @@ use base qw(IMPL::Web::TT::Control); use IMPL::Class::Property; -use IMPL::DOM::Navigator::SchemaNavigator; +use IMPL::DOM::Navigator::SchemaNavigator(); + __PACKAGE__->PassThroughArgs; BEGIN { @@ -39,6 +40,97 @@ $this->errors([]) unless $this->errors; } +sub fillContents { + my ($this) = @_; + + my $schema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base }); + + $this->buildContainer( + $schema, + $schema, + $this->data->isComplex ? $this->data : undef, + $this + ); +} + +sub buildContainer { + my ($this,$schemaSource,$schema,$domNode,$container,$path) = @_; + + $path = [@{$path || []},{node => $domNode, schemaSource => $schemaSource}]; + + $container ||= $this->document->Create($schemaSource->name,'IMPL::Web::TT::Collection'); + + foreach my $schemaItem ( $schema->content->childNodes ) { + my $schemaItemSource = $schemaItem; + + $schemaItem = $this->schema->resolveType($schemaItem->type) + if typeof $schemaItem eq typeof IMPL::DOM::Schema::Node; + + my @nodesData = $domNode->selectNodes(sub { $_->schemaSource == $schemaItemSource } ) if $domNode; + + push @nodesData, undef unless @nodesData; + + if ($schemaItem->isa(typeof IMPL::DOM::Schema::ComplexNode) ) { + $this->appendChild( $this->buildContainer($schemaItemSource,$schemaItem,$_,undef,$path) ) foreach @nodesData; + } elsif ($schemaItem->isa(typeof IMPL::DOM::Schema::SimpleNode)) { + $this->appendChild( $this->buildControl($schemaItemSource,$schemaItem,$_,$path) ) foreach @nodesData; + } + } + + return $container; +} + +sub buildControl { + my ($this,$schemaSource,$schema,$node,$path) = @_; + + my @errors; + + if ($node) { + @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors}; + } else { + @errors = grep $_->Schema == $schemaSource, @{$this->errors}; + } + + return $this->document->CreateControl( + $schemaSource->name, + $this->mapType($schemaSource), + { + schema => $schema, + sourceSchema => $schemaSource, + errors => \@errors, + data => $node, + nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through + queryParameter => $this->makeParameterName([@$path,{ node => $node, schemaSource => $schemaSource}]) + } + ); +} + +sub mapType { + my ($this,$schema) = @_; + + $schema->nodeProperty('control') || + ( $schema->type && $this->schema->resolveType($schema->type)->nodeProperty('control') ) + or die new IMPL::Exception("Unable to get control class for the form element",$schema->path); +} + +sub makeParameterName { + my ($this,$path) = @_; + + join '/', map { + $_->{node} ? + ( + $_->{node}->nodeProperty('instanceId') ? + $_->{node}->nodeName . '['. ']' : + $_->{node}->nodeName + ) : + ( + $_->{schemaSource}->maxOccur eq 'unbounded' || $_->{schemaSource}->maxOccur > 1 ? + $_->{schemaSource}->name . '[0]' : + $_->{schemaSource}->name + ) + } @$path; +} + sub makeControlArgs{ my ($this,$path) = @_; @@ -107,9 +199,7 @@ } } - 1; - __END__ =pod