]> err.no Git - sope/blob - sope-appserver/NGObjWeb/DynamicElements/WOTextField.m
added some WebDrive WebDAV properties
[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 "decommon.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 *)_t
66 {
67   if ((self = [super initWithName:_name associations:_config template:_t])) {
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") autorelease];
78         className = [className valueInComponent:nil];
79         className = NSClassFromString(className);
80         className = [[className alloc] init];
81
82         self->formatter = 
83           [[WOAssociation associationWithValue:className] retain];
84         [className release];
85       }
86     }
87
88     // check formats
89     {
90       int num = 0;
91       if (self->formatter)    num++;
92       if (self->numberformat) num++;
93       if (self->dateformat)   num++;
94       if (num > 1)
95         NSLog(@"WARNING: more than one formats specified in element %@", self);
96     }
97   }
98   return self;
99 }
100
101 - (void)dealloc {
102   [self->numberformat release];
103   [self->dateformat   release];
104   [self->formatter    release];
105   [self->size         release];
106   [super dealloc];
107 }
108
109 /* formatter */
110
111 static inline NSFormatter *_getFormatter(WOTextField *self, WOContext *_ctx) {
112   // TODO: a DUP to WOText?
113   NSFormatter *fmt = nil;
114   
115   if (self->numberformat != nil) {
116     fmt = [[[NSNumberFormatter alloc] init] autorelease];
117     [(NSNumberFormatter *)fmt setFormat:
118         [self->numberformat valueInComponent:[_ctx component]]];
119   }
120   else if (self->dateformat != nil) {
121     fmt = [[NSDateFormatter alloc]
122                             initWithDateFormat:
123                               [self->dateformat valueInComponent:
124                                                   [_ctx component]]
125                             allowNaturalLanguage:NO];
126     fmt = [fmt autorelease];
127   }
128   else if (self->formatter != nil) {
129     fmt = [self->formatter valueInComponent:[_ctx component]];
130   }
131
132   return fmt;
133 }
134
135 /* handle requests */
136
137 - (id)parseFormValue:(id)_value inContext:(WOContext *)_ctx {
138   // TODO: a DUP to WOText?
139   NSException *formatException = nil;
140   NSString    *keyPath         = nil;
141   NSFormatter *fmt;
142   NSString    *errorText = nil;
143   id          object     = nil;
144
145   if ((fmt = _getFormatter(self, _ctx)) == nil)
146     return [super parseFormValue:_value inContext:_ctx];
147   
148   //fmt = [self->formatter valueInComponent:[_ctx component]];
149
150   if ([fmt getObjectValue:&object forString:[_value stringValue]
151              errorDescription:&errorText]) {
152
153     return object;
154   }
155
156   if ([self->value respondsToSelector:@selector(keyPath)])
157     keyPath = [(id)self->value keyPath];
158
159   formatException = [NSException exceptionWithName:@"WOValidationException"
160                                  reason:errorText
161                                  userInfo:nil];
162
163   [[_ctx component] validationFailedWithException:formatException
164                     value:_value
165                     keyPath:keyPath];
166   return nil;
167 }
168
169 /* generate response */
170
171 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
172   NSFormatter *fmt;
173   id       obj;
174   unsigned s;
175
176   obj = [self->value valueInComponent:[_ctx component]];
177   s   = [self->size  unsignedIntValueInComponent:[_ctx component]];
178
179   if ((fmt = _getFormatter(self, _ctx)) != nil) {
180     NSString *formattedObj;
181
182     formattedObj = [fmt editingStringForObjectValue:obj];
183
184 #if 0
185     if (formattedObj == nil) {
186       NSLog(@"WARNING: formatter %@ returned nil string for object %@",
187             fmt, obj);
188     }
189 #endif
190     obj = formattedObj;
191   }
192   
193   WOResponse_AddCString(_response, "<input type=\"text\" name=\"");
194   [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
195   WOResponse_AddCString(_response, "\" value=\"");
196   [_response appendContentHTMLAttributeValue:[obj stringValue]];
197   WOResponse_AddChar(_response, '"');
198   if (s > 0) {
199     WOResponse_AddCString(_response, " size=\"");
200     WOResponse_AddUInt(_response, s);
201     WOResponse_AddChar(_response, '"');
202   }
203
204   if (self->disabled != nil) {
205     if ([self->disabled boolValueInComponent:[_ctx component]])
206       WOResponse_AddCString(_response, " disabled=\"disabled\"");
207   }
208   
209   [self appendExtraAttributesToResponse:_response inContext:_ctx];
210   if (self->otherTagString) {
211     WOResponse_AddChar(_response, ' ');
212     WOResponse_AddString(_response,
213                          [self->otherTagString stringValueInComponent:
214                               [_ctx component]]);
215   }
216   WOResponse_AddEmptyCloseParens(_response, _ctx);
217 }
218
219 /* description */
220
221 - (NSString *)associationDescription {
222   NSMutableString *str;
223   
224   str = [NSMutableString stringWithCapacity:128];
225   [str appendString:[super associationDescription]];
226
227   if (self->size)       [str appendFormat:@" size=%@",      self->size];
228   if (self->formatter)  [str appendFormat:@" formatter=%@", self->formatter];
229   if (self->dateformat) [str appendFormat:@" dateformat=%@", self->dateformat];
230   if (self->numberformat)
231     [str appendFormat:@" numberformat=%@", self->numberformat];
232
233   return str;
234 }
235
236 @end /* WOTextField */