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
22 #include <NGObjWeb/WODynamicElement.h>
24 @interface WOCheckBoxMatrix : WODynamicElement
26 // WODynamicElement: extraAttributes (are appended at the main table)
27 // WODynamicElement: otherTagString
29 WOAssociation *list; // array of objects to iterate through
30 WOAssociation *item; // current item in the array
31 WOAssociation *selections; // selected objects
32 WOAssociation *maxColumns; // number of columns
34 /* non WO attribute */
35 WOAssociation *index; // current index
36 WOAssociation *col; // current column (is updated with each iteration)
37 WOAssociation *row; // current row (is updated with each iteration)
39 WOAssociation *cellAlign; // current cell align
40 WOAssociation *cellVAlign; // current cell valign
41 WOAssociation *rowBackgroundColor; // current row background color;
42 WOAssociation *cellBackgroundColor; // current cell background color;
43 WOAssociation *horizontal; // order items horizontal (default = NO)
51 @implementation WOCheckBoxMatrix
53 static NSString *retStrForInt(int i) {
65 case 10: return @"10";
66 // TODO: find useful count!
68 return [[NSString alloc] initWithFormat:@"%i", i];
72 - (id)initWithName:(NSString *)_name
73 associations:(NSDictionary *)_config
74 template:(WOElement *)_c
76 if ((self = [super initWithName:_name associations:_config template:_c])) {
77 self->list = WOExtGetProperty(_config, @"list");
78 self->item = WOExtGetProperty(_config, @"item");
79 self->selections = WOExtGetProperty(_config, @"selections");
80 self->maxColumns = WOExtGetProperty(_config, @"maxColumns");
82 self->index = WOExtGetProperty(_config, @"index");
83 self->col = WOExtGetProperty(_config, @"col");
84 self->row = WOExtGetProperty(_config, @"row");
85 self->horizontal = WOExtGetProperty(_config, @"horizontal");
87 self->cellAlign = WOExtGetProperty(_config, @"cellAlign");
88 self->cellVAlign = WOExtGetProperty(_config, @"cellVAlign");
89 self->rowBackgroundColor =
90 WOExtGetProperty(_config, @"rowBackgroundColor");
91 self->cellBackgroundColor =
92 WOExtGetProperty(_config, @"cellBackgroundColor");
94 self->template = RETAIN(_c);
100 RELEASE(self->template);
104 RELEASE(self->maxColumns);
105 RELEASE(self->selections);
107 RELEASE(self->index);
110 RELEASE(self->horizontal);
112 RELEASE(self->cellAlign);
113 RELEASE(self->cellVAlign);
114 RELEASE(self->rowBackgroundColor);
115 RELEASE(self->cellBackgroundColor);
119 /* request handling */
122 void _applyIndex(WOCheckBoxMatrix *self, WOComponent *cmp, unsigned _idx)
126 unsigned r, c, cnt, cols;
128 isHor = [self->horizontal boolValueInComponent:cmp];
129 cols = [self->maxColumns unsignedIntValueInComponent:cmp];
130 array = [self->list valueInComponent:cmp];
132 cols = (cols) ? cols : 1;
133 r = (isHor) ? (_idx / cols) + 1 : _idx % ((cnt / cols)+1) + 1;
134 c = (isHor) ? (_idx % cols) + 1 : _idx / ((cnt / cols)+1) + 1;
136 if ([self->index isValueSettable])
137 [self->index setUnsignedIntValue:_idx inComponent:cmp];
139 if ([self->row isValueSettable])
140 [self->row setUnsignedIntValue:r inComponent:cmp];
142 if ([self->col isValueSettable])
143 [self->col setUnsignedIntValue:c inComponent:cmp];
145 if ([self->item isValueSettable]) {
147 [self->item setValue:[array objectAtIndex:_idx] inComponent:cmp];
150 @"WOCheckBoxMatrix: array did change, index is invalid."];
151 [self->item setValue:nil inComponent:cmp];
156 - (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
159 NSArray *selArray = nil;
162 cmp = [_ctx component];
163 array = [self->list valueInComponent:cmp];
167 NSMutableArray *newSelection = nil;
169 if (self->selections)
170 newSelection = [[NSMutableArray alloc] initWithCapacity:cnt];
172 [_ctx appendZeroElementIDComponent];
173 for (i = 0; i < cnt; i++) {
177 _applyIndex(self, cmp, i);
178 [self->template takeValuesFromRequest:_req inContext:_ctx];
180 if ((formValue = [_req formValueForKey:[_ctx elementID]])) {
184 if ([formValue isEqualToString:s]) {
185 if ((obj = [self->item valueInComponent:cmp]) && (newSelection))
186 [newSelection addObject:obj];
190 [_ctx incrementLastElementIDComponent];
192 [_ctx deleteLastElementIDComponent];
194 if (self->selections) {
195 selArray = [newSelection copy];
196 [newSelection release];
200 selArray = [[NSArray alloc] init];
202 if ([self->selections isValueSettable])
203 [self->selections setValue:selArray inComponent:cmp];
208 - (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
214 cmp = [_ctx component];
215 if ([self->list valueInComponent:cmp] == nil)
218 idx = [[_ctx currentElementID] intValue];
219 [_ctx consumeElementID]; // consume index
220 s = retStrForInt(idx);
221 [_ctx appendElementIDComponent:s];
223 _applyIndex(self, cmp, idx);
224 result = [self->template invokeActionForRequest:_req inContext:_ctx];
225 [_ctx deleteLastElementIDComponent];
229 /* generating response */
231 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
235 BOOL isHor; // is horizontal
236 unsigned c, colCount; // column index
237 unsigned r, rowCount; // row index
240 cmp = [_ctx component];
241 colCount = [self->maxColumns unsignedIntValueInComponent:cmp];
242 array = [self->list valueInComponent:cmp];
244 isHor = [self->horizontal boolValueInComponent:cmp];
245 selArray = [self->selections valueInComponent:cmp];
247 colCount = (colCount) ? colCount : 1;
248 rowCount = ((cnt % colCount) > 0) ? (cnt / colCount) + 1 : (cnt / colCount);
250 [_response appendContentString:@"<table "];
251 [self appendExtraAttributesToResponse:_response inContext:_ctx];
252 [_response appendContentCharacter:'>'];
254 for (r = 0; r < rowCount; r++) {
257 rowColor = [self->rowBackgroundColor stringValueInComponent:cmp];
258 [_response appendContentString:@"<tr"];
260 [_response appendContentString:@" bgcolor=\""];
261 [_response appendContentString:rowColor];
262 [_response appendContentCharacter:'"'];
264 [_response appendContentCharacter:'>'];
266 for (c = 0; c < colCount; c++) {
267 NSString *cColor, *align, *valign;
270 cColor = [self->cellBackgroundColor stringValueInComponent:cmp];
271 align = [self->cellAlign stringValueInComponent:cmp];
272 valign = [self->cellVAlign stringValueInComponent:cmp];
273 i = (isHor) ? (r * colCount + c) : (c * rowCount + r);
275 [_response appendContentString:@"<td"];
277 [_response appendContentString:@" bgcolor=\""];
278 [_response appendContentString:cColor];
279 [_response appendContentCharacter:'"'];
282 [_response appendContentString:@" align=\""];
283 [_response appendContentString:align];
284 [_response appendContentCharacter:'"'];
287 [_response appendContentString:@" valign=\""];
288 [_response appendContentString:valign];
289 [_response appendContentCharacter:'"'];
291 [_response appendContentCharacter:'>'];
298 [_ctx appendElementIDComponent:s];
300 _applyIndex(self, cmp, i);
301 obj = [self->item valueInComponent:cmp];
304 [_response appendContentString:@"<input type=\"checkbox\" name=\""];
305 [_response appendContentHTMLAttributeValue:[_ctx elementID]];
306 [_response appendContentString:@"\" value=\""];
308 [_response appendContentString:s];
310 [_response appendContentCharacter:'"'];
312 // TODO: need a ctx flag for empty attributes
313 if ([selArray containsObject:obj])
314 [_response appendContentString:@" checked=\"checked\""];
316 [_response appendContentString:
317 (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
319 /* append template */
320 [self->template appendToResponse:_response inContext:_ctx];
321 [_ctx deleteLastElementIDComponent];
324 [_response appendContentString:@" "]; // TODO: XML/XHTML?
325 [_response appendContentString:@"</td>"];
327 [_response appendContentString:@"</tr>"];
329 [_response appendContentString:@"</table>"];
334 - (NSString *)associationDescription {
335 NSMutableString *str;
337 str = [NSMutableString stringWithCapacity:128];
338 if (self->list) [str appendFormat:@" list=%@", self->list];
339 if (self->item) [str appendFormat:@" item=%@", self->item];
340 if (self->maxColumns) [str appendFormat:@" maxColumns=%@", self->maxColumns];
341 if (self->selections) [str appendFormat:@" selections=%@", self->selections];
342 if (self->index) [str appendFormat:@" index=%@", self->index];
343 if (self->col) [str appendFormat:@" col=%@", self->col];
344 if (self->row) [str appendFormat:@" row=%@", self->row];
345 if (self->horizontal) [str appendFormat:@" horizontal=%@", self->horizontal];
346 if (self->template) [str appendFormat:@" template=%@", self->template];
351 @end /* WOCheckBoxMatrix */