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