1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494: 495: 496: 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547: 548: 549: 550: 551: 552: 553: 554: 555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574: 575: 576: 577: 578: 579: 580: 581: 582: 583: 584: 585: 586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598: 599: 600: 601: 602: 603: 604: 605: 606: 607: 608: 609: 610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623: 624: 625: 626: 627: 628: 629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641: 642: 643: 644: 645: 646: 647: 648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659: 660: 661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671: 672: 673: 674: 675: 676: 677: 678: 679: 680: 681: 682: 683: 684: 685: 686: 687: 688: 689: 690: 691: 692: 693: 694: 695: 696: 697: 698: 699: 700: 701: 702: 703: 704: 705: 706: 707: 708: 709: 710: 711: 712: 713: 714: 715: 716: 717: 718: 719: 720: 721: 722: 723: 724: 725: 726: 727: 728: 729: 730: 731: 732: 733: 734: 735: 736: 737: 738: 739: 740: 741: 742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755: 756: 757: 758: 759: 760: 761: 762: 763: 764: 765: 766: 767: 768: 769:
<?php
/**
* MvcCore
*
* This source file is subject to the BSD 3 License
* For the full copyright and license information, please view
* the LICENSE.md file that are distributed with this source code.
*
* @copyright Copyright (c) 2016 Tom FlĂdr (https://github.com/mvccore/mvccore)
* @license https://mvccore.github.io/docs/mvccore/4.0.0/LICENCE.md
*/
namespace MvcCore\Ext\Form\Core;
require_once('Configuration.php');
//require_once('Exception.php');
//require_once('View.php');
abstract class Field
{
/**
* Form control html id
* @var string
*/
public $Id = '';
/**
* Form control type, usually used in <input type="">
* attr value, but unique type accross all form field types.
* @var string
*/
public $Type = '';
/**
* Form control specific name, server as key in submitting process
* where is sended it's used completed value.
* @requires
* @var string
*/
public $Name = '';
/**
* Form control value.
* @var string
*/
public $Value = '';
/**
* Form control label visible text, text only.
* @var string
*/
public $Label = '';
/**
* Location where to render <label> element.
* 'left' by default.
* @var string
*/
public $LabelSide = 'left'; // right | left
/**
* Form control attribute required, determinating
* if controll will be required to complete by user.
* @var bool
*/
public $Required = null;
/**
* Form control attribute readonly, determinating
* if controll will be readonly to not completed by user,
* and readonly by submitting process - so only session value will be used.
* @var bool
*/
public $Readonly = FALSE;
/**
* Form control attribute disabled, determinating
* if controll will be disabled to not completed by user,
* and disabled by submitting process - so only session value will be used.
* @var bool
*/
public $Disabled = FALSE;
/**
* Boolean telling if field will be translated or not.
* If nothing is configured as boolean, $field->Form->Translate values is used.
* If $field->Translate is TRUE, translated are placeholders, label texts and error messages.
* @var bool
*/
public $Translate = NULL;
/**
* Control/label rendering mode, defined in form by defaut as: 'normal'.
* Normal means label will be rendered before control, only for checkbox
* and radio buttons labels will be rendered after controls.
* Another possible values are 'no-label' and 'label-around'.
* Use \MvcCore\Ext\Form::FIELD_RENDER_MODE_NORMAL, \MvcCore\Ext\Form::FIELD_RENDER_MODE_NO_LABEL and
* \MvcCore\Ext\Form::FIELD_RENDER_MODE_LABEL_AROUND.
* @var string
*/
public $RenderMode = NULL;
/**
* Html element css class string value, more classes separated by space.
* @var array
*/
public $CssClasses = array();
/**
* Collection with html <input> element additional attributes by array keys/values.
* @var array
*/
public $ControlAttrs = array();
/**
* Collection with html <label> element additional attributes by array keys/values.
* @var array
*/
public $LabelAttrs = array();
/**
* List of validator classes end-names or list of closure functions
* accepting arguments: $submitValue, $fieldName, \MvcCore\Ext\Form\Core\Field & $field
* and returning safe value as result. Closure function should call
* $field->Form->AddError() internaly if necessary and submitted value is not correct.
* All validator classes are located in directory: /Form/Validators/...
* For validator class \MvcCore\Ext\Form\Validators\Numeric is necessary only tu set 'Numeric'.
* @var string[]|\Closure[]
*/
public $Validators = array();
/**
* Field instance errors for rendering process.
* @var string[]
*/
public $Errors = array();
/**
* Field relative template path without .phtml extension,
* empty string by default to render field naturaly.
* If there is configured any path, relative from directory /App/Views/Scripts,
* field is rendered by custom template.
* @var string
*/
public $TemplatePath = '';
/**
* Form field view, object container with variables from local context to render in template.
* Created automaticly inside \MvcCore\Ext\Form\Core\Field before field rendering process.
* @var \MvcCore\Ext\Form\Core\View
*/
public $View = NULL;
/**
* Supporting javascript full class name.
* @var string
*/
public $JsClass = '';
/**
* Supporting javascript file relative path.
* Replacement '__MVCCORE_FORM_DIR__' is in rendering process
* replaced by \MvcCore\Ext\Form library root dir or by any other
* reconfigured value from $this->Form->jsAssetsRootDir;
* @var string
*/
public $Js = '';
/**
* Supporting css file relative path.
* Replacement '__MVCCORE_FORM_DIR__' is in rendering process
* replaced by \MvcCore\Ext\Form library root dir or by any other
* reconfigured value from $this->Form->cssAssetsRootDir;
* @var string
*/
public $Css = '';
/**
* Form instance where current fields is placed.
* @var \MvcCore\Ext\Form
*/
public $Form = NULL;
/**
* Core rendering templates storrage.
* Those templates are used in form natural rendering process, form custom
* template rendering process, natural field rendering process but not
* by custom field rendering process.
* @var array
*/
public static $Templates = array(
'label' => '<label for="{id}"{attrs}>{label}</label>',
'control' => '<input id="{id}" name="{name}" type="{type}" value="{value}"{attrs} />',
'togetherLabelLeft' => '<label for="{id}"{attrs}><span>{label}</span>{control}</label>',
'togetherLabelRight'=> '<label for="{id}"{attrs}>{control}<span>{label}</span></label>',
);
/**
* Local $this context properties which is not possible
* to configure throught constructor config array.
* @var string[]
*/
protected static $declaredProtectedProperties = array(
'Id', 'View', 'Form', 'Field',
);
/* setters and getters ********************************************************************/
/**
* Set field name, used to identify submitting value.
* @requires
* @param string $name
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetName ($name) {
$this->Name = $name;
return $this;
}
/**
* Set input type like: 'text', 'number', 'range'...
* @param string $type
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetType ($type) {
$this->Type = $type;
return $this;
}
/**
* Set control label visible text.
* Translation will be processed internaly inside
* Simpleform before rendering process by $this->Form->Translator();
* @param string $label
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetLabel ($label) {
$this->Label = $label;
return $this;
}
/**
* Set label side - location where label will be rendered.
* By default $this->LabelSide is configured to 'left'.
* If you want to reconfigure it to different side,
* next possible value is 'right'.
* @param string $labelSide
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetLabelSide ($labelSide = 'right') {
$this->LabelSide = $labelSide;
return $this;
}
/**
* Set required boolean if field will be
* required to complete by user for submit.
* @param bool $required
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetRequired ($required = TRUE) {
$this->Required = $required;
return $this;
}
/**
* Set read only boolean if field will be
* read only, not possible to complete by user for submit,
* result value will be used from session.
* @param bool $readonly
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetReadonly ($readonly = TRUE) {
$this->Readonly = $readonly;
return $this;
}
/**
* Set field render mode to render label normaly before control
* by value 'normal', which controls have mostly configured by default
* or to render label around the control by value 'label-around' or
* to not render any label by value 'no-label'.
* Use \MvcCore\Ext\Form class constants:
* - \MvcCore\Ext\Form::FIELD_RENDER_MODE_NORMAL
* - \MvcCore\Ext\Form::FIELD_RENDER_MODE_LABEL_AROUND
* - \MvcCore\Ext\Form::FIELD_RENDER_MODE_NO_LABEL
* @param string $renderMode
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetRenderMode ($renderMode = \MvcCore\Ext\Form\Core\Configuration::FIELD_RENDER_MODE_LABEL_AROUND) {
$this->RenderMode = $renderMode;
return $this;
}
/**
* Set control value, should be string or array, by field type implementation.
* @param string|array|mixed $value
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetValue ($value) {
$this->Value = $value;
return $this;
}
/**
* Get control value, should be string or array, by field type implementation.
* @return string|array
*/
public function GetValue () {
return $this->Value;
}
/**
* Set translate to TRUE if you want to translate this field.
* It is necessary to set up any $form->Translator callable to
* translate cotnrol placeholder, label and error messages.
* @param bool $translate
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetTranslate ($translate = TRUE) {
$this->Translate = $translate;
return $this;
}
/**
* Set disabled boolean if field will be
* disabled for user, not possible to complete
* by user for submit and disabled in submitting process,
* result value will be used from session.
* @param bool $readonly
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetDisabled ($disabled) {
$this->Disabled = $disabled;
return $this;
}
/**
* Set value to control html class attribute.
* More classes is necessary to set as strings separated by spaces.
* @param string $cssClasses
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetCssClasses ($cssClasses) {
if (gettype($cssClasses) == 'array') {
$this->CssClasses = $cssClasses;
} else {
$this->CssClasses = explode(' ', (string)$cssClasses);
}
return $this;
}
/**
* Add value to html class attribute.
* More classes is necessary to add as strings separated by spaces.
* @param string $cssClasses
* @return \MvcCore\Ext\Form\Core\Field
*/
public function AddCssClass ($cssClass) {
$this->CssClasses[] = $cssClass;
return $this;
}
/**
* Set any additional control html attributes by key/value array.
* Do not use system attributes as id, name, value, readonly, disabled, class...
* @param array $attrs
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetControlAttrs ($attrs = array()) {
$this->ControlAttrs = $attrs;
return $this;
}
/**
* Add any additional control html attributes by key/value array.
* Do not use system attributes as id, name, value, readonly, disabled, class...
* Use specific setter for them.
* @param array $attrs
* @return \MvcCore\Ext\Form\Core\Field
*/
public function AddControlAttr ($attr = array()) {
$this->ControlAttrs[] = $attr;
return $this;
}
/**
* Set any additional control html attributes by key/value array.
* @param array $attrs
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetLabelAttrs ($attrs = array()) {
$this->LabelAttrs = $attrs;
return $this;
}
/**
* Add any additional control html attributes by key/value array.
* @param array $attrs
* @return \MvcCore\Ext\Form\Core\Field
*/
public function AddLabelAttr ($attr = array()) {
$this->LabelAttrs[] = $attr;
return $this;
}
/**
* Set field validators collection, it shoud be validator class end-name in pascal
* case or closure function. All validators are located in /Form/Validators/...
* dir. So for validator class \MvcCore\Ext\Form\Validators\Numeric is necessary only to set
* array('Numeric'). Or any validator shoud be defined as simple closure function
* accepting arguments: $submitValue, $fieldName, \MvcCore\Ext\Form\Core\Field & $field
* and returnning safe value as result. This closure function shoud call
* $field->Form->AddError(); whenever is necessary and values is not correct.
* @param string[]|\Closure[] $validators
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetValidators ($validators = array()) {
$this->Validators = $validators;
return $this;
}
/**
* Add field validators, it shoud be validator class end-name in pascal
* case or closure function. All validators are located in /Form/Validators/...
* dir. So for validator class \MvcCore\Ext\Form\Validators\Numeric is necessary only to set
* array('Numeric'). Or any validator shoud be defined as simple closure function
* accepting arguments: $submitValue, $fieldName, \MvcCore\Ext\Form\Core\Field & $field
* and returnning safe value as result. This closure function shoud call
* $field->Form->AddError(); whenever is necessary and values is not correct.
* @param string|Closure,... $validators
* @return \MvcCore\Ext\Form\Core\Field
*/
public function AddValidators () {
$args = func_get_args();
foreach ($args as $arg) $this->Validators[] = $arg;
return $this;
}
/**
* Set template relative path without .phtml extension,
* if you want to render field by custom template.
* Empty string by default to render field naturaly.
* If there is configured any path, relative from directory /App/Views/Scripts,
* field is rendered by custom template.
* @param string $templatePath
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetTemplatePath ($templatePath = '') {
$this->TemplatePath = $templatePath;
return $this;
}
/**
* Set supporting javascript full class name.
* @param string $jsClass
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetJsClass ($jsClass) {
$this->JsClass = $jsClass;
return $this;
}
/**
* Set supporting javascript file relative path.
* Replacement '__MVCCORE_FORM_DIR__' is in rendering process
* replaced by \MvcCore\Ext\Form library root dir or by any other
* reconfigured value from $this->Form->jsAssetsRootDir;
* @param string $jsFullFile
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetJs ($jsFullFile) {
$this->Js = $jsFullFile;
return $this;
}
/**
* Set supporting css file relative path.
* Replacement '__MVCCORE_FORM_DIR__' is in rendering process
* replaced by \MvcCore\Ext\Form library root dir or by any other
* reconfigured value from $this->Form->cssAssetsRootDir;
* @param string $cssFullFile
* @return \MvcCore\Ext\Form\Core\Field
*/
public function SetCss ($cssFullFile) {
$this->Css = $cssFullFile;
return $this;
}
/**
* Add field error message.
* This method is always called internaly from \MvcCore\Ext\Form
* in render preparing process. Do not use it.
* To add form error properly, use $field->Form->AddError();
* method isntead.
* @param string $errorText
* @return \MvcCore\Ext\Form\Core\Field
*/
public function AddError ($errorText) {
$this->Errors[] = $errorText;
return $this;
}
/* core methods **************************************************************************/
/**
* Create new form control instance.
* @param array $cfg config array with camel case
* public properties and its values which you want to configure.
* @throws \MvcCore\Ext\Form\Core\Exception
*/
public function __construct ($cfg = array()) {
static::$Templates = (object) static::$Templates;
foreach ($cfg as $key => $value) {
$propertyName = ucfirst($key);
if (in_array($propertyName, static::$declaredProtectedProperties)) {
$clsName = get_class($this);
include_once('Exception.php');
throw new \MvcCore\Ext\Form\Core\Exception(
"Property: '$propertyName' is protected, class: '$clsName'."
);
} else {
$this->$propertyName = $value;
}
}
}
/**
* Set any nondeclared property dynamicly
* to get it in view by rendering process.
* @param string $name
* @param mixed $value
*/
public function __set ($name, $value) {
$this->$name = $value;
}
/**
* This method is called internaly from \MvcCore\Ext\Form after field
* is added into form by $form->AddField(); method. Do not use it
* if you are only user of this library.
* - check if field has any name, which is required
* - set up form and field id attribute by form id and field name
* - set up required
* @param \MvcCore\Ext\Form $form
* @throws \MvcCore\Ext\Form\Core\Exception
* @return void
*/
public function OnAdded (\MvcCore\Ext\Form & $form) {
if (!$this->Name) {
$clsName = get_class($this);
include_once('Exception.php');
throw new \MvcCore\Ext\Form\Core\Exception("No 'Name' defined for form field: '$clsName'.");
}
$this->Form = $form;
$this->Id = implode(Configuration::HTML_IDS_DELIMITER, array(
$form->Id,
$this->Name
));
// if there is no specific required boolean - set required boolean by form
$this->Required = is_null($this->Required) ? $form->Required : $this->Required ;
}
/**
* Set up field properties before rendering process.
* - set up field render mode
* - set up translation boolean
* - translate label if any
* @return void
*/
public function SetUp () {
$form = $this->Form;
$translator = $form->Translator;
// if there is no specific render mode - set render mode by form
if (is_null($this->RenderMode)) {
$this->RenderMode = $form->FieldsDefaultRenderMode;
}
// translate only if Translate options is null or true and translator handler is defined
if (
(is_null($this->Translate) || $this->Translate === TRUE || $form->Translate) &&
!is_null($translator)
) {
$this->Translate = TRUE;
} else {
$this->Translate = FALSE;
}
if ($this->Translate && $this->Label) {
$this->Label = call_user_func($translator, $this->Label, $form->Lang);
}
}
/* rendering ******************************************************************************/
/**
* Render field in full mode, naturaly or by custom template.
* @return string
*/
public function Render () {
if ($this->TemplatePath) {
return $this->RenderTemplate();
} else {
return $this->RenderNaturally();
}
}
/**
* Render field by configured template.
* This method creates $view = new \MvcCore\Ext\Form\Core\View
* sets all local context variables into it and renders it into string.
* @return string
*/
public function RenderTemplate () {
include_once('View.php');
$view = new View($this->Form);
$this->Field = $this;
$view->SetUp($this);
return $view->Render($this->Form->TemplateTypePath, $this->TemplatePath);
}
/**
* Render field naturaly by render mode.
* Field shoud be rendered with label beside, label around
* or without label by local field configuration. Also there
* could be rendered specific field errors before or after field
* if field form is configured in that way.
* @return string
*/
public function RenderNaturally () {
$result = '';
if ($this->RenderMode == Configuration::FIELD_RENDER_MODE_NORMAL && $this->Label) {
$result = $this->RenderLabelAndControl();
} else if ($this->RenderMode == Configuration::FIELD_RENDER_MODE_LABEL_AROUND && $this->Label) {
$result = $this->RenderControlInsideLabel();
} else if ($this->RenderMode == Configuration::FIELD_RENDER_MODE_NO_LABEL || !$this->Label) {
$result = $this->RenderControl();
$errors = $this->RenderErrors();
if ($this->Form->ErrorsRenderMode !== Configuration::ERROR_RENDER_MODE_BEFORE_EACH_CONTROL) {
$result = $errors . $result;
} else if ($this->Form->ErrorsRenderMode !== Configuration::ERROR_RENDER_MODE_AFTER_EACH_CONTROL) {
$result .= $errors;
}
}
return $result;
}
/**
* Render field control and label by local configuration in left or in right side,
* errors beside if form is configured to render specific errors beside controls.
* @return string
*/
public function RenderLabelAndControl () {
$result = "";
if ($this->LabelSide == 'left') {
$result = $this->RenderLabel() . $this->RenderControl();
} else {
$result = $this->RenderControl() . $this->RenderLabel();
}
$errors = $this->RenderErrors();
if ($this->Form->ErrorsRenderMode == Configuration::ERROR_RENDER_MODE_BEFORE_EACH_CONTROL) {
$result = $errors . $result;
} else if ($this->Form->ErrorsRenderMode == Configuration::ERROR_RENDER_MODE_AFTER_EACH_CONTROL) {
$result .= $errors;
}
return $result;
}
/**
* Render field control inside label by local configuration, render field
* errors beside if form is configured to render specific errors beside controls.
* @return string
*/
public function RenderControlInsideLabel () {
if ($this->RenderMode == Configuration::FIELD_RENDER_MODE_NO_LABEL) return $this->RenderControl();
$attrsStr = $this->renderLabelAttrsWithFieldVars();
$template = $this->LabelSide == 'left' ? static::$Templates->togetherLabelLeft : static::$Templates->togetherLabelRight;
$result = $this->Form->View->Format($template, array(
'id' => $this->Id,
'label' => $this->Label,
'control' => $this->RenderControl(),
'attrs' => $attrsStr ? " $attrsStr" : '',
));
$errors = $this->RenderErrors();
if ($this->Form->ErrorsRenderMode == Configuration::ERROR_RENDER_MODE_BEFORE_EACH_CONTROL) {
$result = $errors . $result;
} else if ($this->Form->ErrorsRenderMode == Configuration::ERROR_RENDER_MODE_AFTER_EACH_CONTROL) {
$result .= $errors;
}
return $result;
}
/**
* Render control tag only without label or specific errors.
* @return string
*/
public function RenderControl () {
$attrsStr = $this->renderControlAttrsWithFieldVars();
return $this->Form->View->Format(static::$Templates->control, array(
'id' => $this->Id,
'name' => $this->Name,
'type' => $this->Type,
'value' => $this->Value,
'attrs' => $attrsStr ? " $attrsStr" : '',
));
}
/**
* Render label tag only without control or specific errors.
* @return string
*/
public function RenderLabel () {
if ($this->RenderMode == Configuration::FIELD_RENDER_MODE_NO_LABEL) return '';
$attrsStr = $this->renderLabelAttrsWithFieldVars();
return $this->Form->View->Format(static::$Templates->label, array(
'id' => $this->Id,
'label' => $this->Label,
'attrs' => $attrsStr ? " $attrsStr" : '',
));
}
/**
* Render field specific errors only without control or label.
* @return string
*/
public function RenderErrors () {
$result = "";
if ($this->Errors && $this->Form->ErrorsRenderMode !== Configuration::ERROR_RENDER_MODE_ALL_TOGETHER) {
$result .= '<span class="errors">';
foreach ($this->Errors as $key => $errorMessage) {
$errorCssClass = 'error';
if (isset($this->Fields[$key])) $errorCssClass .= " $key";
$result .= "<span class=\"$errorCssClass\">$errorMessage</span>";
}
$result .= '</span>';
}
return $result;
}
/* protected renderers *******************************************************************/
/**
* Complete HTML attributes and css classes strings for label element
* by selected field variables from $this field context
* only if called $fieldVars item in $this field context is
* something different then NULL value.
* Automaticly render into attributes and css classes also
* system field properties: 'Disabled', 'Readonly' and 'Required'
* in boolean mode. All named field context properties translate
* into attributes names and css classes strings from PascalCase into
* dashed-case.
* @param string[] $fieldVars
* @return string
*/
protected function renderLabelAttrsWithFieldVars ($fieldVars = array()) {
return $this->renderAttrsWithFieldVars(
$fieldVars, $this->LabelAttrs, $this->CssClasses
);
}
/**
* Complete HTML attributes and css classes strings for control element
* by selected field variables from $this field context
* only if called $fieldVars item in $this field context is
* something different then NULL value.
* Automaticly render into attributes and css classes also
* system field properties: 'Disabled', 'Readonly' and 'Required'
* in boolean mode. All named field context properties translate
* into attributes names and css classes strings from PascalCase into
* dashed-case.
* @param string[] $fieldVars
* @return string
*/
protected function renderControlAttrsWithFieldVars ($fieldVars = array()) {
return $this->renderAttrsWithFieldVars(
$fieldVars, $this->ControlAttrs, $this->CssClasses, TRUE
);
}
/**
* Complete HTML attributes and css classes strings for label/control element
* by selected field variables from $this field context
* only if called $fieldVars item in $this field context is
* something different then NULL value.
* Automaticly render into attributes and css classes also
* system field properties: 'Disabled', 'Readonly' and 'Required'
* in boolean mode. All named field context properties translate
* into attributes names and css classes strings from PascalCase into
* dashed-case.
* Only if fourth param is false, do not add system attributes in boolean
* mode into attributes, only into css class.
* @param string[] $fieldVars
* @param array $fieldAttrs
* @param array $cssClasses
* @param bool $controlRendering
* @return string
*/
protected function renderAttrsWithFieldVars (
$fieldVars = array(), $fieldAttrs = array(), $cssClasses = array(), $controlRendering = FALSE
) {
$attrs = array();
foreach ($fieldVars as $fieldVar) {
if (!is_null($this->$fieldVar)) {
$attrName = \MvcCore\Tool::GetDashedFromPascalCase($fieldVar);
$attrs[$attrName] = $this->$fieldVar;
}
}
$boolFieldVars = array('Disabled', 'Readonly', 'Required');
foreach ($boolFieldVars as $fieldVar) {
if ($this->$fieldVar) {
$attrName = lcfirst($fieldVar);
if ($controlRendering) $attrs[$attrName] = $attrName;
$cssClasses[] = $attrName;
}
}
$cssClasses[] = \MvcCore\Tool::GetDashedFromPascalCase($this->Name);
$attrs['class'] = implode(' ', $cssClasses);
include_once('View.php');
return View::RenderAttrs(
array_merge($fieldAttrs, $attrs)
);
}
}