2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
25 @interface WOBrowser : WOInput
27 // WODynamicElement: extraAttributes
28 // WODynamicElement: otherTagString
31 // inherited: disabled
35 WOAssociation *selection; // => use 'selections'!
36 WOAssociation *string; // WO4 => use 'displayString'!
37 WOAssociation *noSelectionString; // WO4
40 WOAssociation *singleSelection; // selection contains an item, not an array
43 WOAssociation *multiple; // multiple selections allowed
46 // TODO: WO 4.5: selectedValues, escapeHTML
51 @implementation WOBrowser
54 return [super version] + 0 /* v2 */;
58 NSAssert2([super version] == 2,
59 @"invalid superclass (%@) version %i !",
60 NSStringFromClass([self superclass]), [super version]);
63 - (id)initWithName:(NSString *)_name
64 associations:(NSDictionary *)_config
65 template:(WOElement *)_c {
67 if ((self = [super initWithName:_name associations:_config template:_c])) {
68 self->list = OWGetProperty(_config, @"list");
69 self->item = OWGetProperty(_config, @"item");
70 self->singleSelection = OWGetProperty(_config, @"singleSelection");
71 self->multiple = OWGetProperty(_config, @"multiple");
72 self->size = OWGetProperty(_config, @"size");
73 self->noSelectionString = OWGetProperty(_config, @"noSelectionString");
75 if ((self->string = OWGetProperty(_config, @"displayString")) == nil) {
76 if ((self->string = OWGetProperty(_config, @"string")) != nil) {
77 [self debugWithFormat:
78 @"Note: using deprecated 'string' binding, "
79 @"use 'displayString' instead."];
82 else if (OWGetProperty(_config, @"string") != nil) {
83 [self debugWithFormat:@"WARNING: 'displayString' AND 'string' bindings "
84 @"are set, use only one! ('string' is deprecated!)"];
87 if ((self->selection = OWGetProperty(_config, @"selections")) == nil) {
88 if ((self->selection = OWGetProperty(_config, @"selection")) == nil) {
89 [self debugWithFormat:
90 @"Note: using deprecated 'selection' binding, "
91 @"use 'selections' instead."];
94 else if (OWGetProperty(_config, @"selection") != nil) {
95 [self debugWithFormat:@"WARNING: 'selections' AND 'selection' bindings "
96 @"are set, use only one! ('selection' is deprecated!)"];
100 if (self->noSelectionString == nil)
101 self->noSelectionString = OWGetProperty(_config, @"nilString");
103 if (self->multiple == nil) {
105 [WOAssociation associationWithValue:[NSNumber numberWithBool:YES]];
106 self->multiple = [self->multiple retain];
113 [self->noSelectionString release];
114 [self->singleSelection release];
115 [self->list release];
116 [self->item release];
117 [self->selection release];
118 [self->string release];
119 [self->size release];
120 [self->multiple release];
124 /* handling request */
126 - (void)_takeSingleFormValue:(id)formValue fromRequest:(WORequest *)_request
127 inContext:(WOContext *)_ctx
129 WOComponent *sComponent;
133 sComponent = [_ctx component];
134 objects = [self->list valueInComponent:sComponent];
136 if ([[formValue stringValue] isEqualToString:@"$"])
137 object = nil; // nil item selected
142 if ((idx = [formValue intValue]) >= 0) {
143 if (idx < (int)[objects count])
144 object = [objects objectAtIndex:idx];
146 [sComponent logWithFormat:
147 @"WOBrowser got invalid index '%i' (formvalue='%@') "
148 @"for list with count %i !",
149 idx, formValue, [objects count]];
153 [sComponent logWithFormat:@"WOBrowser got invalid index '%i' !", idx];
156 if ([self->selection isValueSettable]) {
159 if ([self->item isValueSettable])
160 [self->item setValue:object inComponent:sComponent];
163 sel = [self->singleSelection boolValueInComponent:sComponent]
165 : [[NSArray alloc] initWithObjects:object,nil];
167 else // nil item selected
170 [self->selection setValue:sel inComponent:sComponent];
171 [sel release]; sel = nil;
175 - (void)_takeMultiFormValue:(NSArray *)formValue fromRequest:(WORequest *)_rq
176 inContext:(WOContext *)_ctx
178 WOComponent *sComponent;
179 NSEnumerator *values;
184 values = [formValue objectEnumerator];
185 sComponent = [_ctx component];
186 objects = [self->list valueInComponent:sComponent];
188 if ([self->selection isValueSettable]) {
192 sel = [[NSMutableArray alloc] initWithCapacity:[formValue count]];
193 objCount = [objects count];
195 while ((v = [values nextObject])) {
199 if ((idx = [v intValue]) >= 0) {
200 if (idx < (int)objCount)
201 object = [objects objectAtIndex:idx];
203 [sComponent logWithFormat:
204 @"WOBrowser got invalid index '%i'(formValue='%@' "
205 @"for list with count %i !",
209 if ([self->item isValueSettable])
210 [self->item setValue:object inComponent:sComponent];
213 [sComponent logWithFormat:@"WOBrowser got invalid index '%i' !",
217 if (object) [sel addObject:object];
220 if ([self->singleSelection boolValueInComponent:sComponent]) {
221 if ([sel count] > 1) {
222 NSLog(@"WARNING(%@): "
223 @"using singleSelection with multiple selected values",
226 [self->selection setValue:[sel lastObject] inComponent:sComponent];
229 [self->selection setValue:sel inComponent:sComponent];
230 [sel release]; sel = nil;
234 - (void)takeValuesFromRequest:(WORequest *)_request
235 inContext:(WOContext *)_ctx
237 WOComponent *sComponent;
240 sComponent = [_ctx component];
241 if ([self->disabled boolValueInComponent:sComponent])
244 formValue = [_request formValuesForKey:OWFormElementName(self, _ctx)];
246 [self logWithFormat:@"value=%@ ..", formValue];
249 if ([self->value isValueSettable])
250 // TODO: is this correct?
251 [self->value setValue:formValue inComponent:sComponent];
253 if ([formValue count] == 1) {
254 [self _takeSingleFormValue:[formValue lastObject] fromRequest:_request
257 else if (formValue != nil) {
258 [self _takeMultiFormValue:formValue fromRequest:_request
263 if ([self->item isValueSettable])
264 [self->item setValue:nil inComponent:sComponent];
265 if ([self->selection isValueSettable])
266 [self->selection setValue:nil inComponent:sComponent];
270 - (void)appendOptionsToResponse:(WOResponse *)_response
271 inContext:(WOContext *)_ctx
273 WOComponent *sComponent = [_ctx component];
275 NSString *nilStr = nil;
276 NSArray *array = nil;
281 nilStr = [self->noSelectionString stringValueInComponent:sComponent];
282 isSingle = [self->singleSelection boolValueInComponent:sComponent];
283 array = [self->list valueInComponent:sComponent];
284 selArray = [self->selection valueInComponent:sComponent];
285 toGo = [array count];
288 WOResponse_AddCString(_response, "<option value=\"$\">");
289 WOResponse_AddHtmlString(_response, nilStr);
290 WOResponse_AddCString(_response, "</option>");
293 for (i = 0; i < toGo; i++) {
295 NSString *displayV = nil;
296 id object = [array objectAtIndex:i];
299 if ([self->item isValueSettable])
300 [self->item setValue:object inComponent:sComponent];
304 isSelected = isSingle
305 ? [selArray isEqual:object] : [selArray containsObject:object];
309 ? [self->value stringValueInComponent:sComponent]
310 : [NSString stringWithFormat:@"%i", i];
312 displayV = self->string
313 ? [self->string stringValueInComponent:sComponent]
314 : [object stringValue];
316 if (displayV == nil) displayV = @"";
318 WOResponse_AddCString(_response, "<option value=\"");
319 WOResponse_AddString(_response, v);
320 WOResponse_AddString(_response,
321 isSelected ? @"\" selected=\"selected\">" : @"\">");
322 WOResponse_AddHtmlString(_response, displayV);
323 WOResponse_AddCString(_response, "</option>");
327 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
331 if ([[_ctx request] isFromClientComponent])
334 isMultiple = [self->multiple boolValueInComponent:[_ctx component]];
335 s = [self->size unsignedIntValueInComponent:[_ctx component]];
337 WOResponse_AddCString(_response, "<select name=\"");
338 [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
339 if (self->otherTagString) {
340 WOResponse_AddChar(_response, ' ');
341 WOResponse_AddString(_response,
342 [self->otherTagString stringValueInComponent:
345 WOResponse_AddCString(_response, "\"");
348 WOResponse_AddCString(_response, " size=\"");
349 WOResponse_AddUInt(_response, s);
350 [_response appendContentCharacter:'"'];
354 WOResponse_AddCString(_response, " multiple=\"multiple\"");
356 [self appendExtraAttributesToResponse:_response inContext:_ctx];
357 WOResponse_AddCString(_response, ">\n");
359 [self appendOptionsToResponse:_response inContext:_ctx];
361 WOResponse_AddCString(_response, "</select>");
366 - (NSString *)associationDescription {
367 NSMutableString *str;
369 str = [NSMutableString stringWithCapacity:256];
370 [str appendString:[super associationDescription]];
372 if (self->list) [str appendFormat:@" list=%@", self->list];
373 if (self->item) [str appendFormat:@" item=%@", self->item];
374 if (self->selection) [str appendFormat:@" selection=%@", self->selection];
375 if (self->string) [str appendFormat:@" string=%@", self->string];
376 if (self->noSelectionString)
377 [str appendFormat:@" noselection=%@", self->noSelectionString];
378 if (self->singleSelection)
379 [str appendFormat:@" singleSelection=%@", self->singleSelection];
381 if (self->size) [str appendFormat:@" size=%@", self->size];
382 if (self->multiple) [str appendFormat:@" multiple=%@", self->multiple];