CFormInputElement.php 10.2 KB
Newer Older
JULIO JARAMILLO's avatar
JULIO JARAMILLO committed
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
<?php
/**
 * CFormInputElement class file.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.yiiframework.com/
 * @copyright 2008-2013 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * CFormInputElement represents form input element.
 *
 * CFormInputElement can represent the following types of form input based on {@link type} property:
 * <ul>
 * <li>text: a normal text input generated using {@link CHtml::activeTextField}</li>
 * <li>hidden: a hidden input generated using {@link CHtml::activeHiddenField}</li>
 * <li>password: a password input generated using {@link CHtml::activePasswordField}</li>
 * <li>textarea: a text area generated using {@link CHtml::activeTextArea}</li>
 * <li>file: a file input generated using {@link CHtml::activeFileField}</li>
 * <li>radio: a radio button generated using {@link CHtml::activeRadioButton}</li>
 * <li>checkbox: a check box generated using {@link CHtml::activeCheckBox}</li>
 * <li>listbox: a list box generated using {@link CHtml::activeListBox}</li>
 * <li>dropdownlist: a drop-down list generated using {@link CHtml::activeDropDownList}</li>
 * <li>checkboxlist: a list of check boxes generated using {@link CHtml::activeCheckBoxList}</li>
 * <li>radiolist: a list of radio buttons generated using {@link CHtml::activeRadioButtonList}</li>
 * <li>url: an HTML5 url input generated using {@link CHtml::activeUrlField}</li>
 * <li>email: an HTML5 email input generated using {@link CHtml::activeEmailField}</li>
 * <li>number: an HTML5 number input generated using {@link CHtml::activeNumberField}</li>
 * <li>range: an HTML5 range input generated using {@link CHtml::activeRangeField}</li>
 * <li>date: an HTML5 date input generated using {@link CHtml::activeDateField}</li>
 * <li>time: an HTML5 time input generated using {@link CHtml::activeTimeField}</li>
 * <li>datetime: an HTML5 datetime input generated using {@link CHtml::activeDateTimeField}</li>
 * <li>datetimelocal: an HTML5 datetime-local input generated using {@link CHtml::activeDateTimeLocalField}</li>
 * <li>week: an HTML5 week input generated using {@link CHtml::activeWeekField}</li>
 * <li>color: an HTML5 color input generated using {@link CHtml::activeColorField}</li>
 * <li>tel: an HTML5 tel input generated using {@link CHtml::activeTelField}</li>
 * <li>search: an HTML5 search input generated using {@link CHtml::activeSearchField}</li>
 * </ul>
 * The {@link type} property can also be a class name or a path alias to the class. In this case,
 * the input is generated using a widget of the specified class. Note, the widget must
 * have a property called "model" which expects a model object, and a property called "attribute"
 * which expects the name of a model attribute.
 *
 * Because CFormElement is an ancestor class of CFormInputElement, a value assigned to a non-existing property will be
 * stored in {@link attributes} which will be passed as HTML attribute values to the {@link CHtml} method
 * generating the input or initial values of the widget properties.
 *
 * @property boolean $required Whether this input is required.
 * @property string $label The label for this input. If the label is not manually set,
 * this method will call {@link CModel::getAttributeLabel} to determine the label.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @package system.web.form
 * @since 1.1
 */
class CFormInputElement extends CFormElement
{
	/**
	 * @var array Core input types (alias=>CHtml method name)
	 */
	public static $coreTypes=array(
		'text'=>'activeTextField',
		'hidden'=>'activeHiddenField',
		'password'=>'activePasswordField',
		'textarea'=>'activeTextArea',
		'file'=>'activeFileField',
		'radio'=>'activeRadioButton',
		'checkbox'=>'activeCheckBox',
		'listbox'=>'activeListBox',
		'dropdownlist'=>'activeDropDownList',
		'checkboxlist'=>'activeCheckBoxList',
		'radiolist'=>'activeRadioButtonList',
		'url'=>'activeUrlField',
		'email'=>'activeEmailField',
		'number'=>'activeNumberField',
		'range'=>'activeRangeField',
		'date'=>'activeDateField',
		'time'=>'activeTimeField',
		'datetime'=>'activeDateTimeField',
		'datetimelocal'=>'activeDateTimeLocalField',
		'week'=>'activeWeekField',
		'color'=>'activeColorField',
		'tel'=>'activeTelField',
		'search'=>'activeSearchField',
	);

