]> err.no Git - sope/blob - sope-appserver/WOExtensions/JSValidatedField.m
updated framework version
[sope] / sope-appserver / WOExtensions / JSValidatedField.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #include <NGObjWeb/WODynamicElement.h>
23
24 @interface JSValidatedField : WODynamicElement
25 {
26   WOAssociation *inputText;
27   WOAssociation *errorMessage;
28   WOAssociation *formName;
29   WOAssociation *fieldSize;
30   WOAssociation *inputIsRequired;
31   WOAssociation *requiredText;
32
33   /* non WO */
34   WOElement     *template;
35   WOAssociation *escapeJS;
36 }
37 @end
38
39 #include <NGObjWeb/NSString+JavaScriptEscaping.h>
40 #include <NGExtensions/NSString+Ext.h>
41 #include "common.h"
42
43 @implementation JSValidatedField
44
45 + (int)version {
46   return [super version] + 0 /* v2 */;
47 }
48 + (void)initialize {
49   NSAssert2([super version] == 2,
50             @"invalid superclass (%@) version %i !",
51             NSStringFromClass([self superclass]), [super version]);
52 }
53
54 - (id)initWithName:(NSString *)_name
55   associations:(NSDictionary *)_config
56   template:(WOElement *)_t
57 {
58   if ((self = [super initWithName:_name associations:_config template:_t])) {
59     self->inputText       = WOExtGetProperty(_config,@"inputText");
60     self->errorMessage    = WOExtGetProperty(_config,@"errorMessage");
61     self->formName        = WOExtGetProperty(_config,@"formName");
62     self->fieldSize       = WOExtGetProperty(_config,@"fieldSize");
63     self->inputIsRequired = WOExtGetProperty(_config,@"inputIsRequired");
64     self->requiredText    = WOExtGetProperty(_config,@"requiredText");
65     self->escapeJS        = WOExtGetProperty(_config,@"escapeJS");
66
67     if (!self->inputText)
68       NSLog(@"WARNING: JSValidatedField: 'inputText' not bound.");
69     if (!self->errorMessage)
70       NSLog(@"WARNING: JSValidatedField: 'errorMessage' not bound, "
71             @"using default.");
72     if (!self->formName)
73       NSLog(@"ERROR: JSValidatedField: 'formName' not bound.");
74
75     self->template = [_t retain];
76   }
77   return self;
78 }
79
80 - (void)dealloc {
81   [self->inputText       release];
82   [self->errorMessage    release];
83   [self->fieldSize       release];
84   [self->inputIsRequired release];
85   [self->requiredText    release];
86   [self->template        release];
87   [self->escapeJS        release];
88   [super dealloc];
89 }
90
91 /* operations */
92
93 - (NSString *)buildJSSaveID:(NSString *)_id {
94   return [_id stringByReplacingString:@"." withString:@"x"];
95 }
96
97 /* processing requests */
98
99 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
100   id       formValue;
101   NSString *elID;
102
103   elID = [self buildJSSaveID:[_ctx elementID]];
104   
105   if ((formValue = [_rq formValueForKey:elID])) {
106     if ([self->inputText isValueSettable])
107       [self->inputText setValue: formValue inComponent:[_ctx component]];
108   }
109
110   [self->template takeValuesFromRequest:_rq inContext:_ctx];
111 }
112
113 - (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
114   return [self->template invokeActionForRequest:_rq inContext:_ctx];
115 }
116
117 /* generating response */
118
119 - (void)appendToResponse:(WOResponse *)_response
120   inContext:(WOContext *)_ctx
121 {
122   NSString    *elID;
123   WOComponent *comp;
124   NSString    *tmp;
125   int         objectsCount;
126   NSString    *terrMesg, *tformName, *tinput, *ttext;
127   NSString    *s;
128
129   comp = [_ctx component];
130   elID = [self buildJSSaveID:[_ctx elementID]];
131
132   terrMesg = (self->errorMessage)
133     ? [self->errorMessage stringValueInComponent:comp]
134     : @"Invalid values.";
135   if (self->escapeJS != nil && [self->escapeJS boolValueInComponent:comp])
136       terrMesg = [terrMesg stringByApplyingJavaScriptEscaping];
137   tformName = [self->formName stringValueInComponent:comp];
138   tinput = ([self->inputIsRequired boolValueInComponent:comp])
139     ? @"true"
140     : @"false";
141   if (self->requiredText) {
142     ttext = [self->requiredText stringValueInComponent:comp];
143     if (self->escapeJS != nil && [self->escapeJS boolValueInComponent:comp])
144       ttext = [ttext stringByApplyingJavaScriptEscaping];
145     ttext = [NSString stringWithFormat:@"\"%@\"", ttext];
146   }
147   else
148       ttext = @"false";
149   
150   /* script */
151   [_response appendContentString:@"<script type=\"text/javascript\">\n<!--\n"];
152
153   if (!((objectsCount =
154          [[_ctx valueForKey:@"JSValidatedFieldCounter"] intValue]))) {
155     objectsCount = 0;
156
157     tmp = @"var JSVFtestedObjects = new Array();\n"
158           @"function JSValidatedFieldCheckValues() {\n"
159           @"  for (var i = 0; i < JSVFtestedObjects.length; i++) {\n"
160           @"    tform  = JSVFtestedObjects[i][\"form\"];\n"
161           @"    tname  = JSVFtestedObjects[i][\"name\"];\n"
162           @"    tinput = JSVFtestedObjects[i][\"inputIsRequired\"];\n"
163           @"    ttext  = JSVFtestedObjects[i][\"requiredText\"];\n"
164           @"    tmesg  = JSVFtestedObjects[i][\"errorMessage\"];\n"
165           @"    obj = document.forms[tform].elements[tname];\n"
166           @"    if (((tinput) && (obj.value == \"\")) || \n"
167           @"        ((ttext)  && (obj.value.indexOf(ttext) == -1))) {\n"
168           @"      alert(tmesg);\n"
169           @"      obj.focus();\n"
170           @"      return false;\n"
171           @"    }\n"
172           @"  }\n"
173           @"  return true;\n"
174           @"}\n";
175
176     [_response appendContentString:tmp];
177   }
178   
179   tmp = @"JSVFtestedObjects[%i] = new Array();\n"
180         @"JSVFtestedObjects[%i][\"name\"]            = \"%@\";\n"
181         @"JSVFtestedObjects[%i][\"form\"]            = \"%@\";\n"
182         @"JSVFtestedObjects[%i][\"inputIsRequired\"] = %@;\n"
183         @"JSVFtestedObjects[%i][\"requiredText\"]    = %@;\n"
184         @"JSVFtestedObjects[%i][\"errorMessage\"]    = \"%@\";\n"
185         @"document.%@.onsubmit = JSValidatedFieldCheckValues;\n";
186   
187   s = [[NSString alloc] initWithFormat:tmp,
188                                               objectsCount,
189                                               objectsCount, elID,
190                                               objectsCount, tformName,
191                                               objectsCount, tinput,
192                                               objectsCount, ttext,
193                                               objectsCount, terrMesg,
194                 tformName];
195   [_response appendContentString:s];
196   [s release];
197   
198   [_ctx takeValue:[NSNumber numberWithInt:(objectsCount + 1)]
199         forKey:@"JSValidatedFieldCounter"];
200   [_response appendContentString:@"\n//-->\n</script>"];
201
202   /* input element */
203   
204   [_response appendContentString:@"<input type=\"text\" name=\""];
205   [_response appendContentString:elID];
206   [_response appendContentString:@"\" value=\""];
207   [_response appendContentHTMLAttributeValue:
208                [self->inputText stringValueInComponent:comp]];
209   [_response appendContentString:@"\""];
210   if (self->fieldSize) {
211     [_response appendContentString:@" size=\""];
212     [_response appendContentString:
213                  [self->fieldSize stringValueInComponent:comp]];
214     [_response appendContentString:@"\""];
215   }
216
217   [_response appendContentString:
218                (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
219 }
220
221 @end /* JSValidatedField */