Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • Container
  • ControlGroup
  • Form
  • Helpers
  • Rule
  • Rules
  • Validator

Interfaces

  • IControl
  • IFormRenderer
  • ISubmitterControl
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Forms;
  9: 
 10: use Nette;
 11: 
 12: 
 13: /**
 14:  * Container for form controls.
 15:  *
 16:  * @property   Nette\Utils\ArrayHash $values
 17:  * @property-read \ArrayIterator $controls
 18:  * @property-read Form $form
 19:  */
 20: class Container extends Nette\ComponentModel\Container implements \ArrayAccess
 21: {
 22:     /** @var callable[]  function (Container $sender); Occurs when the form is validated */
 23:     public $onValidate;
 24: 
 25:     /** @var ControlGroup */
 26:     protected $currentGroup;
 27: 
 28:     /** @var bool */
 29:     private $validated;
 30: 
 31: 
 32:     /********************* data exchange ****************d*g**/
 33: 
 34: 
 35:     /**
 36:      * Fill-in with default values.
 37:      * @param  array|\Traversable  values used to fill the form
 38:      * @param  bool     erase other default values?
 39:      * @return self
 40:      */
 41:     public function setDefaults($values, $erase = FALSE)
 42:     {
 43:         $form = $this->getForm(FALSE);
 44:         if (!$form || !$form->isAnchored() || !$form->isSubmitted()) {
 45:             $this->setValues($values, $erase);
 46:         }
 47:         return $this;
 48:     }
 49: 
 50: 
 51:     /**
 52:      * Fill-in with values.
 53:      * @param  array|\Traversable  values used to fill the form
 54:      * @param  bool     erase other controls?
 55:      * @return self
 56:      */
 57:     public function setValues($values, $erase = FALSE)
 58:     {
 59:         if ($values instanceof \Traversable) {
 60:             $values = iterator_to_array($values);
 61: 
 62:         } elseif (!is_array($values)) {
 63:             throw new Nette\InvalidArgumentException(sprintf('First parameter must be an array, %s given.', gettype($values)));
 64:         }
 65: 
 66:         foreach ($this->getComponents() as $name => $control) {
 67:             if ($control instanceof IControl) {
 68:                 if (array_key_exists($name, $values)) {
 69:                     $control->setValue($values[$name]);
 70: 
 71:                 } elseif ($erase) {
 72:                     $control->setValue(NULL);
 73:                 }
 74: 
 75:             } elseif ($control instanceof self) {
 76:                 if (array_key_exists($name, $values)) {
 77:                     $control->setValues($values[$name], $erase);
 78: 
 79:                 } elseif ($erase) {
 80:                     $control->setValues(array(), $erase);
 81:                 }
 82:             }
 83:         }
 84:         return $this;
 85:     }
 86: 
 87: 
 88:     /**
 89:      * Returns the values submitted by the form.
 90:      * @param  bool  return values as an array?
 91:      * @return Nette\Utils\ArrayHash|array
 92:      */
 93:     public function getValues($asArray = FALSE)
 94:     {
 95:         $values = $asArray ? array() : new Nette\Utils\ArrayHash;
 96:         foreach ($this->getComponents() as $name => $control) {
 97:             if ($control instanceof IControl && !$control->isOmitted()) {
 98:                 $values[$name] = $control->getValue();
 99: 
100:             } elseif ($control instanceof self) {
101:                 $values[$name] = $control->getValues($asArray);
102:             }
103:         }
104:         return $values;
105:     }
106: 
107: 
108:     /********************* validation ****************d*g**/
109: 
110: 
111:     /**
112:      * Is form valid?
113:      * @return bool
114:      */
115:     public function isValid()
116:     {
117:         if (!$this->validated) {
118:             if ($this->getErrors()) {
119:                 return FALSE;
120:             }
121:             $this->validate();
122:         }
123:         return !$this->getErrors();
124:     }
125: 
126: 
127:     /**
128:      * Performs the server side validation.
129:      * @param  IControl[]
130:      * @return void
131:      */
132:     public function validate(array $controls = NULL)
133:     {
134:         foreach ($controls === NULL ? $this->getComponents() : $controls as $control) {
135:             $control->validate();
136:         }
137:         if ($this->onValidate !== NULL) {
138:             if (!is_array($this->onValidate) && !$this->onValidate instanceof \Traversable) {
139:                 throw new Nette\UnexpectedValueException('Property Form::$onValidate must be array or Traversable, ' . gettype($this->onValidate) . ' given.');
140:             }
141:             foreach ($this->onValidate as $handler) {
142:                 $params = Nette\Utils\Callback::toReflection($handler)->getParameters();
143:                 $values = isset($params[1]) ? $this->getValues($params[1]->isArray()) : NULL;
144:                 Nette\Utils\Callback::invoke($handler, $this, $values);
145:             }
146:         }
147:         $this->validated = TRUE;
148:     }
149: 
150: 
151:     /**
152:      * Returns all validation errors.
153:      * @return array
154:      */
155:     public function getErrors()
156:     {
157:         $errors = array();
158:         foreach ($this->getControls() as $control) {
159:             $errors = array_merge($errors, $control->getErrors());
160:         }
161:         return array_unique($errors);
162:     }
163: 
164: 
165:     /********************* form building ****************d*g**/
166: 
167: 
168:     /**
169:      * @return self
170:      */
171:     public function setCurrentGroup(ControlGroup $group = NULL)
172:     {
173:         $this->currentGroup = $group;
174:         return $this;
175:     }
176: 
177: 
178:     /**
179:      * Returns current group.
180:      * @return ControlGroup
181:      */
182:     public function getCurrentGroup()
183:     {
184:         return $this->currentGroup;
185:     }
186: 
187: 
188:     /**
189:      * Adds the specified component to the IContainer.
190:      * @param  Nette\ComponentModel\IComponent
191:      * @param  string
192:      * @param  string
193:      * @return self
194:      * @throws Nette\InvalidStateException
195:      */
196:     public function addComponent(Nette\ComponentModel\IComponent $component, $name, $insertBefore = NULL)
197:     {
198:         parent::addComponent($component, $name, $insertBefore);
199:         if ($this->currentGroup !== NULL && $component instanceof IControl) {
200:             $this->currentGroup->add($component);
201:         }
202:         return $this;
203:     }
204: 
205: 
206:     /**
207:      * Iterates over all form controls.
208:      * @return \ArrayIterator
209:      */
210:     public function getControls()
211:     {
212:         return $this->getComponents(TRUE, 'Nette\Forms\IControl');
213:     }
214: 
215: 
216:     /**
217:      * Returns form.
218:      * @param  bool   throw exception if form doesn't exist?
219:      * @return Form
220:      */
221:     public function getForm($need = TRUE)
222:     {
223:         return $this->lookup('Nette\Forms\Form', $need);
224:     }
225: 
226: 
227:     /********************* control factories ****************d*g**/
228: 
229: 
230:     /**
231:      * Adds single-line text input control to the form.
232:      * @param  string  control name
233:      * @param  string  label
234:      * @param  int  width of the control (deprecated)
235:      * @param  int  maximum number of characters the user may enter
236:      * @return Nette\Forms\Controls\TextInput
237:      */
238:     public function addText($name, $label = NULL, $cols = NULL, $maxLength = NULL)
239:     {
240:         $control = new Controls\TextInput($label, $maxLength);
241:         $control->setAttribute('size', $cols);
242:         return $this[$name] = $control;
243:     }
244: 
245: 
246:     /**
247:      * Adds single-line text input control used for sensitive input such as passwords.
248:      * @param  string  control name
249:      * @param  string  label
250:      * @param  int  width of the control (deprecated)
251:      * @param  int  maximum number of characters the user may enter
252:      * @return Nette\Forms\Controls\TextInput
253:      */
254:     public function addPassword($name, $label = NULL, $cols = NULL, $maxLength = NULL)
255:     {
256:         $control = new Controls\TextInput($label, $maxLength);
257:         $control->setAttribute('size', $cols);
258:         return $this[$name] = $control->setType('password');
259:     }
260: 
261: 
262:     /**
263:      * Adds multi-line text input control to the form.
264:      * @param  string  control name
265:      * @param  string  label
266:      * @param  int  width of the control
267:      * @param  int  height of the control in text lines
268:      * @return Nette\Forms\Controls\TextArea
269:      */
270:     public function addTextArea($name, $label = NULL, $cols = NULL, $rows = NULL)
271:     {
272:         $control = new Controls\TextArea($label);
273:         $control->setAttribute('cols', $cols)->setAttribute('rows', $rows);
274:         return $this[$name] = $control;
275:     }
276: 
277: 
278:     /**
279:      * Adds control that allows the user to upload files.
280:      * @param  string  control name
281:      * @param  string  label
282:      * @param  bool  allows to upload multiple files
283:      * @return Nette\Forms\Controls\UploadControl
284:      */
285:     public function addUpload($name, $label = NULL, $multiple = FALSE)
286:     {
287:         return $this[$name] = new Controls\UploadControl($label, $multiple);
288:     }
289: 
290: 
291:     /**
292:      * Adds control that allows the user to upload multiple files.
293:      * @param  string  control name
294:      * @param  string  label
295:      * @return Nette\Forms\Controls\UploadControl
296:      */
297:     public function addMultiUpload($name, $label = NULL)
298:     {
299:         return $this[$name] = new Controls\UploadControl($label, TRUE);
300:     }
301: 
302: 
303:     /**
304:      * Adds hidden form control used to store a non-displayed value.
305:      * @param  string  control name
306:      * @param  mixed   default value
307:      * @return Nette\Forms\Controls\HiddenField
308:      */
309:     public function addHidden($name, $default = NULL)
310:     {
311:         $control = new Controls\HiddenField;
312:         $control->setDefaultValue($default);
313:         return $this[$name] = $control;
314:     }
315: 
316: 
317:     /**
318:      * Adds check box control to the form.
319:      * @param  string  control name
320:      * @param  string  caption
321:      * @return Nette\Forms\Controls\Checkbox
322:      */
323:     public function addCheckbox($name, $caption = NULL)
324:     {
325:         return $this[$name] = new Controls\Checkbox($caption);
326:     }
327: 
328: 
329:     /**
330:      * Adds set of radio button controls to the form.
331:      * @param  string  control name
332:      * @param  string  label
333:      * @param  array   options from which to choose
334:      * @return Nette\Forms\Controls\RadioList
335:      */
336:     public function addRadioList($name, $label = NULL, array $items = NULL)
337:     {
338:         return $this[$name] = new Controls\RadioList($label, $items);
339:     }
340: 
341: 
342:     /**
343:      * Adds set of checkbox controls to the form.
344:      * @return Nette\Forms\Controls\CheckboxList
345:      */
346:     public function addCheckboxList($name, $label = NULL, array $items = NULL)
347:     {
348:         return $this[$name] = new Controls\CheckboxList($label, $items);
349:     }
350: 
351: 
352:     /**
353:      * Adds select box control that allows single item selection.
354:      * @param  string  control name
355:      * @param  string  label
356:      * @param  array   items from which to choose
357:      * @param  int     number of rows that should be visible
358:      * @return Nette\Forms\Controls\SelectBox
359:      */
360:     public function addSelect($name, $label = NULL, array $items = NULL, $size = NULL)
361:     {
362:         $control = new Controls\SelectBox($label, $items);
363:         if ($size > 1) {
364:             $control->setAttribute('size', (int) $size);
365:         }
366:         return $this[$name] = $control;
367:     }
368: 
369: 
370:     /**
371:      * Adds select box control that allows multiple item selection.
372:      * @param  string  control name
373:      * @param  string  label
374:      * @param  array   options from which to choose
375:      * @param  int     number of rows that should be visible
376:      * @return Nette\Forms\Controls\MultiSelectBox
377:      */
378:     public function addMultiSelect($name, $label = NULL, array $items = NULL, $size = NULL)
379:     {
380:         $control = new Controls\MultiSelectBox($label, $items);
381:         if ($size > 1) {
382:             $control->setAttribute('size', (int) $size);
383:         }
384:         return $this[$name] = $control;
385:     }
386: 
387: 
388:     /**
389:      * Adds button used to submit form.
390:      * @param  string  control name
391:      * @param  string  caption
392:      * @return Nette\Forms\Controls\SubmitButton
393:      */
394:     public function addSubmit($name, $caption = NULL)
395:     {
396:         return $this[$name] = new Controls\SubmitButton($caption);
397:     }
398: 
399: 
400:     /**
401:      * Adds push buttons with no default behavior.
402:      * @param  string  control name
403:      * @param  string  caption
404:      * @return Nette\Forms\Controls\Button
405:      */
406:     public function addButton($name, $caption = NULL)
407:     {
408:         return $this[$name] = new Controls\Button($caption);
409:     }
410: 
411: 
412:     /**
413:      * Adds graphical button used to submit form.
414:      * @param  string  control name
415:      * @param  string  URI of the image
416:      * @param  string  alternate text for the image
417:      * @return Nette\Forms\Controls\ImageButton
418:      */
419:     public function addImage($name, $src = NULL, $alt = NULL)
420:     {
421:         return $this[$name] = new Controls\ImageButton($src, $alt);
422:     }
423: 
424: 
425:     /**
426:      * Adds naming container to the form.
427:      * @param  string  name
428:      * @return Container
429:      */
430:     public function addContainer($name)
431:     {
432:         $control = new self;
433:         $control->currentGroup = $this->currentGroup;
434:         return $this[$name] = $control;
435:     }
436: 
437: 
438:     /********************* interface \ArrayAccess ****************d*g**/
439: 
440: 
441:     /**
442:      * Adds the component to the container.
443:      * @param  string  component name
444:      * @param  Nette\ComponentModel\IComponent
445:      * @return void
446:      */
447:     public function offsetSet($name, $component)
448:     {
449:         $this->addComponent($component, $name);
450:     }
451: 
452: 
453:     /**
454:      * Returns component specified by name. Throws exception if component doesn't exist.
455:      * @param  string  component name
456:      * @return Nette\ComponentModel\IComponent
457:      * @throws Nette\InvalidArgumentException
458:      */
459:     public function offsetGet($name)
460:     {
461:         return $this->getComponent($name, TRUE);
462:     }
463: 
464: 
465:     /**
466:      * Does component specified by name exists?
467:      * @param  string  component name
468:      * @return bool
469:      */
470:     public function offsetExists($name)
471:     {
472:         return $this->getComponent($name, FALSE) !== NULL;
473:     }
474: 
475: 
476:     /**
477:      * Removes component from the container.
478:      * @param  string  component name
479:      * @return void
480:      */
481:     public function offsetUnset($name)
482:     {
483:         $component = $this->getComponent($name, FALSE);
484:         if ($component !== NULL) {
485:             $this->removeComponent($component);
486:         }
487:     }
488: 
489: 
490:     /**
491:      * Prevents cloning.
492:      */
493:     public function __clone()
494:     {
495:         throw new Nette\NotImplementedException('Form cloning is not supported yet.');
496:     }
497: 
498: }
499: 
Nette 2.3.8 API API documentation generated by ApiGen 2.8.0