comparison 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
comparison
equal deleted inserted replaced
147:c2aa10fbb396 148:e6447ad85cb4
2 package IMPL::Web::TT::Form; 2 package IMPL::Web::TT::Form;
3 3
4 use base qw(IMPL::Web::TT::Control); 4 use base qw(IMPL::Web::TT::Control);
5 5
6 use IMPL::Class::Property; 6 use IMPL::Class::Property;
7 use IMPL::DOM::Navigator::SchemaNavigator; 7 use IMPL::DOM::Navigator::SchemaNavigator();
8
8 __PACKAGE__->PassThroughArgs; 9 __PACKAGE__->PassThroughArgs;
9 10
10 BEGIN { 11 BEGIN {
11 public property base => prop_all; 12 public property base => prop_all;
12 public property schema => prop_all; 13 public property schema => prop_all;
35 die new IMPL::InvalidOperationException('Can\'t find a form definition in a schema',$this->nodeName,$this->base) 36 die new IMPL::InvalidOperationException('Can\'t find a form definition in a schema',$this->nodeName,$this->base)
36 unless $this->schema->selectNodes(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base }); 37 unless $this->schema->selectNodes(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base });
37 } 38 }
38 39
39 $this->errors([]) unless $this->errors; 40 $this->errors([]) unless $this->errors;
41 }
42
43 sub fillContents {
44 my ($this) = @_;
45
46 my $schema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base });
47
48 $this->buildContainer(
49 $schema,
50 $schema,
51 $this->data->isComplex ? $this->data : undef,
52 $this
53 );
54 }
55
56 sub buildContainer {
57 my ($this,$schemaSource,$schema,$domNode,$container,$path) = @_;
58
59 $path = [@{$path || []},{node => $domNode, schemaSource => $schemaSource}];
60
61 $container ||= $this->document->Create($schemaSource->name,'IMPL::Web::TT::Collection');
62
63 foreach my $schemaItem ( $schema->content->childNodes ) {
64 my $schemaItemSource = $schemaItem;
65
66 $schemaItem = $this->schema->resolveType($schemaItem->type)
67 if typeof $schemaItem eq typeof IMPL::DOM::Schema::Node;
68
69 my @nodesData = $domNode->selectNodes(sub { $_->schemaSource == $schemaItemSource } ) if $domNode;
70
71 push @nodesData, undef unless @nodesData;
72
73 if ($schemaItem->isa(typeof IMPL::DOM::Schema::ComplexNode) ) {
74 $this->appendChild( $this->buildContainer($schemaItemSource,$schemaItem,$_,undef,$path) ) foreach @nodesData;
75 } elsif ($schemaItem->isa(typeof IMPL::DOM::Schema::SimpleNode)) {
76 $this->appendChild( $this->buildControl($schemaItemSource,$schemaItem,$_,$path) ) foreach @nodesData;
77 }
78 }
79
80 return $container;
81 }
82
83 sub buildControl {
84 my ($this,$schemaSource,$schema,$node,$path) = @_;
85
86 my @errors;
87
88 if ($node) {
89 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors};
90 } else {
91 @errors = grep $_->Schema == $schemaSource, @{$this->errors};
92 }
93
94 return $this->document->CreateControl(
95 $schemaSource->name,
96 $this->mapType($schemaSource),
97 {
98 schema => $schema,
99 sourceSchema => $schemaSource,
100 errors => \@errors,
101 data => $node,
102 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through
103 queryParameter => $this->makeParameterName([@$path,{ node => $node, schemaSource => $schemaSource}])
104 }
105 );
106 }
107
108 sub mapType {
109 my ($this,$schema) = @_;
110
111 $schema->nodeProperty('control') ||
112 ( $schema->type && $this->schema->resolveType($schema->type)->nodeProperty('control') )
113 or die new IMPL::Exception("Unable to get control class for the form element",$schema->path);
114 }
115
116 sub makeParameterName {
117 my ($this,$path) = @_;
118
119 join '/', map {
120 $_->{node} ?
121 (
122 $_->{node}->nodeProperty('instanceId') ?
123 $_->{node}->nodeName . '['. ']' :
124 $_->{node}->nodeName
125 ) :
126 (
127 $_->{schemaSource}->maxOccur eq 'unbounded' || $_->{schemaSource}->maxOccur > 1 ?
128 $_->{schemaSource}->name . '[0]' :
129 $_->{schemaSource}->name
130 )
131 } @$path;
40 } 132 }
41 133
42 sub makeControlArgs{ 134 sub makeControlArgs{
43 my ($this,$path) = @_; 135 my ($this,$path) = @_;
44 136
105 } else { 197 } else {
106 return []; 198 return [];
107 } 199 }
108 } 200 }
109 201
110
111 1; 202 1;
112
113 __END__ 203 __END__
114 204
115 =pod 205 =pod
116 206
117 =head1 NAME 207 =head1 NAME