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