2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo 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 OGo 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 OGo; 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;
36 WOAssociation *string; // WO4 => use 'displayString'!
37 WOAssociation *noSelectionString; // WO4
40 WOAssociation *singleSelection; // selection contains an item, not an array
41 WOAssociation *multiple; // multiple selections allowed
44 // TODO: WO 4.5: selectedValues, escapeHTML, selections
49 @implementation WOBrowser
52 return [super version] + 0 /* v2 */;
56 NSAssert2([super version] == 2,
57 @"invalid superclass (%@) version %i !",
58 NSStringFromClass([self superclass]), [super version]);
61 - (id)initWithName:(NSString *)_name
62 associations:(NSDictionary *)_config
63 template:(WOElement *)_c {
65 if ((self = [super initWithName:_name associations:_config template:_c])) {
66 self->list = OWGetProperty(_config, @"list");
67 self->item = OWGetProperty(_config, @"item");
68 self->selection = OWGetProperty(_config, @"selection");
69 self->singleSelection = OWGetProperty(_config, @"singleSelection");
70 self->multiple = OWGetProperty(_config, @"multiple");
71 self->size = OWGetProperty(_config, @"size");
72 self->noSelectionString = OWGetProperty(_config, @"noSelectionString");
74 if ((self->string = OWGetProperty(_config, @"displayString")) == nil) {
75 if ((self->string = OWGetProperty(_config, @"string")) != nil) {
76 [self debugWithFormat:
77 @"Note: using deprecated 'string' binding, "
78 @"use 'displayString' instead."];
81 else if (OWGetProperty(_config, @"string") != nil) {
82 [self debugWithFormat:@"WARNING: 'displayString' AND 'string' bindings "
83 @"are set, use only one! ('string' is deprecated!)"];
87 if (self->noSelectionString == nil)
88 self->noSelectionString = OWGetProperty(_config, @"nilString");
90 if (self->multiple == nil) {
92 [WOAssociation associationWithValue:[NSNumber numberWithBool:YES]];
93 self->multiple = [self->multiple retain];
100 [self->noSelectionString release];
101 [self->singleSelection release];
102 [self->list release];
103 [self->item release];
104 [self->selection release];
105 [self->string release];
106 [self->size release];
107 [self->multiple release];
111 /* handling request */
113 - (void)_takeSingleFormValue:(id)formValue fromRequest:(WORequest *)_request
114 inContext:(WOContext *)_ctx
116 WOComponent *sComponent;
120 sComponent = [_ctx component];
121 objects = [self->list valueInComponent:sComponent];
123 if ([[formValue stringValue] isEqualToString:@"$"])
124 object = nil; // nil item selected
129 if ((idx = [formValue intValue]) >= 0) {
130 if (idx < (int)[objects count])
131 object = [objects objectAtIndex:idx];
133 [sComponent logWithFormat:
134 @"WOBrowser got invalid index '%i' (formvalue='%@') "
135 @"for list with count %i !",
136 idx, formValue, [objects count]];
140 [sComponent logWithFormat:@"WOBrowser got invalid index '%i' !", idx];
143 if ([self->selection isValueSettable]) {
146 if ([self->item isValueSettable])
147 [self->item setValue:object inComponent:sComponent];
150 sel = [self->singleSelection boolValueInComponent:sComponent]
152 : [[NSArray alloc] initWithObjects:object,nil];
154 else // nil item selected
157 [self->selection setValue:sel inComponent:sComponent];
158 [sel release]; sel = nil;
162 - (void)_takeMultiFormValue:(NSArray *)formValue fromRequest:(WORequest *)_rq
163 inContext:(WOContext *)_ctx
165 WOComponent *sComponent;
166 NSEnumerator *values;
171 values = [formValue objectEnumerator];
172 sComponent = [_ctx component];
173 objects = [self->list valueInComponent:sComponent];
175 if ([self->selection isValueSettable]) {
179 sel = [[NSMutableArray alloc] initWithCapacity:[formValue count]];
180 objCount = [objects count];
182 while ((v = [values nextObject])) {
186 if ((idx = [v intValue]) >= 0) {
187 if (idx < (int)objCount)
188 object = [objects objectAtIndex:idx];
190 [sComponent logWithFormat:
191 @"WOBrowser got invalid index '%i'(formValue='%@' "
192 @"for list with count %i !",
196 if ([self->item isValueSettable])
197 [self->item setValue:object inComponent:sComponent];
200 [sComponent logWithFormat:@"WOBrowser got invalid index '%i' !",
204 if (object) [sel addObject:object];
207 if ([self->singleSelection boolValueInComponent:sComponent]) {
208 if ([sel count] > 1) {
209 NSLog(@"WARNING(%@): "
210 @"using singleSelection with multiple selected values",
213 [self->selection setValue:[sel lastObject] inComponent:sComponent];
216 [self->selection setValue:sel inComponent:sComponent];
217 [sel release]; sel = nil;
221 - (void)takeValuesFromRequest:(WORequest *)_request
222 inContext:(WOContext *)_ctx
224 WOComponent *sComponent;
227 sComponent = [_ctx component];
228 if ([self->disabled boolValueInComponent:sComponent])
231 formValue = [_request formValuesForKey:OWFormElementName(self, _ctx)];
233 [self logWithFormat:@"value=%@ ..", formValue];
236 if ([self->value isValueSettable])
237 // TODO: is this correct?
238 [self->value setValue:formValue inComponent:sComponent];
240 if ([formValue count] == 1) {
241 [self _takeSingleFormValue:[formValue lastObject] fromRequest:_request
244 else if (formValue != nil) {
245 [self _takeMultiFormValue:formValue fromRequest:_request
250 if ([self->item isValueSettable])
251 [self->item setValue:nil inComponent:sComponent];
252 if ([self->selection isValueSettable])
253 [self->selection setValue:nil inComponent:sComponent];
257 - (void)appendOptionsToResponse:(WOResponse *)_response
258 inContext:(WOContext *)_ctx
260 WOComponent *sComponent = [_ctx component];
262 NSString *nilStr = nil;
263 NSArray *array = nil;
268 nilStr = [self->noSelectionString stringValueInComponent:sComponent];
269 isSingle = [self->singleSelection boolValueInComponent:sComponent];
270 array = [self->list valueInComponent:sComponent];
271 selArray = [self->selection valueInComponent:sComponent];
272 toGo = [array count];
275 WOResponse_AddCString(_response, "<option value=\"$\">");
276 WOResponse_AddHtmlString(_response, nilStr);
277 WOResponse_AddCString(_response, "</option>");
280 for (i = 0; i < toGo; i++) {
282 NSString *displayV = nil;
283 id object = [array objectAtIndex:i];
286 if ([self->item isValueSettable])
287 [self->item setValue:object inComponent:sComponent];
291 isSelected = isSingle
292 ? [selArray isEqual:object] : [selArray containsObject:object];
296 ? [self->value stringValueInComponent:sComponent]
297 : [NSString stringWithFormat:@"%i", i];
299 displayV = self->string
300 ? [self->string stringValueInComponent:sComponent]
301 : [object stringValue];
303 if (displayV == nil) displayV = @"";
305 WOResponse_AddCString(_response, "<option value=\"");
306 WOResponse_AddString(_response, v);
307 WOResponse_AddString(_response,
308 isSelected ? @"\" selected=\"selected\">" : @"\">");
309 WOResponse_AddHtmlString(_response, displayV);
310 WOResponse_AddCString(_response, "</option>");
314 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
318 if ([[_ctx request] isFromClientComponent])
321 isMultiple = [self->multiple boolValueInComponent:[_ctx component]];
322 s = [self->size unsignedIntValueInComponent:[_ctx component]];
324 WOResponse_AddCString(_response, "<select name=\"");
325 [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
326 if (self->otherTagString) {
329 os = [self->otherTagString stringValueInComponent:[_ctx component]];
330 WOResponse_AddString(_response, os);
332 WOResponse_AddCString(_response, "\"");
335 WOResponse_AddCString(_response, " size=\"");
336 WOResponse_AddUInt(_response, s);
337 [_response appendContentCharacter:'"'];
341 WOResponse_AddCString(_response, " multiple=\"multiple\"");
343 [self appendExtraAttributesToResponse:_response inContext:_ctx];
344 WOResponse_AddCString(_response, ">\n");
346 [self appendOptionsToResponse:_response inContext:_ctx];
348 WOResponse_AddCString(_response, "</select>");
353 - (NSString *)associationDescription {
354 NSMutableString *str;
356 str = [NSMutableString stringWithCapacity:256];
357 [str appendString:[super associationDescription]];
359 if (self->list) [str appendFormat:@" list=%@", self->list];
360 if (self->item) [str appendFormat:@" item=%@", self->item];
361 if (self->selection) [str appendFormat:@" selection=%@", self->selection];
362 if (self->string) [str appendFormat:@" string=%@", self->string];
363 if (self->noSelectionString)
364 [str appendFormat:@" noselection=%@", self->noSelectionString];
365 if (self->singleSelection)
366 [str appendFormat:@" singleSelection=%@", self->singleSelection];
368 if (self->size) [str appendFormat:@" size=%@", self->size];
369 if (self->multiple) [str appendFormat:@" multiple=%@", self->multiple];