Namespaces

  • Nette
    • Application
    • Caching
    • Collections
    • Config
    • Forms
    • IO
    • Loaders
    • Mail
    • Reflection
    • Security
    • Templates
    • Web
  • None
  • PHP

Classes

  • Button
  • Checkbox
  • ConventionalRenderer
  • FileUpload
  • Form
  • FormContainer
  • FormControl
  • FormGroup
  • HiddenField
  • ImageButton
  • InstantClientScript
  • MultiSelectBox
  • RadioList
  • Rule
  • Rules
  • SelectBox
  • SubmitButton
  • TextArea
  • TextBase
  • TextInput

Interfaces

  • IFormControl
  • IFormRenderer
  • INamingContainer
  • ISubmitterControl
  • Overview
  • Namespace
  • Class
  • Tree
  • Other releases
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  */
 11: 
 12: namespace Nette\Forms;
 13: 
 14: use Nette;
 15: 
 16: 
 17: 
 18: /**
 19:  * Container for form controls.
 20:  *
 21:  * @author     David Grudl
 22:  *
 23:  * @property-read \ArrayIterator $controls
 24:  * @property-read Form $form
 25:  * @property-read bool $valid
 26:  * @property   array $values
 27:  */
 28: class FormContainer extends Nette\ComponentContainer implements \ArrayAccess, INamingContainer
 29: {
 30:     /** @var array of function(Form $sender); Occurs when the form is validated */
 31:     public $onValidate;
 32: 
 33:     /** @var FormGroup */
 34:     protected $currentGroup;
 35: 
 36:     /** @var bool */
 37:     protected $valid;
 38: 
 39: 
 40: 
 41:     /********************* data exchange ****************d*g**/
 42: 
 43: 
 44: 
 45:     /**
 46:      * Fill-in with default values.
 47:      * @param  array|Traversable  values used to fill the form
 48:      * @param  bool     erase other default values?
 49:      * @return FormContainer  provides a fluent interface
 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:      * Fill-in with values.
 64:      * @param  array|Traversable  values used to fill the form
 65:      * @param  bool     erase other controls?
 66:      * @return FormContainer  provides a fluent interface
 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:      * Returns the values submitted by the form.
108:      * @return array
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:     /********************* validation ****************d*g**/
134: 
135: 
136: 
137:     /**
138:      * Is form valid?
139:      * @return bool
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:      * Performs the server side validation.
153:      * @return void
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:     /********************* form building ****************d*g**/
169: 
170: 
171: 
172:     /**
173:      * @param  FormGroup
174:      * @return FormContainer  provides a fluent interface
175:      */
176:     public function setCurrentGroup(FormGroup $group = NULL)
177:     {
178:         $this->currentGroup = $group;
179:         return $this;
180:     }
181: 
182: 
183: 
184:     /**
185:      * Adds the specified component to the IComponentContainer.
186:      * @param  IComponent
187:      * @param  string
188:      * @param  string
189:      * @return void
190:      * @throws \InvalidStateException
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:      * Iterates over all form controls.
204:      * @return \ArrayIterator
205:      */
206:     public function getControls()
207:     {
208:         return $this->getComponents(TRUE, 'Nette\Forms\IFormControl');
209:     }
210: 
211: 
212: 
213:     /**
214:      * Returns form.
215:      * @param  bool   throw exception if form doesn't exist?
216:      * @return Form
217:      */
218:     public function getForm($need = TRUE)
219:     {
220:         return $this->lookup('Nette\Forms\Form', $need);
221:     }
222: 
223: 
224: 
225:     /********************* control factories ****************d*g**/
226: 
227: 
228: 
229:     /**
230:      * Adds single-line text input control to the form.
231:      * @param  string  control name
232:      * @param  string  label
233:      * @param  int  width of the control
234:      * @param  int  maximum number of characters the user may enter
235:      * @return TextInput
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:      * Adds single-line text input control used for sensitive input such as passwords.
246:      * @param  string  control name
247:      * @param  string  label
248:      * @param  int  width of the control
249:      * @param  int  maximum number of characters the user may enter
250:      * @return TextInput
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:      * Adds multi-line text input control to the form.
263:      * @param  string  control name
264:      * @param  string  label
265:      * @param  int  width of the control
266:      * @param  int  height of the control in text lines
267:      * @return TextArea
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:      * Adds control that allows the user to upload files.
278:      * @param  string  control name
279:      * @param  string  label
280:      * @return FileUpload
281:      */
282:     public function addFile($name, $label = NULL)
283:     {
284:         return $this[$name] = new FileUpload($label);
285:     }
286: 
287: 
288: 
289:     /**
290:      * Adds hidden form control used to store a non-displayed value.
291:      * @param  string  control name
292:      * @param  mixed   default value
293:      * @return HiddenField
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:      * Adds check box control to the form.
306:      * @param  string  control name
307:      * @param  string  caption
308:      * @return Checkbox
309:      */
310:     public function addCheckbox($name, $caption = NULL)
311:     {
312:         return $this[$name] = new Checkbox($caption);
313:     }
314: 
315: 
316: 
317:     /**
318:      * Adds set of radio button controls to the form.
319:      * @param  string  control name
320:      * @param  string  label
321:      * @param  array   options from which to choose
322:      * @return RadioList
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:      * Adds select box control that allows single item selection.
333:      * @param  string  control name
334:      * @param  string  label
335:      * @param  array   items from which to choose
336:      * @param  int     number of rows that should be visible
337:      * @return SelectBox
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:      * Adds select box control that allows multiple item selection.
348:      * @param  string  control name
349:      * @param  string  label
350:      * @param  array   options from which to choose
351:      * @param  int     number of rows that should be visible
352:      * @return MultiSelectBox
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:      * Adds button used to submit form.
363:      * @param  string  control name
364:      * @param  string  caption
365:      * @return SubmitButton
366:      */
367:     public function addSubmit($name, $caption = NULL)
368:     {
369:         return $this[$name] = new SubmitButton($caption);
370:     }
371: 
372: 
373: 
374:     /**
375:      * Adds push buttons with no default behavior.
376:      * @param  string  control name
377:      * @param  string  caption
378:      * @return Button
379:      */
380:     public function addButton($name, $caption)
381:     {
382:         return $this[$name] = new Button($caption);
383:     }
384: 
385: 
386: 
387:     /**
388:      * Adds graphical button used to submit form.
389:      * @param  string  control name
390:      * @param  string  URI of the image
391:      * @param  string  alternate text for the image
392:      * @return ImageButton
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:      * Adds naming container to the form.
403:      * @param  string  name
404:      * @return FormContainer
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:     /********************* interface \ArrayAccess ****************d*g**/
416: 
417: 
418: 
419:     /**
420:      * Adds the component to the container.
421:      * @param  string  component name
422:      * @param  Nette\IComponent
423:      * @return void
424:      */
425:     final public function offsetSet($name, $component)
426:     {
427:         $this->addComponent($component, $name);
428:     }
429: 
430: 
431: 
432:     /**
433:      * Returns component specified by name. Throws exception if component doesn't exist.
434:      * @param  string  component name
435:      * @return Nette\IComponent
436:      * @throws \InvalidArgumentException
437:      */
438:     final public function offsetGet($name)
439:     {
440:         return $this->getComponent($name, TRUE);
441:     }
442: 
443: 
444: 
445:     /**
446:      * Does component specified by name exists?
447:      * @param  string  component name
448:      * @return bool
449:      */
450:     final public function offsetExists($name)
451:     {
452:         return $this->getComponent($name, FALSE) !== NULL;
453:     }
454: 
455: 
456: 
457:     /**
458:      * Removes component from the container.
459:      * @param  string  component name
460:      * @return void
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:      * Prevents cloning.
474:      */
475:     final public function __clone()
476:     {
477:         throw new \NotImplementedException('Form cloning is not supported yet.');
478:     }
479: 
480: }
481: 
Nette Framework 0.9.7 API documentation generated by ApiGen 2.3.0