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 = array();
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];
125: $cursor = array();
126: }
127: }
128: return $values;
129: }
130:
131:
132:
133:
134:
135:
136:
137: 138: 139: 140:
141: public function isValid()
142: {
143: if ($this->valid === NULL) {
144: $this->validate();
145: }
146: return $this->valid;
147: }
148:
149:
150:
151: 152: 153: 154:
155: public function validate()
156: {
157: $this->valid = TRUE;
158: $this->onValidate($this);
159: foreach ($this->getControls() as $control) {
160: if (!$control->getRules()->validate()) {
161: $this->valid = FALSE;
162: }
163: }
164: }
165:
166:
167:
168:
169:
170:
171:
172: 173: 174: 175:
176: public function setCurrentGroup(FormGroup $group = NULL)
177: {
178: $this->currentGroup = $group;
179: return $this;
180: }
181:
182:
183:
184: 185: 186: 187:
188: public function getCurrentGroup()
189: {
190: return $this->currentGroup;
191: }
192:
193:
194:
195: 196: 197: 198: 199: 200: 201: 202:
203: public function addComponent(Nette\IComponent $component, $name, $insertBefore = NULL)
204: {
205: parent::addComponent($component, $name, $insertBefore);
206: if ($this->currentGroup !== NULL && $component instanceof IFormControl) {
207: $this->currentGroup->add($component);
208: }
209: }
210:
211:
212:
213: 214: 215: 216:
217: public function getControls()
218: {
219: return $this->getComponents(TRUE, 'Nette\Forms\IFormControl');
220: }
221:
222:
223:
224: 225: 226: 227: 228:
229: public function getForm($need = TRUE)
230: {
231: return $this->lookup('Nette\Forms\Form', $need);
232: }
233:
234:
235:
236:
237:
238:
239:
240: 241: 242: 243: 244: 245: 246: 247:
248: public function addText($name, $label = NULL, $cols = NULL, $maxLength = NULL)
249: {
250: return $this[$name] = new TextInput($label, $cols, $maxLength);
251: }
252:
253:
254:
255: 256: 257: 258: 259: 260: 261: 262:
263: public function addPassword($name, $label = NULL, $cols = NULL, $maxLength = NULL)
264: {
265: $control = new TextInput($label, $cols, $maxLength);
266: $control->setType('password');
267: return $this[$name] = $control;
268: }
269:
270:
271:
272: 273: 274: 275: 276: 277: 278: 279:
280: public function addTextArea($name, $label = NULL, $cols = 40, $rows = 10)
281: {
282: return $this[$name] = new TextArea($label, $cols, $rows);
283: }
284:
285:
286:
287: 288: 289: 290: 291: 292:
293: public function addFile($name, $label = NULL)
294: {
295: return $this[$name] = new FileUpload($label);
296: }
297:
298:
299:
300: 301: 302: 303: 304: 305:
306: public function addHidden($name, $default = NULL)
307: {
308: $control = new HiddenField;
309: $control->setDefaultValue($default);
310: return $this[$name] = $control;
311: }
312:
313:
314:
315: 316: 317: 318: 319: 320:
321: public function addCheckbox($name, $caption = NULL)
322: {
323: return $this[$name] = new Checkbox($caption);
324: }
325:
326:
327:
328: 329: 330: 331: 332: 333: 334:
335: public function addRadioList($name, $label = NULL, array $items = NULL)
336: {
337: return $this[$name] = new RadioList($label, $items);
338: }
339:
340:
341:
342: 343: 344: 345: 346: 347: 348: 349:
350: public function addSelect($name, $label = NULL, array $items = NULL, $size = NULL)
351: {
352: return $this[$name] = new SelectBox($label, $items, $size);
353: }
354:
355:
356:
357: 358: 359: 360: 361: 362: 363: 364:
365: public function addMultiSelect($name, $label = NULL, array $items = NULL, $size = NULL)
366: {
367: return $this[$name] = new MultiSelectBox($label, $items, $size);
368: }
369:
370:
371:
372: 373: 374: 375: 376: 377:
378: public function addSubmit($name, $caption = NULL)
379: {
380: return $this[$name] = new SubmitButton($caption);
381: }
382:
383:
384:
385: 386: 387: 388: 389: 390:
391: public function addButton($name, $caption)
392: {
393: return $this[$name] = new Button($caption);
394: }
395:
396:
397:
398: 399: 400: 401: 402: 403: 404:
405: public function addImage($name, $src = NULL, $alt = NULL)
406: {
407: return $this[$name] = new ImageButton($src, $alt);
408: }
409:
410:
411:
412: 413: 414: 415: 416:
417: public function addContainer($name)
418: {
419: $control = new FormContainer;
420: $control->currentGroup = $this->currentGroup;
421: return $this[$name] = $control;
422: }
423:
424:
425:
426:
427:
428:
429:
430: 431: 432: 433: 434: 435:
436: final public function offsetSet($name, $component)
437: {
438: $this->addComponent($component, $name);
439: }
440:
441:
442:
443: 444: 445: 446: 447: 448:
449: final public function offsetGet($name)
450: {
451: return $this->getComponent($name, TRUE);
452: }
453:
454:
455:
456: 457: 458: 459: 460:
461: final public function offsetExists($name)
462: {
463: return $this->getComponent($name, FALSE) !== NULL;
464: }
465:
466:
467:
468: 469: 470: 471: 472:
473: final public function offsetUnset($name)
474: {
475: $component = $this->getComponent($name, FALSE);
476: if ($component !== NULL) {
477: $this->removeComponent($component);
478: }
479: }
480:
481:
482:
483: 484: 485:
486: final public function __clone()
487: {
488: throw new \NotImplementedException('Form cloning is not supported yet.');
489: }
490:
491: }
492: