1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Forms;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
28: class FormContainer extends Nette\ComponentContainer implements \ArrayAccess
29: {
30:
31: public $onValidate;
32:
33:
34: protected $currentGroup;
35:
36:
37: protected $valid;
38:
39:
40:
41:
42:
43:
44:
45: 46: 47: 48: 49: 50:
51: public function setDefaults($values, $erase = FALSE)
52: {
53: $form = $this->getForm(FALSE);
54: if (!$form || !$form->isAnchored() || !$form->isSubmitted()) {
55: $this->setValues($values, $erase);
56: }
57: return $this;
58: }
59:
60:
61:
62: 63: 64: 65: 66: 67:
68: public function setValues($values, $erase = FALSE)
69: {
70: if ($values instanceof \Traversable) {
71: $values = iterator_to_array($values);
72:
73: } elseif (!is_array($values)) {
74: throw new \InvalidArgumentException("First parameter must be an array, " . gettype($values) ." given.");
75: }
76:
77: $cursor = & $values;
78: $iterator = $this->getComponents(TRUE);
79: foreach ($iterator as $name => $control) {
80: $sub = $iterator->getSubIterator();
81: if (!isset($sub->cursor)) {
82: $sub->cursor = & $cursor;
83: }
84: if ($control instanceof IFormControl) {
85: if ((is_array($sub->cursor) || $sub->cursor instanceof \ArrayAccess) && array_key_exists($name, $sub->cursor)) {
86: $control->setValue($sub->cursor[$name]);
87:
88: } elseif ($erase) {
89: $control->setValue(NULL);
90: }
91: }
92: if ($control instanceof FormContainer) {
93: if ((is_array($sub->cursor) || $sub->cursor instanceof \ArrayAccess) && isset($sub->cursor[$name])) {
94: $cursor = & $sub->cursor[$name];
95: } else {
96: unset($cursor);
97: $cursor = NULL;
98: }
99: }
100: }
101: return $this;
102: }
103:
104:
105:
106: 107: 108: 109:
110: public function getValues()
111: {
112: $values = new Nette\ArrayHash;
113: $cursor = $values;
114: $iterator = $this->getComponents(TRUE);
115: foreach ($iterator as $name => $control) {
116: $sub = $iterator->getSubIterator();
117: if (!isset($sub->cursor)) {
118: $sub->cursor = $cursor;
119: }
120: if ($control instanceof IFormControl && !$control->isDisabled() && !$control instanceof ISubmitterControl) {
121: $sub->cursor->$name = $control->getValue();
122: }
123: if ($control instanceof FormContainer) {
124: $cursor = $sub->cursor->$name = new Nette\ArrayHash;
125: }
126: }
127: return $values;
128: }
129:
130:
131:
132:
133:
134:
135:
136: 137: 138: 139:
140: public function isValid()
141: {
142: if ($this->valid === NULL) {
143: $this->validate();
144: }
145: return $this->valid;
146: }
147:
148:
149:
150: 151: 152: 153:
154: public function validate()
155: {
156: $this->valid = TRUE;
157: $this->onValidate($this);
158: foreach ($this->getControls() as $control) {
159: if (!$control->getRules()->validate()) {
160: $this->valid = FALSE;
161: }
162: }
163: }
164:
165:
166:
167:
168:
169:
170:
171: 172: 173: 174:
175: public function setCurrentGroup(FormGroup $group = NULL)
176: {
177: $this->currentGroup = $group;
178: return $this;
179: }
180:
181:
182:
183: 184: 185: 186:
187: public function getCurrentGroup()
188: {
189: return $this->currentGroup;
190: }
191:
192:
193:
194: 195: 196: 197: 198: 199: 200: 201:
202: public function addComponent(Nette\IComponent $component, $name, $insertBefore = NULL)
203: {
204: parent::addComponent($component, $name, $insertBefore);
205: if ($this->currentGroup !== NULL && $component instanceof IFormControl) {
206: $this->currentGroup->add($component);
207: }
208: }
209:
210:
211:
212: 213: 214: 215:
216: public function getControls()
217: {
218: return $this->getComponents(TRUE, 'Nette\Forms\IFormControl');
219: }
220:
221:
222:
223: 224: 225: 226: 227:
228: public function getForm($need = TRUE)
229: {
230: return $this->lookup('Nette\Forms\Form', $need);
231: }
232:
233:
234:
235:
236:
237:
238:
239: 240: 241: 242: 243: 244: 245: 246:
247: public function addText($name, $label = NULL, $cols = NULL, $maxLength = NULL)
248: {
249: return $this[$name] = new TextInput($label, $cols, $maxLength);
250: }
251:
252:
253:
254: 255: 256: 257: 258: 259: 260: 261:
262: public function addPassword($name, $label = NULL, $cols = NULL, $maxLength = NULL)
263: {
264: $control = new TextInput($label, $cols, $maxLength);
265: $control->setType('password');
266: return $this[$name] = $control;
267: }
268:
269:
270:
271: 272: 273: 274: 275: 276: 277: 278:
279: public function addTextArea($name, $label = NULL, $cols = 40, $rows = 10)
280: {
281: return $this[$name] = new TextArea($label, $cols, $rows);
282: }
283:
284:
285:
286: 287: 288: 289: 290: 291:
292: public function addFile($name, $label = NULL)
293: {
294: return $this[$name] = new FileUpload($label);
295: }
296:
297:
298:
299: 300: 301: 302: 303: 304:
305: public function addHidden($name, $default = NULL)
306: {
307: $control = new HiddenField;
308: $control->setDefaultValue($default);
309: return $this[$name] = $control;
310: }
311:
312:
313:
314: 315: 316: 317: 318: 319:
320: public function addCheckbox($name, $caption = NULL)
321: {
322: return $this[$name] = new Checkbox($caption);
323: }
324:
325:
326:
327: 328: 329: 330: 331: 332: 333:
334: public function addRadioList($name, $label = NULL, array $items = NULL)
335: {
336: return $this[$name] = new RadioList($label, $items);
337: }
338:
339:
340:
341: 342: 343: 344: 345: 346: 347: 348:
349: public function addSelect($name, $label = NULL, array $items = NULL, $size = NULL)
350: {
351: return $this[$name] = new SelectBox($label, $items, $size);
352: }
353:
354:
355:
356: 357: 358: 359: 360: 361: 362: 363:
364: public function addMultiSelect($name, $label = NULL, array $items = NULL, $size = NULL)
365: {
366: return $this[$name] = new MultiSelectBox($label, $items, $size);
367: }
368:
369:
370:
371: 372: 373: 374: 375: 376:
377: public function addSubmit($name, $caption = NULL)
378: {
379: return $this[$name] = new SubmitButton($caption);
380: }
381:
382:
383:
384: 385: 386: 387: 388: 389:
390: public function addButton($name, $caption)
391: {
392: return $this[$name] = new Button($caption);
393: }
394:
395:
396:
397: 398: 399: 400: 401: 402: 403:
404: public function addImage($name, $src = NULL, $alt = NULL)
405: {
406: return $this[$name] = new ImageButton($src, $alt);
407: }
408:
409:
410:
411: 412: 413: 414: 415:
416: public function addContainer($name)
417: {
418: $control = new FormContainer;
419: $control->currentGroup = $this->currentGroup;
420: return $this[$name] = $control;
421: }
422:
423:
424:
425:
426:
427:
428:
429: 430: 431: 432: 433: 434:
435: final public function offsetSet($name, $component)
436: {
437: $this->addComponent($component, $name);
438: }
439:
440:
441:
442: 443: 444: 445: 446: 447:
448: final public function offsetGet($name)
449: {
450: return $this->getComponent($name, TRUE);
451: }
452:
453:
454:
455: 456: 457: 458: 459:
460: final public function offsetExists($name)
461: {
462: return $this->getComponent($name, FALSE) !== NULL;
463: }
464:
465:
466:
467: 468: 469: 470: 471:
472: final public function offsetUnset($name)
473: {
474: $component = $this->getComponent($name, FALSE);
475: if ($component !== NULL) {
476: $this->removeComponent($component);
477: }
478: }
479:
480:
481:
482: 483: 484:
485: final public function __clone()
486: {
487: throw new \NotImplementedException('Form cloning is not supported yet.');
488: }
489:
490: }
491: