Mercurial > pub > Impl
comparison Lib/IMPL/Web/TT/Form.pm @ 194:4d0e1962161c
Replaced tabs with spaces
IMPL::Web::View - fixed document model, new features (control classes, document constructor parameters)
author | cin |
---|---|
date | Tue, 10 Apr 2012 20:08:29 +0400 |
parents | d1676be8afcc |
children |
comparison
equal
deleted
inserted
replaced
193:8e8401c0aea4 | 194:4d0e1962161c |
---|---|
7 use IMPL::DOM::Navigator::SchemaNavigator(); | 7 use IMPL::DOM::Navigator::SchemaNavigator(); |
8 | 8 |
9 __PACKAGE__->PassThroughArgs; | 9 __PACKAGE__->PassThroughArgs; |
10 | 10 |
11 BEGIN { | 11 BEGIN { |
12 public property base => prop_all; | 12 public property base => prop_all; |
13 public property schema => prop_all; | 13 public property schema => prop_all; |
14 public property errors => prop_all; | 14 public property errors => prop_all; |
15 public property data => prop_all; | 15 public property data => prop_all; |
16 public property state => prop_all; | 16 public property state => prop_all; |
17 public property formResult => prop_all; | 17 public property formResult => prop_all; |
18 } | 18 } |
19 | 19 |
20 sub CTOR { | 20 sub CTOR { |
21 my ($this) = @_; | 21 my ($this) = @_; |
22 | 22 |
23 if (my $form = $this->formResult) { | 23 if (my $form = $this->formResult) { |
24 $this->base($form->{formName}); | 24 $this->base($form->{formName}); |
25 $this->errors($form->{formErrors}); | 25 $this->errors($form->{formErrors}); |
26 $this->data($form->{formData}); | 26 $this->data($form->{formData}); |
27 $this->schema($form->{formSchema}); | 27 $this->schema($form->{formSchema}); |
28 $this->state($form->{state}); | 28 $this->state($form->{state}); |
29 } else { | 29 } else { |
30 | 30 |
31 $this->base($this->nodeName) unless $this->base; | 31 $this->base($this->nodeName) unless $this->base; |
32 | 32 |
33 die new IMPL::InvalidArgumentException('A schema is required for a form',$this->nodeName) | 33 die new IMPL::InvalidArgumentException('A schema is required for a form',$this->nodeName) |
34 unless eval { $this->schema->isa( typeof IMPL::DOM::Schema ) }; | 34 unless eval { $this->schema->isa( typeof IMPL::DOM::Schema ) }; |
35 | 35 |
36 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) |
37 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 }); |
38 } | 38 } |
39 | 39 |
40 $this->errors([]) unless $this->errors; | 40 $this->errors([]) unless $this->errors; |
41 } | 41 } |
42 | 42 |
43 sub fillContents { | 43 sub fillContents { |
44 my ($this) = @_; | 44 my ($this) = @_; |
45 | 45 |
46 my $schema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base }); | 46 my $schema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base }); |
47 | 47 |
48 $this->buildContainer( | 48 $this->buildContainer( |
49 $schema, | 49 $schema, |
50 $schema, | 50 $schema, |
51 $this->data->isComplex ? $this->data : undef, | 51 $this->data->isComplex ? $this->data : undef, |
52 $this | 52 $this |
53 ); | 53 ); |
54 } | 54 } |
55 | 55 |
56 sub buildContainer { | 56 sub buildContainer { |
57 my ($this,$schemaSource,$schema,$domNode,$container,$path) = @_; | 57 my ($this,$schemaSource,$schema,$domNode,$container,$path) = @_; |
58 | 58 |
59 $path = [@{$path || []},{node => $domNode, schemaSource => $schemaSource}]; | 59 $path = [@{$path || []},{node => $domNode, schemaSource => $schemaSource}]; |
60 | 60 |
61 $container ||= $this->document->Create($schemaSource->name,'IMPL::Web::TT::Collection'); | 61 $container ||= $this->document->Create($schemaSource->name,'IMPL::Web::TT::Collection'); |
62 | 62 |
63 foreach my $schemaItem ( $schema->content->childNodes ) { | 63 foreach my $schemaItem ( $schema->content->childNodes ) { |
64 my $schemaItemSource = $schemaItem; | 64 my $schemaItemSource = $schemaItem; |
65 | 65 |
66 $schemaItem = $this->schema->resolveType($schemaItem->type) | 66 $schemaItem = $this->schema->resolveType($schemaItem->type) |
67 if typeof $schemaItem eq typeof IMPL::DOM::Schema::Node; | 67 if typeof $schemaItem eq typeof IMPL::DOM::Schema::Node; |
68 | 68 |
69 my @nodesData = $domNode->selectNodes(sub { $_->schemaSource == $schemaItemSource } ) if $domNode; | 69 my @nodesData = $domNode->selectNodes(sub { $_->schemaSource == $schemaItemSource } ) if $domNode; |
70 | 70 |
71 push @nodesData, undef unless @nodesData; | 71 push @nodesData, undef unless @nodesData; |
72 | 72 |
73 if ($schemaItem->isa(typeof IMPL::DOM::Schema::ComplexNode) ) { | 73 if ($schemaItem->isa(typeof IMPL::DOM::Schema::ComplexNode) ) { |
74 $this->appendChild( $this->buildContainer($schemaItemSource,$schemaItem,$_,undef,$path) ) foreach @nodesData; | 74 $this->appendChild( $this->buildContainer($schemaItemSource,$schemaItem,$_,undef,$path) ) foreach @nodesData; |
75 } elsif ($schemaItem->isa(typeof IMPL::DOM::Schema::SimpleNode)) { | 75 } elsif ($schemaItem->isa(typeof IMPL::DOM::Schema::SimpleNode)) { |
76 $this->appendChild( $this->buildControl($schemaItemSource,$schemaItem,$_,$path) ) foreach @nodesData; | 76 $this->appendChild( $this->buildControl($schemaItemSource,$schemaItem,$_,$path) ) foreach @nodesData; |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 return $container; | 80 return $container; |
81 } | 81 } |
82 | 82 |
83 sub buildControl { | 83 sub buildControl { |
84 my ($this,$schemaSource,$schema,$node,$path) = @_; | 84 my ($this,$schemaSource,$schema,$node,$path) = @_; |
85 | 85 |
86 my @errors; | 86 my @errors; |
87 | 87 |
88 if ($node) { | 88 if ($node) { |
89 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors}; | 89 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors}; |
90 } else { | 90 } else { |
91 @errors = grep $_->Schema == $schemaSource, @{$this->errors}; | 91 @errors = grep $_->Schema == $schemaSource, @{$this->errors}; |
92 } | 92 } |
93 | 93 |
94 return $this->document->CreateControl( | 94 return $this->document->CreateControl( |
95 $schemaSource->name, | 95 $schemaSource->name, |
96 $this->mapType($schemaSource), | 96 $this->mapType($schemaSource), |
97 { | 97 { |
98 schema => $schema, | 98 schema => $schema, |
99 sourceSchema => $schemaSource, | 99 sourceSchema => $schemaSource, |
100 errors => \@errors, | 100 errors => \@errors, |
101 data => $node, | 101 data => $node, |
102 inputType => $schemaSource->nodeProperty('inputType') || $schema->nodeProperty('inputType'), | 102 inputType => $schemaSource->nodeProperty('inputType') || $schema->nodeProperty('inputType'), |
103 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through | 103 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through |
104 queryParameter => $this->makeParameterName([@$path,{ node => $node, schemaSource => $schemaSource}]) | 104 queryParameter => $this->makeParameterName([@$path,{ node => $node, schemaSource => $schemaSource}]) |
105 } | 105 } |
106 ); | 106 ); |
107 } | 107 } |
108 | 108 |
109 sub mapType { | 109 sub mapType { |
110 my ($this,$schema) = @_; | 110 my ($this,$schema) = @_; |
111 | 111 |
112 $schema->nodeProperty('control') || | 112 $schema->nodeProperty('control') || |
113 ( $schema->type && $this->schema->resolveType($schema->type)->nodeProperty('control') ) | 113 ( $schema->type && $this->schema->resolveType($schema->type)->nodeProperty('control') ) |
114 or die new IMPL::Exception("Unable to get control class for the form element",$schema->path); | 114 or die new IMPL::Exception("Unable to get control class for the form element",$schema->path); |
115 } | 115 } |
116 | 116 |
117 sub makeParameterName { | 117 sub makeParameterName { |
118 my ($this,$path) = @_; | 118 my ($this,$path) = @_; |
119 | 119 |
120 join '/', map { | 120 join '/', map { |
121 $_->{node} ? | 121 $_->{node} ? |
122 ( | 122 ( |
123 $_->{node}->nodeProperty('instanceId') ? | 123 $_->{node}->nodeProperty('instanceId') ? |
124 $_->{node}->nodeName . '['. ']' : | 124 $_->{node}->nodeName . '['. ']' : |
125 $_->{node}->nodeName | 125 $_->{node}->nodeName |
126 ) : | 126 ) : |
127 ( | 127 ( |
128 $_->{schemaSource}->maxOccur eq 'unbounded' || $_->{schemaSource}->maxOccur > 1 ? | 128 $_->{schemaSource}->maxOccur eq 'unbounded' || $_->{schemaSource}->maxOccur > 1 ? |
129 $_->{schemaSource}->name . '[0]' : | 129 $_->{schemaSource}->name . '[0]' : |
130 $_->{schemaSource}->name | 130 $_->{schemaSource}->name |
131 ) | 131 ) |
132 } @$path; | 132 } @$path; |
133 } | 133 } |
134 | 134 |
135 sub makeControlArgs{ | 135 sub makeControlArgs{ |
136 my ($this,$path) = @_; | 136 my ($this,$path) = @_; |
137 | 137 |
138 my $navi = new IMPL::DOM::Navigator::SchemaNavigator($this->schema); | 138 my $navi = new IMPL::DOM::Navigator::SchemaNavigator($this->schema); |
139 my @path = ($this->base, split(/\./,$path) ); | 139 my @path = ($this->base, split(/\./,$path) ); |
140 | 140 |
141 $navi->NavigateName($_) or die new IMPL::InvalidArgumentException( | 141 $navi->NavigateName($_) or die new IMPL::InvalidArgumentException( |
142 "Can't find a definition for an element", | 142 "Can't find a definition for an element", |
143 $_, | 143 $_, |
144 $path, | 144 $path, |
145 $this->element, | 145 $this->element, |
146 ) foreach @path; | 146 ) foreach @path; |
147 | 147 |
148 my $schema = $navi->Current; | 148 my $schema = $navi->Current; |
149 my $sourceSchema = $navi->SourceSchemaNode; | 149 my $sourceSchema = $navi->SourceSchemaNode; |
150 my $queryParameter = join '/', @path; | 150 my $queryParameter = join '/', @path; |
151 shift @path; | 151 shift @path; |
152 my $node = $this->data ? $this->data->selectSingleNode(@path) : undef; | 152 my $node = $this->data ? $this->data->selectSingleNode(@path) : undef; |
153 | 153 |
154 my @errors; | 154 my @errors; |
155 | 155 |
156 if ($node) { | 156 if ($node) { |
157 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors}; | 157 @errors = grep { ($_->Node || $_->Parent) == $node } @{$this->errors}; |
158 } else { | 158 } else { |
159 @errors = grep $_->Schema == $sourceSchema, @{$this->errors}; | 159 @errors = grep $_->Schema == $sourceSchema, @{$this->errors}; |
160 } | 160 } |
161 | 161 |
162 return { | 162 return { |
163 schema => $schema, | 163 schema => $schema, |
164 sourceSchema => $sourceSchema, | 164 sourceSchema => $sourceSchema, |
165 errors => \@errors, | 165 errors => \@errors, |
166 data => $node, | 166 data => $node, |
167 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through | 167 nodeValue => $node && $node->nodeValue, # small hack set a non dom class property through |
168 queryParameter => $queryParameter, | 168 queryParameter => $queryParameter, |
169 inputType => $sourceSchema->nodeProperty('inputType') || $schema->nodeProperty('inputType') | 169 inputType => $sourceSchema->nodeProperty('inputType') || $schema->nodeProperty('inputType') |
170 }; | 170 }; |
171 } | 171 } |
172 | 172 |
173 sub makeContent { | 173 sub makeContent { |
174 my ($this,$mappings) = @_; | 174 my ($this,$mappings) = @_; |
175 | 175 |
176 my $formSchema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base } ) | 176 my $formSchema = $this->schema->selectSingleNode(sub { $_->nodeName eq 'ComplexNode' and $_->name eq $this->base } ) |
177 or die new Exception("Cant find a schema element for the specified form", $this->base); | 177 or die new Exception("Cant find a schema element for the specified form", $this->base); |
178 | 178 |
179 my $doc = $this->document; | 179 my $doc = $this->document; |
180 foreach my $itemSchema ( $formSchema->content->childNodes ) { | 180 foreach my $itemSchema ( $formSchema->content->childNodes ) { |
181 my $itemName = $itemSchema->name; | 181 my $itemName = $itemSchema->name; |
182 if (my $controlClass = $mappings->{$itemName} ) { | 182 if (my $controlClass = $mappings->{$itemName} ) { |
183 my $contorl = $doc->CreateControl($itemName,$controlClass,$this->makeControlArgs($itemName)); | 183 my $contorl = $doc->CreateControl($itemName,$controlClass,$this->makeControlArgs($itemName)); |
184 $this->appendChild($contorl); | 184 $this->appendChild($contorl); |
185 } | 185 } |
186 } | 186 } |
187 return; | 187 return; |
188 } | 188 } |
189 | 189 |
190 sub formErrors { | 190 sub formErrors { |
191 my ($this) = @_; | 191 my ($this) = @_; |
192 | 192 |
193 if (my $node = $this->data ) { | 193 if (my $node = $this->data ) { |
194 return [ | 194 return [ |
195 grep { | 195 grep { |
196 ( $_->Node || $_->Parent) == $node | 196 ( $_->Node || $_->Parent) == $node |
197 } @{$this->errors} | 197 } @{$this->errors} |
198 ]; | 198 ]; |
199 } else { | 199 } else { |
200 return []; | 200 return []; |
201 } | 201 } |
202 } | 202 } |
203 | 203 |
204 1; | 204 1; |
205 __END__ | 205 __END__ |
206 | 206 |