]> err.no Git - sope/blob - sope-appserver/NGObjWeb/DynamicElements/WOTextField.m
fixed copyrights for 2005
[sope] / sope-appserver / NGObjWeb / DynamicElements / WOTextField.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 "WOInput.h"
23 #include "common.h"
24 #import <Foundation/NSNumberFormatter.h>
25 #import <Foundation/NSDateFormatter.h>
26
27 /*
28   Usage:
29
30     PhoneNumber: WOTextField {
31       size               = 30;
32       formatter          = session.phoneNumberFormatter;
33       formatErrorString  = errorString;
34       formatFailedAction = "handleFormattingError";
35     };
36
37   The textfield calls the -validationFailed:.. method of the associated
38   component if a formatter could not format a value.
39 */
40
41 @interface WOTextField : WOInput
42 {
43   // inherited: name
44   // inherited: value
45   // inherited: disabled
46 @protected
47   WOAssociation *numberformat; // string
48   WOAssociation *dateformat;   // string
49   WOAssociation *formatter;    // WO4
50   
51   // non WO:
52   WOAssociation *size;
53 }
54
55 @end /* WOTextField */
56
57 @interface NSObject(UsedKeyPath)
58 - (NSString *)keyPath;
59 @end
60
61 @implementation WOTextField
62
63 - (id)initWithName:(NSString *)_name
64   associations:(NSDictionary *)_config
65   template:(WOElement *)_root
66 {
67   if ((self = [super initWithName:_name associations:_config template:_root])) {
68     self->size         = OWGetProperty(_config, @"size");
69     self->formatter    = OWGetProperty(_config, @"formatter");
70     self->numberformat = OWGetProperty(_config, @"numberformat");
71     self->dateformat   = OWGetProperty(_config, @"dateformat");
72
73     if (self->formatter == nil) {
74       if ([_config objectForKey:@"formatterClass"]) {
75         id className;
76
77         className = OWGetProperty(_config, @"formatterClass");
78         className = AUTORELEASE(className);
79
80         className = [className valueInComponent:nil];
81         className = NSClassFromString(className);
82         className = [[className alloc] init];
83
84         self->formatter = [WOAssociation associationWithValue:className];
85         self->formatter = RETAIN(self->formatter);
86         RELEASE(className);
87       }
88     }
89
90     // check formats
91     {
92       int num = 0;
93       if (self->formatter)    num++;
94       if (self->numberformat) num++;
95       if (self->dateformat)   num++;
96       if (num > 1)
97         NSLog(@"WARNING: more than one formats specified in element %@", self);
98     }
99   }
100   return self;
101 }
102
103 - (void)dealloc {
104   [self->numberformat release];
105   [self->dateformat   release];
106   [self->formatter    release];
107   [self->size         release];
108   [super dealloc];
109 }
110
111 /* formatter */
112
113 static inline NSFormatter *_getFormatter(WOTextField *self, WOContext *_ctx) {
114   NSFormatter *fmt   = nil;
115   
116   if (self->numberformat) {
117     fmt = [[[NSNumberFormatter alloc] init] autorelease];
118     [(NSNumberFormatter *)fmt setFormat:
119         [self->numberformat valueInComponent:[_ctx component]]];
120   }
121   else if (self->dateformat) {
122     fmt = [[NSDateFormatter alloc]
123                             initWithDateFormat:
124                               [self->dateformat valueInComponent:
125                                                   [_ctx component]]
126                             allowNaturalLanguage:NO];
127     fmt = [fmt autorelease];
128   }
129   else if (self->formatter) {
130     fmt = [self->formatter valueInComponent:[_ctx component]];
131   }
132
133   return fmt;
134 }
135
136 // ******************** responder ********************
137
138 - (id)parseFormValue:(id)_value inContext:(WOContext *)_ctx {
139   NSFormatter *fmt = nil;
140
141   fmt = _getFormatter(self, _ctx);
142   
143   if (fmt) {
144     NSString    *errorText = nil;
145     id          object     = nil;
146
147     //fmt = [self->formatter valueInComponent:[_ctx component]];
148
149     if ([fmt getObjectValue:&object forString:[_value stringValue]
150              errorDescription:&errorText]) {
151
152       return object;
153     }
154     else {
155       NSException *formatException = nil;
156       NSString    *keyPath         = nil;
157       
158       if ([self->value respondsToSelector:@selector(keyPath)])
159         keyPath = [(id)self->value keyPath];
160
161       formatException = [NSException exceptionWithName:@"WOValidationException"
162                                      reason:errorText
163                                      userInfo:nil];
164
165       [[_ctx component] validationFailedWithException:formatException
166                         value:_value
167                         keyPath:keyPath];
168       return nil;
169     }
170   }
171   else
172     return [super parseFormValue:_value inContext:_ctx];
173 }
174
175 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
176   NSFormatter *fmt = nil;
177   id       obj = nil;
178   unsigned s   = 0;
179
180   obj = [self->value valueInComponent:[_ctx component]];
181   s   = [self->size  unsignedIntValueInComponent:[_ctx component]];
182
183   fmt = _getFormatter(self, _ctx);
184   if (fmt) {
185     NSString *formattedObj = nil;
186
187     formattedObj = [fmt editingStringForObjectValue:obj];
188
189 #if 0
190     if (formattedObj == nil) {
191       NSLog(@"WARNING: formatter %@ returned nil string for object %@",
192             fmt, obj);
193     }
194 #endif
195     obj = formattedObj;
196   }
197   
198   WOResponse_AddCString(_response, "<input type=\"text\" name=\"");
199   [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
200   WOResponse_AddCString(_response, "\" value=\"");
201   [_response appendContentHTMLAttributeValue:[obj stringValue]];
202   WOResponse_AddChar(_response, '"');
203   if (s > 0) {
204     WOResponse_AddCString(_response, " size=\"");
205     WOResponse_AddUInt(_response, s);
206     WOResponse_AddChar(_response, '"');
207   }
208   [self appendExtraAttributesToResponse:_response inContext:_ctx];
209   if (self->otherTagString) {
210     WOResponse_AddChar(_response, ' ');
211     WOResponse_AddString(_response,
212                          [self->otherTagString stringValueInComponent:
213                               [_ctx component]]);
214   }
215   WOResponse_AddCString(_response, " />");
216 }
217
218 /* description */
219
220 - (NSString *)associationDescription {
221   NSMutableString *str;
222   
223   str = [NSMutableString stringWithCapacity:128];
224   [str appendString:[super associationDescription]];
225
226   if (self->size)       [str appendFormat:@" size=%@",      self->size];
227   if (self->formatter)  [str appendFormat:@" formatter=%@", self->formatter];
228   if (self->dateformat) [str appendFormat:@" dateformat=%@", self->dateformat];
229   if (self->numberformat)
230     [str appendFormat:@" numberformat=%@", self->numberformat];
231
232   return str;
233 }
234
235 @end /* WOTextField */