	/**
	 * @var string the type of this input. This can be a widget class name, a path alias of a widget class name,
	 * or an input type alias (text, hidden, password, textarea, file, radio, checkbox, listbox, dropdownlist, checkboxlist, or radiolist).
	 * If a widget class, it must extend from {@link CInputWidget} or (@link CJuiInputWidget).
	 */
	public $type;
	/**
	 * @var string name of this input
	 */
	public $name;
	/**
	 * @var string hint text of this input
	 */
	public $hint;
	/**
	 * @var array the options for this input when it is a list box, drop-down list, check box list, or radio button list.
	 * Please see {@link CHtml::listData} for details of generating this property value.
	 */
	public $items=array();
	/**
	 * @var array the options used when rendering the error part. This property will be passed
	 * to the {@link CActiveForm::error} method call as its $htmlOptions parameter.
	 * @see CActiveForm::error
	 * @since 1.1.1
	 */
	public $errorOptions=array();
	/**
	 * @var boolean whether to allow AJAX-based validation for this input. Note that in order to use
	 * AJAX-based validation, {@link CForm::activeForm} must be configured with 'enableAjaxValidation'=>true.
	 * This property allows turning on or off  AJAX-based validation for individual input fields.
	 * Defaults to true.
	 * @since 1.1.7
	 */
	public $enableAjaxValidation=true;
	/**
	 * @var boolean whether to allow client-side validation for this input. Note that in order to use
	 * client-side validation, {@link CForm::activeForm} must be configured with 'enableClientValidation'=>true.
	 * This property allows turning on or off  client-side validation for individual input fields.
	 * Defaults to true.
	 * @since 1.1.7
	 */
	public $enableClientValidation=true;
	/**
	 * @var string the layout used to render label, input, hint and error. They correspond to the placeholders
	 * "{label}", "{input}", "{hint}" and "{error}".
	 */
	public $layout="{label}\n{input}\n{hint}\n{error}";

	private $_label;
	private $_required;

	/**
	 * Gets the value indicating whether this input is required.
	 * If this property is not set explicitly, it will be determined by calling
	 * {@link CModel::isAttributeRequired} for the associated model and attribute of this input.
	 * @return boolean whether this input is required.
	 */
	public function getRequired()
	{
		if($this->_required!==null)
			return $this->_required;
		else
			return $this->getParent()->getModel()->isAttributeRequired($this->name);
	}

	/**
	 * @param boolean $value whether this input is required.
	 */
	public function setRequired($value)
	{
		$this->_required=$value;
	}

	/**
	 * @return string the label for this input. If the label is not manually set,
	 * this method will call {@link CModel::getAttributeLabel} to determine the label.
	 */
	public function getLabel()
	{
		if($this->_label!==null)
			return $this->_label;
		else
			return $this->getParent()->getModel()->getAttributeLabel($this->name);
	}

	/**
	 * @param string $value the label for this input
	 */
	public function setLabel($value)
	{
		$this->_label=$value;
	}

	/**
	 * Renders everything for this input.
	 * The default implementation simply returns the result of {@link renderLabel}, {@link renderInput},
	 * {@link renderHint}. When {@link CForm::showErrorSummary} is false, {@link renderError} is also called
	 * to show error messages after individual input fields.
	 * @return string the complete rendering result for this input, including label, input field, hint, and error.
	 */
	public function render()
	{
		if($this->type==='hidden')
			return $this->renderInput();
		$output=array(
			'{label}'=>$this->renderLabel(),
			'{input}'=>$this->renderInput(),
			'{hint}'=>$this->renderHint(),
			'{error}'=>!$this->getParent()->showErrors ? '' : $this->renderError(),
		);
		return strtr($this->layout,$output);
	}

	/**
	 * Renders the label for this input.
	 * The default implementation returns the result of {@link CHtml activeLabelEx}.
	 * @return string the rendering result
	 */
	public function renderLabel()
	{
		$options = array(
			'label'=>$this->getLabel(),
			'required'=>$this->getRequired()
		);

		if(!empty($this->attributes['id']))
			$options['for']=$this->attributes['id'];

		return CHtml::activeLabel($this->getParent()->getModel(), $this->name, $options);
	}

	/**
	 * Renders the input field.
	 * The default implementation returns the result of the appropriate CHtml method or the widget.
	 * @return string the rendering result
	 */
	public function renderInput()
	{
		if(isset(self::$coreTypes[$this->type]))
		{
			$method=self::$coreTypes[$this->type];
			if(strpos($method,'List')!==false)
				return CHtml::$method($this->getParent()->getModel(), $this->name, $this->items, $this->attributes);
			else
				return CHtml::$method($this->getParent()->getModel(), $this->name, $this->attributes);
		}
		else
		{
			$attributes=$this->attributes;
			$attributes['model']=$this->getParent()->getModel();
			$attributes['attribute']=$this->name;
			ob_start();
			$this->getParent()->getOwner()->widget($this->type, $attributes);
			return ob_get_clean();
		}
	}

	/**
	 * Renders the error display of this input.
	 * The default implementation returns the result of {@link CHtml::error}
	 * @return string the rendering result
	 */
	public function renderError()
	{
		$parent=$this->getParent();
		return $parent->getActiveFormWidget()->error($parent->getModel(), $this->name, $this->errorOptions, $this->enableAjaxValidation, $this->enableClientValidation);
	}

	/**
	 * Renders the hint text for this input.
	 * The default implementation returns the {@link hint} property enclosed in a paragraph HTML tag.
	 * @return string the rendering result.
	 */
	public function renderHint()
	{
		return $this->hint===null ? '' : '<div class="hint">'.$this->hint.'</div>';
	}

	/**
	 * Evaluates the visibility of this element.
	 * This method will check if the attribute associated with this input is safe for
	 * the current model scenario.
	 * @return boolean whether this element is visible.
	 */
	protected function evaluateVisible()
	{
		return $this->getParent()->getModel()->isAttributeSafe($this->name);
	}
}