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