Christoffer Niska avatar Christoffer Niska committed 65d09a9

fixed some issues with forms (fixes #74, fixes #71, fixes #40, fixes #30)

Comments (0)

Files changed (5)

widgets/BootActiveForm.php

 	/**
 	 * @var boolean flag that indicates if the errors should be displayed as blocks.
 	 */
-	public $inlineErrors = true;
+	public $inlineErrors;
 
 	/**
 	 * Initializes the widget.
 		else
 			$this->htmlOptions['class'] .= ' form-'.$this->type;
 
+		if (!isset($this->inlineErrors))
+			$this->inlineErrors = $this->type === self::TYPE_HORIZONTAL;
+
 		if ($this->inlineErrors)
-			$this->errorMessageCssClass = 'help-inline';
+			$this->errorMessageCssClass = 'help-inline error';
 		else
-			$this->errorMessageCssClass = 'help-block';
+			$this->errorMessageCssClass = 'help-block error';
 
 		parent::init();
 	}
 
 		if ($model->hasErrors($attribute))
 		{
-			if(isset($htmlOptions['class']))
+			if (isset($htmlOptions['class']))
 				$htmlOptions['class'] .= ' '.CHtml::$errorCss;
 			else
 				$htmlOptions['class'] = CHtml::$errorCss;
 		$labelCssClass = $checkbox ? 'checkbox' : 'radio';
 
 		if (isset($htmlOptions['inline']))
-        {
-                $labelCssClass .= ' inline';
-                unset($htmlOptions['inline']);
-        }
+		{
+			$labelCssClass .= ' inline';
+			unset($htmlOptions['inline']);
+		}
 
 		foreach ($data as $value => $label)
 		{
 			$option = CHtml::$method($name, $checked, $htmlOptions);
 			$label = CHtml::label($label, $htmlOptions['id'], $labelOptions);
 			$items[] = strtr($template, array(
-				'{labelCssClass}'=>$labelCssClass,
-				'{input}'=>$option,
-				'{label}'=>$label,
+				'{labelCssClass}' => $labelCssClass,
+				'{input}' => $option,
+				'{label}' => $label,
 			));
 		}
 
 			$htmlOptions['class'] = $this->errorMessageCssClass;
 
 		if (!$enableAjaxValidation && !$enableClientValidation)
-			return $this->getErrorHtml($model, $attribute, $htmlOptions);
+			return $this->renderError($model, $attribute, $htmlOptions);
 
 		$id = CHtml::activeId($model,$attribute);
 		$inputID = isset($htmlOptions['inputID']) ? $htmlOptions['inputID'] : $id;
 		if ($enableClientValidation)
 		{
 			$validators = isset($htmlOptions['clientValidation']) ? array($htmlOptions['clientValidation']) : array();
-			foreach ($model->getValidators($attribute) as $validator)
+
+			$attributeName = $attribute;
+			if (($pos = strrpos($attribute, ']')) !== false && $pos !== strlen($attribute) - 1) // e.g. [a]name
+				$attributeName = substr($attribute, $pos + 1);
+
+			foreach ($model->getValidators($attributeName) as $validator)
 			{
-				if ($enableClientValidation && $validator->enableClientValidation)
-				{
-					if (($js = $validator->clientValidateAttribute($model,$attribute)) != '')
+				if ($validator->enableClientValidation)
+					if (($js = $validator->clientValidateAttribute($model, $attributeName)) != '')
 						$validators[] = $js;
-				}
 			}
 
 			if ($validators !== array())
-				$option['clientValidation']="js:function(value, messages, attribute) {\n".implode("\n",$validators)."\n}";
+				$option['clientValidation'] = "js:function(value, messages, attribute) {\n".implode("\n", $validators)."\n}";
 		}
 
-		$html = $this->getErrorHtml($model, $attribute, $htmlOptions);
+		$html = $this->renderError($model, $attribute, $htmlOptions);
 
 		if ($html === '')
 		{
 			if (isset($htmlOptions['style']))
-				$htmlOptions['style'] = rtrim($htmlOptions['style'], ';').';display: none';
+				$htmlOptions['style'] = rtrim($htmlOptions['style'], ';').'; display: none';
 			else
 				$htmlOptions['style'] = 'display: none';
 
 		}
 
 		$this->attributes[$inputID] = $option;
+
 		return $html;
 	}
 
 	 * @param CModel $model the data model
 	 * @param string $attribute the attribute name
 	 * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag.
-	 * @param string $tag the tag to use for rendering the error.
 	 * @return string the error display. Empty if no errors are found.
 	 * @see CModel::getErrors
 	 * @see errorMessageCss
 	 */
-	public static function getErrorHtml($model, $attribute, $htmlOptions = array())
+	protected static function renderError($model, $attribute, $htmlOptions = array())
 	{
-		CHtml::resolveName($model, $attribute);
+		CHtml::resolveName($model, $attribute); // turn [a][b]attr into attr
 		$error = $model->getError($attribute);
-
-		if ($error !== null)
-			return CHtml::tag('span', $htmlOptions, $error); // Bootstrap errors must be spans
-		else
-			return '';
+		return $error != '' ? CHtml::tag('span', $htmlOptions, $error) : '';
 	}
 
 	/**

widgets/input/BootInput.php

 	 */
 	protected function getAttributeId($attribute) 
 	{
-		return isset($this->htmlOptions['id']) ? $this->htmlOptions['id'] : 
-			CHtml::getIdByName(CHtml::resolveName($this->model, $attribute));
+		return isset($this->htmlOptions['id'])
+				? $this->htmlOptions['id']
+				: CHtml::getIdByName(CHtml::resolveName($this->model, $attribute));
 	}
 
 	/**
 	 */
 	protected function getContainerCssClass()
 	{
-		if ($this->model->hasErrors(CHtml::resolveName($this->model, $this->attribute)))
-			return CHtml::$errorCss;
-		else
-			return '';
+		$attribute = $this->attribute;
+		return $this->model->hasErrors(CHtml::resolveName($this->model, $attribute)) ? CHtml::$errorCss : '';
 	}
 
 	/**

widgets/input/BootInputHorizontal.php

 	{
 		$attribute = $this->attribute;
 		echo '<div class="controls">';
-		echo '<label class="radio" for="'.CHtml::getIdByName(CHtml::resolveName($this->model, $attribute)).'">';
+		echo '<label class="radio" for="'.$this->getAttributeId($attribute).'">';
 		echo $this->form->radioButton($this->model, $attribute, $this->htmlOptions).PHP_EOL;
 		echo $this->model->getAttributeLabel($attribute);
 		echo $this->getError().$this->getHint();

widgets/input/BootInputSearch.php

 	 * Renders a text field.
 	 * @return string the rendered content
 	 */
-	protected function textField()
+	protected function searchField()
 	{
 		$classes = 'search-query';
 		if (isset($this->htmlOptions['class']))

widgets/input/BootInputVertical.php

 	protected function radioButton()
 	{
 		$attribute = $this->attribute;
-		echo '<label class="radio" for="'.CHtml::getIdByName(CHtml::resolveName($this->model, $attribute)).'">';
+		echo '<label class="radio" for="'.$this->getAttributeId($attribute).'">';
 		echo $this->form->radioButton($this->model, $this->attribute, $this->htmlOptions).PHP_EOL;
 		echo $this->model->getAttributeLabel($attribute);
 		echo $this->getError().$this->getHint();
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.