CFormInputElement.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <?php
  2. /**
  3. * CFormInputElement class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CFormInputElement represents form input element.
  12. *
  13. * CFormInputElement can represent the following types of form input based on {@link type} property:
  14. * <ul>
  15. * <li>text: a normal text input generated using {@link CHtml::activeTextField}</li>
  16. * <li>hidden: a hidden input generated using {@link CHtml::activeHiddenField}</li>
  17. * <li>password: a password input generated using {@link CHtml::activePasswordField}</li>
  18. * <li>textarea: a text area generated using {@link CHtml::activeTextArea}</li>
  19. * <li>file: a file input generated using {@link CHtml::activeFileField}</li>
  20. * <li>radio: a radio button generated using {@link CHtml::activeRadioButton}</li>
  21. * <li>checkbox: a check box generated using {@link CHtml::activeCheckBox}</li>
  22. * <li>listbox: a list box generated using {@link CHtml::activeListBox}</li>
  23. * <li>dropdownlist: a drop-down list generated using {@link CHtml::activeDropDownList}</li>
  24. * <li>checkboxlist: a list of check boxes generated using {@link CHtml::activeCheckBoxList}</li>
  25. * <li>radiolist: a list of radio buttons generated using {@link CHtml::activeRadioButtonList}</li>
  26. * <li>url: an HTML5 url input generated using {@link CHtml::activeUrlField}</li>
  27. * <li>email: an HTML5 email input generated using {@link CHtml::activeEmailField}</li>
  28. * <li>number: an HTML5 number input generated using {@link CHtml::activeNumberField}</li>
  29. * <li>range: an HTML5 range input generated using {@link CHtml::activeRangeField}</li>
  30. * <li>date: an HTML5 date input generated using {@link CHtml::activeDateField}</li>
  31. * <li>time: an HTML5 time input generated using {@link CHtml::activeTimeField}</li>
  32. * <li>datetime: an HTML5 datetime input generated using {@link CHtml::activeDateTimeField}</li>
  33. * <li>datetimelocal: an HTML5 datetime-local input generated using {@link CHtml::activeDateTimeLocalField}</li>
  34. * <li>week: an HTML5 week input generated using {@link CHtml::activeWeekField}</li>
  35. * <li>color: an HTML5 color input generated using {@link CHtml::activeColorField}</li>
  36. * <li>tel: an HTML5 tel input generated using {@link CHtml::activeTelField}</li>
  37. * <li>search: an HTML5 search input generated using {@link CHtml::activeSearchField}</li>
  38. * </ul>
  39. * The {@link type} property can also be a class name or a path alias to the class. In this case,
  40. * the input is generated using a widget of the specified class. Note, the widget must
  41. * have a property called "model" which expects a model object, and a property called "attribute"
  42. * which expects the name of a model attribute.
  43. *
  44. * Because CFormElement is an ancestor class of CFormInputElement, a value assigned to a non-existing property will be
  45. * stored in {@link attributes} which will be passed as HTML attribute values to the {@link CHtml} method
  46. * generating the input or initial values of the widget properties.
  47. *
  48. * @property boolean $required Whether this input is required.
  49. * @property string $label The label for this input. If the label is not manually set,
  50. * this method will call {@link CModel::getAttributeLabel} to determine the label.
  51. *
  52. * @author Qiang Xue <qiang.xue@gmail.com>
  53. * @package system.web.form
  54. * @since 1.1
  55. */
  56. class CFormInputElement extends CFormElement
  57. {
  58. /**
  59. * @var array Core input types (alias=>CHtml method name)
  60. */
  61. public static $coreTypes=array(
  62. 'text'=>'activeTextField',
  63. 'hidden'=>'activeHiddenField',
  64. 'password'=>'activePasswordField',
  65. 'textarea'=>'activeTextArea',
  66. 'file'=>'activeFileField',
  67. 'radio'=>'activeRadioButton',
  68. 'checkbox'=>'activeCheckBox',
  69. 'listbox'=>'activeListBox',
  70. 'dropdownlist'=>'activeDropDownList',
  71. 'checkboxlist'=>'activeCheckBoxList',
  72. 'radiolist'=>'activeRadioButtonList',
  73. 'url'=>'activeUrlField',
  74. 'email'=>'activeEmailField',
  75. 'number'=>'activeNumberField',
  76. 'range'=>'activeRangeField',
  77. 'date'=>'activeDateField',
  78. 'time'=>'activeTimeField',
  79. 'datetime'=>'activeDateTimeField',
  80. 'datetimelocal'=>'activeDateTimeLocalField',
  81. 'week'=>'activeWeekField',
  82. 'color'=>'activeColorField',
  83. 'tel'=>'activeTelField',
  84. 'search'=>'activeSearchField',
  85. );
  86. /**
  87. * @var string the type of this input. This can be a widget class name, a path alias of a widget class name,
  88. * or an input type alias (text, hidden, password, textarea, file, radio, checkbox, listbox, dropdownlist, checkboxlist, or radiolist).
  89. * If a widget class, it must extend from {@link CInputWidget} or (@link CJuiInputWidget).
  90. */
  91. public $type;
  92. /**
  93. * @var string name of this input
  94. */
  95. public $name;
  96. /**
  97. * @var string hint text of this input
  98. */
  99. public $hint;
  100. /**
  101. * @var array the options for this input when it is a list box, drop-down list, check box list, or radio button list.
  102. * Please see {@link CHtml::listData} for details of generating this property value.
  103. */
  104. public $items=array();
  105. /**
  106. * @var array the options used when rendering the error part. This property will be passed
  107. * to the {@link CActiveForm::error} method call as its $htmlOptions parameter.
  108. * @see CActiveForm::error
  109. * @since 1.1.1
  110. */
  111. public $errorOptions=array();
  112. /**
  113. * @var boolean whether to allow AJAX-based validation for this input. Note that in order to use
  114. * AJAX-based validation, {@link CForm::activeForm} must be configured with 'enableAjaxValidation'=>true.
  115. * This property allows turning on or off AJAX-based validation for individual input fields.
  116. * Defaults to true.
  117. * @since 1.1.7
  118. */
  119. public $enableAjaxValidation=true;
  120. /**
  121. * @var boolean whether to allow client-side validation for this input. Note that in order to use
  122. * client-side validation, {@link CForm::activeForm} must be configured with 'enableClientValidation'=>true.
  123. * This property allows turning on or off client-side validation for individual input fields.
  124. * Defaults to true.
  125. * @since 1.1.7
  126. */
  127. public $enableClientValidation=true;
  128. /**
  129. * @var string the layout used to render label, input, hint and error. They correspond to the placeholders
  130. * "{label}", "{input}", "{hint}" and "{error}".
  131. */
  132. public $layout="{label}\n{input}\n{hint}\n{error}";
  133. private $_label;
  134. private $_required;
  135. /**
  136. * Gets the value indicating whether this input is required.
  137. * If this property is not set explicitly, it will be determined by calling
  138. * {@link CModel::isAttributeRequired} for the associated model and attribute of this input.
  139. * @return boolean whether this input is required.
  140. */
  141. public function getRequired()
  142. {
  143. if($this->_required!==null)
  144. return $this->_required;
  145. else
  146. return $this->getParent()->getModel()->isAttributeRequired($this->name);
  147. }
  148. /**
  149. * @param boolean $value whether this input is required.
  150. */
  151. public function setRequired($value)
  152. {
  153. $this->_required=$value;
  154. }
  155. /**
  156. * @return string the label for this input. If the label is not manually set,
  157. * this method will call {@link CModel::getAttributeLabel} to determine the label.
  158. */
  159. public function getLabel()
  160. {
  161. if($this->_label!==null)
  162. return $this->_label;
  163. else
  164. return $this->getParent()->getModel()->getAttributeLabel($this->name);
  165. }
  166. /**
  167. * @param string $value the label for this input
  168. */
  169. public function setLabel($value)
  170. {
  171. $this->_label=$value;
  172. }
  173. /**
  174. * Renders everything for this input.
  175. * The default implementation simply returns the result of {@link renderLabel}, {@link renderInput},
  176. * {@link renderHint}. When {@link CForm::showErrorSummary} is false, {@link renderError} is also called
  177. * to show error messages after individual input fields.
  178. * @return string the complete rendering result for this input, including label, input field, hint, and error.
  179. */
  180. public function render()
  181. {
  182. if($this->type==='hidden')
  183. return $this->renderInput();
  184. $output=array(
  185. '{label}'=>$this->renderLabel(),
  186. '{input}'=>$this->renderInput(),
  187. '{hint}'=>$this->renderHint(),
  188. '{error}'=>!$this->getParent()->showErrors ? '' : $this->renderError(),
  189. );
  190. return strtr($this->layout,$output);
  191. }
  192. /**
  193. * Renders the label for this input.
  194. * The default implementation returns the result of {@link CHtml activeLabelEx}.
  195. * @return string the rendering result
  196. */
  197. public function renderLabel()
  198. {
  199. $options = array(
  200. 'label'=>$this->getLabel(),
  201. 'required'=>$this->getRequired()
  202. );
  203. if(!empty($this->attributes['id']))
  204. $options['for']=$this->attributes['id'];
  205. return CHtml::activeLabel($this->getParent()->getModel(), $this->name, $options);
  206. }
  207. /**
  208. * Renders the input field.
  209. * The default implementation returns the result of the appropriate CHtml method or the widget.
  210. * @return string the rendering result
  211. */
  212. public function renderInput()
  213. {
  214. if(isset(self::$coreTypes[$this->type]))
  215. {
  216. $method=self::$coreTypes[$this->type];
  217. if(strpos($method,'List')!==false)
  218. return CHtml::$method($this->getParent()->getModel(), $this->name, $this->items, $this->attributes);
  219. else
  220. return CHtml::$method($this->getParent()->getModel(), $this->name, $this->attributes);
  221. }
  222. else
  223. {
  224. $attributes=$this->attributes;
  225. $attributes['model']=$this->getParent()->getModel();
  226. $attributes['attribute']=$this->name;
  227. ob_start();
  228. $this->getParent()->getOwner()->widget($this->type, $attributes);
  229. return ob_get_clean();
  230. }
  231. }
  232. /**
  233. * Renders the error display of this input.
  234. * The default implementation returns the result of {@link CHtml::error}
  235. * @return string the rendering result
  236. */
  237. public function renderError()
  238. {
  239. $parent=$this->getParent();
  240. return $parent->getActiveFormWidget()->error($parent->getModel(), $this->name, $this->errorOptions, $this->enableAjaxValidation, $this->enableClientValidation);
  241. }
  242. /**
  243. * Renders the hint text for this input.
  244. * The default implementation returns the {@link hint} property enclosed in a paragraph HTML tag.
  245. * @return string the rendering result.
  246. */
  247. public function renderHint()
  248. {
  249. return $this->hint===null ? '' : '<div class="hint">'.$this->hint.'</div>';
  250. }
  251. /**
  252. * Evaluates the visibility of this element.
  253. * This method will check if the attribute associated with this input is safe for
  254. * the current model scenario.
  255. * @return boolean whether this element is visible.
  256. */
  257. protected function evaluateVisible()
  258. {
  259. return $this->getParent()->getModel()->isAttributeSafe($this->name);
  260. }
  261. }