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

  • BaseControl
  • Button
  • Checkbox
  • CheckboxList
  • ChoiceControl
  • CsrfProtection
  • HiddenField
  • ImageButton
  • MultiChoiceControl
  • MultiSelectBox
  • RadioList
  • SelectBox
  • SubmitButton
  • TextArea
  • TextBase
  • TextInput
  • UploadControl
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  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\Controls;
  9: 
 10: use Nette;
 11: use Nette\Forms\IControl;
 12: use Nette\Utils\Html;
 13: use Nette\Forms\Form;
 14: 
 15: 
 16: /**
 17:  * Base class that implements the basic functionality common to form controls.
 18:  *
 19:  * @property-read Form $form
 20:  * @property-read string $htmlName
 21:  * @property   string $htmlId
 22:  * @property   mixed $value
 23:  * @property   bool $disabled
 24:  * @property   bool $omitted
 25:  * @property-read Html $control
 26:  * @property-read Html $label
 27:  * @property-read Html $controlPrototype
 28:  * @property-read Html $labelPrototype
 29:  * @property   bool $required
 30:  * @property-read array $errors
 31:  */
 32: abstract class BaseControl extends Nette\ComponentModel\Component implements IControl
 33: {
 34:     /** @var string */
 35:     public static $idMask = 'frm-%s';
 36: 
 37:     /** @var string textual caption or label */
 38:     public $caption;
 39: 
 40:     /** @var mixed current control value */
 41:     protected $value;
 42: 
 43:     /** @var Html  control element template */
 44:     protected $control;
 45: 
 46:     /** @var Html  label element template */
 47:     protected $label;
 48: 
 49:     /** @var array */
 50:     private $errors = array();
 51: 
 52:     /** @var bool */
 53:     protected $disabled = FALSE;
 54: 
 55:     /** @var bool */
 56:     private $omitted = FALSE;
 57: 
 58:     /** @var Nette\Forms\Rules */
 59:     private $rules;
 60: 
 61:     /** @var Nette\Localization\ITranslator */
 62:     private $translator = TRUE; // means autodetect
 63: 
 64:     /** @var array user options */
 65:     private $options = array();
 66: 
 67: 
 68:     /**
 69:      * @param  string  caption
 70:      */
 71:     public function __construct($caption = NULL)
 72:     {
 73:         $this->monitor('Nette\Forms\Form');
 74:         parent::__construct();
 75:         $this->control = Html::el('input', array('type' => NULL, 'name' => NULL));
 76:         $this->label = Html::el('label');
 77:         $this->caption = $caption;
 78:         $this->rules = new Nette\Forms\Rules($this);
 79:         $this->setValue(NULL);
 80:     }
 81: 
 82: 
 83:     /**
 84:      * This method will be called when the component becomes attached to Form.
 85:      * @param  Nette\ComponentModel\IComponent
 86:      * @return void
 87:      */
 88:     protected function attached($form)
 89:     {
 90:         if (!$this->isDisabled() && $form instanceof Form && $form->isAnchored() && $form->isSubmitted()) {
 91:             $this->loadHttpData();
 92:         }
 93:     }
 94: 
 95: 
 96:     /**
 97:      * Returns form.
 98:      * @param  bool   throw exception if form doesn't exist?
 99:      * @return Form
100:      */
101:     public function getForm($need = TRUE)
102:     {
103:         return $this->lookup('Nette\Forms\Form', $need);
104:     }
105: 
106: 
107:     /**
108:      * Loads HTTP data.
109:      * @return void
110:      */
111:     public function loadHttpData()
112:     {
113:         $this->setValue($this->getHttpData(Form::DATA_TEXT));
114:     }
115: 
116: 
117:     /**
118:      * Loads HTTP data.
119:      * @return mixed
120:      */
121:     public function getHttpData($type, $htmlTail = NULL)
122:     {
123:         return $this->getForm()->getHttpData($type, $this->getHtmlName() . $htmlTail);
124:     }
125: 
126: 
127:     /**
128:      * Returns HTML name of control.
129:      * @return string
130:      */
131:     public function getHtmlName()
132:     {
133:         return Nette\Forms\Helpers::generateHtmlName($this->lookupPath('Nette\Forms\Form'));
134:     }
135: 
136: 
137:     /********************* interface IControl ****************d*g**/
138: 
139: 
140:     /**
141:      * Sets control's value.
142:      * @return self
143:      */
144:     public function setValue($value)
145:     {
146:         $this->value = $value;
147:         return $this;
148:     }
149: 
150: 
151:     /**
152:      * Returns control's value.
153:      * @return mixed
154:      */
155:     public function getValue()
156:     {
157:         return $this->value;
158:     }
159: 
160: 
161:     /**
162:      * Is control filled?
163:      * @return bool
164:      */
165:     public function isFilled()
166:     {
167:         $value = $this->getValue();
168:         return $value !== NULL && $value !== array() && $value !== '';
169:     }
170: 
171: 
172:     /**
173:      * Sets control's default value.
174:      * @return self
175:      */
176:     public function setDefaultValue($value)
177:     {
178:         $form = $this->getForm(FALSE);
179:         if ($this->isDisabled() || !$form || !$form->isAnchored() || !$form->isSubmitted()) {
180:             $this->setValue($value);
181:         }
182:         return $this;
183:     }
184: 
185: 
186:     /**
187:      * Disables or enables control.
188:      * @param  bool
189:      * @return self
190:      */
191:     public function setDisabled($value = TRUE)
192:     {
193:         if ($this->disabled = (bool) $value) {
194:             $this->omitted = TRUE;
195:             $this->setValue(NULL);
196:         }
197:         return $this;
198:     }
199: 
200: 
201:     /**
202:      * Is control disabled?
203:      * @return bool
204:      */
205:     public function isDisabled()
206:     {
207:         return $this->disabled === TRUE;
208:     }
209: 
210: 
211:     /**
212:      * Sets whether control value is excluded from $form->getValues() result.
213:      * @param  bool
214:      * @return self
215:      */
216:     public function setOmitted($value = TRUE)
217:     {
218:         $this->omitted = (bool) $value;
219:         return $this;
220:     }
221: 
222: 
223:     /**
224:      * Is control value excluded from $form->getValues() result?
225:      * @return bool
226:      */
227:     public function isOmitted()
228:     {
229:         return $this->omitted;
230:     }
231: 
232: 
233:     /********************* rendering ****************d*g**/
234: 
235: 
236:     /**
237:      * Generates control's HTML element.
238:      * @return Html|string
239:      */
240:     public function getControl()
241:     {
242:         $this->setOption('rendered', TRUE);
243:         $el = clone $this->control;
244:         return $el->addAttributes(array(
245:             'name' => $this->getHtmlName(),
246:             'id' => $this->getHtmlId(),
247:             'required' => $this->isRequired(),
248:             'disabled' => $this->isDisabled(),
249:             'data-nette-rules' => Nette\Forms\Helpers::exportRules($this->rules) ?: NULL,
250:         ));
251:     }
252: 
253: 
254:     /**
255:      * Generates label's HTML element.
256:      * @param  string
257:      * @return Html|string
258:      */
259:     public function getLabel($caption = NULL)
260:     {
261:         $label = clone $this->label;
262:         $label->for = $this->getHtmlId();
263:         $label->setText($this->translate($caption === NULL ? $this->caption : $caption));
264:         return $label;
265:     }
266: 
267: 
268:     /**
269:      * Returns control's HTML element template.
270:      * @return Html
271:      */
272:     public function getControlPrototype()
273:     {
274:         return $this->control;
275:     }
276: 
277: 
278:     /**
279:      * Returns label's HTML element template.
280:      * @return Html
281:      */
282:     public function getLabelPrototype()
283:     {
284:         return $this->label;
285:     }
286: 
287: 
288:     /**
289:      * Changes control's HTML id.
290:      * @param  string new ID, or FALSE or NULL
291:      * @return self
292:      */
293:     public function setHtmlId($id)
294:     {
295:         $this->control->id = $id;
296:         return $this;
297:     }
298: 
299: 
300:     /**
301:      * Returns control's HTML id.
302:      * @return string
303:      */
304:     public function getHtmlId()
305:     {
306:         if (!isset($this->control->id)) {
307:             $this->control->id = sprintf(self::$idMask, $this->lookupPath());
308:         }
309:         return $this->control->id;
310:     }
311: 
312: 
313:     /**
314:      * Changes control's HTML attribute.
315:      * @param  string name
316:      * @param  mixed  value
317:      * @return self
318:      */
319:     public function setAttribute($name, $value = TRUE)
320:     {
321:         $this->control->$name = $value;
322:         return $this;
323:     }
324: 
325: 
326:     /********************* translator ****************d*g**/
327: 
328: 
329:     /**
330:      * Sets translate adapter.
331:      * @return self
332:      */
333:     public function setTranslator(Nette\Localization\ITranslator $translator = NULL)
334:     {
335:         $this->translator = $translator;
336:         return $this;
337:     }
338: 
339: 
340:     /**
341:      * Returns translate adapter.
342:      * @return Nette\Localization\ITranslator|NULL
343:      */
344:     public function getTranslator()
345:     {
346:         if ($this->translator === TRUE) {
347:             return $this->getForm(FALSE) ? $this->getForm()->getTranslator() : NULL;
348:         }
349:         return $this->translator;
350:     }
351: 
352: 
353:     /**
354:      * Returns translated string.
355:      * @param  mixed
356:      * @param  int      plural count
357:      * @return string
358:      */
359:     public function translate($value, $count = NULL)
360:     {
361:         if ($translator = $this->getTranslator()) {
362:             $tmp = is_array($value) ? array(& $value) : array(array(& $value));
363:             foreach ($tmp[0] as & $v) {
364:                 if ($v != NULL && !$v instanceof Html) { // intentionally ==
365:                     $v = $translator->translate($v, $count);
366:                 }
367:             }
368:         }
369:         return $value;
370:     }
371: 
372: 
373:     /********************* rules ****************d*g**/
374: 
375: 
376:     /**
377:      * Adds a validation rule.
378:      * @param  mixed      rule type
379:      * @param  string     message to display for invalid data
380:      * @param  mixed      optional rule arguments
381:      * @return self
382:      */
383:     public function addRule($validator, $message = NULL, $arg = NULL)
384:     {
385:         $this->rules->addRule($validator, $message, $arg);
386:         return $this;
387:     }
388: 
389: 
390:     /**
391:      * Adds a validation condition a returns new branch.
392:      * @param  mixed     condition type
393:      * @param  mixed     optional condition arguments
394:      * @return Nette\Forms\Rules      new branch
395:      */
396:     public function addCondition($validator, $value = NULL)
397:     {
398:         return $this->rules->addCondition($validator, $value);
399:     }
400: 
401: 
402:     /**
403:      * Adds a validation condition based on another control a returns new branch.
404:      * @param  IControl form control
405:      * @param  mixed      condition type
406:      * @param  mixed      optional condition arguments
407:      * @return Nette\Forms\Rules      new branch
408:      */
409:     public function addConditionOn(IControl $control, $validator, $value = NULL)
410:     {
411:         return $this->rules->addConditionOn($control, $validator, $value);
412:     }
413: 
414: 
415:     /**
416:      * @return Nette\Forms\Rules
417:      */
418:     public function getRules()
419:     {
420:         return $this->rules;
421:     }
422: 
423: 
424:     /**
425:      * Makes control mandatory.
426:      * @param  mixed  state or error message
427:      * @return self
428:      */
429:     public function setRequired($value = TRUE)
430:     {
431:         $this->rules->setRequired($value);
432:         return $this;
433:     }
434: 
435: 
436:     /**
437:      * Is control mandatory?
438:      * @return bool
439:      */
440:     public function isRequired()
441:     {
442:         return $this->rules->isRequired();
443:     }
444: 
445: 
446:     /**
447:      * Performs the server side validation.
448:      * @return void
449:      */
450:     public function validate()
451:     {
452:         if ($this->isDisabled()) {
453:             return;
454:         }
455:         $this->cleanErrors();
456:         $this->rules->validate();
457:     }
458: 
459: 
460:     /**
461:      * Adds error message to the list.
462:      * @param  string  error message
463:      * @return void
464:      */
465:     public function addError($message)
466:     {
467:         $this->errors[] = $message;
468:     }
469: 
470: 
471:     /**
472:      * Returns errors corresponding to control.
473:      * @return string
474:      */
475:     public function getError()
476:     {
477:         return $this->errors ? implode(' ', array_unique($this->errors)) : NULL;
478:     }
479: 
480: 
481:     /**
482:      * Returns errors corresponding to control.
483:      * @return array
484:      */
485:     public function getErrors()
486:     {
487:         return array_unique($this->errors);
488:     }
489: 
490: 
491:     /**
492:      * @return bool
493:      */
494:     public function hasErrors()
495:     {
496:         return (bool) $this->errors;
497:     }
498: 
499: 
500:     /**
501:      * @return void
502:      */
503:     public function cleanErrors()
504:     {
505:         $this->errors = array();
506:     }
507: 
508: 
509:     /** @deprecated */
510:     protected static function exportRules($rules)
511:     {
512:         trigger_error(__METHOD__ . '() is deprecated; use Nette\Forms\Helpers::exportRules() instead.', E_USER_DEPRECATED);
513:         return Nette\Forms\Helpers::exportRules($rules);
514:     }
515: 
516: 
517:     /********************* user data ****************d*g**/
518: 
519: 
520:     /**
521:      * Sets user-specific option.
522:      * @return self
523:      */
524:     public function setOption($key, $value)
525:     {
526:         if ($value === NULL) {
527:             unset($this->options[$key]);
528:         } else {
529:             $this->options[$key] = $value;
530:         }
531:         return $this;
532:     }
533: 
534: 
535:     /**
536:      * Returns user-specific option.
537:      * @return mixed
538:      */
539:     public function getOption($key, $default = NULL)
540:     {
541:         return isset($this->options[$key]) ? $this->options[$key] : $default;
542:     }
543: 
544: 
545:     /**
546:      * Returns user-specific options.
547:      * @return array
548:      */
549:     public function getOptions()
550:     {
551:         return $this->options;
552:     }
553: 
554: }
555: 
Nette 2.3.8 API API documentation generated by ApiGen 2.8.0