From 8ac7f9b53d4c0085bf2a4e85d8812ad7056c4e41 Mon Sep 17 00:00:00 2001 From: Eugene Tupikov Date: Sun, 26 Jul 2015 20:03:42 +0600 Subject: [PATCH] Fix display inline errors in case using form without ajax validation --- docs/multiple_columns.md | 1 + examples/actions/MultipleInputAction.php | 8 ++++-- examples/models/ExampleModel.php | 16 ++++++----- src/MultipleInput.php | 17 +++++++----- src/MultipleInputColumn.php | 34 +++++++++++++++++++++--- 5 files changed, 57 insertions(+), 19 deletions(-) diff --git a/docs/multiple_columns.md b/docs/multiple_columns.md index a1d6b56..b04d267 100644 --- a/docs/multiple_columns.md +++ b/docs/multiple_columns.md @@ -86,6 +86,7 @@ use yii\helpers\Html; [ 'name' => 'priority', 'title' => 'Priority', + 'enableError' => true, 'options' => [ 'class' => 'input-priority' ] diff --git a/examples/actions/MultipleInputAction.php b/examples/actions/MultipleInputAction.php index 9b36253..2b54f88 100644 --- a/examples/actions/MultipleInputAction.php +++ b/examples/actions/MultipleInputAction.php @@ -28,9 +28,13 @@ public function run() return $result; } - if ($model->load(Yii::$app->request->post()) && $model->validate()) { - + if ($model->load(Yii::$app->request->post())) { + if (!$model->validate()) { + Yii::error('Validation errors: ' . print_r($model->getErrors(), true)); + } } + + return $this->controller->render('@unclead-examples/views/example.php', ['model' => $model]); } } \ No newline at end of file diff --git a/examples/models/ExampleModel.php b/examples/models/ExampleModel.php index d011cb3..432c578 100644 --- a/examples/models/ExampleModel.php +++ b/examples/models/ExampleModel.php @@ -43,12 +43,12 @@ public function init() $this->schedule = [ [ 'day' => '27.02.2015', - 'user_id' => 1, + 'user_id' => 31, 'priority' => 1 ], [ 'day' => '27.02.2015', - 'user_id' => 2, + 'user_id' => 33, 'priority' => 2 ], ]; @@ -139,10 +139,14 @@ public function validateSchedule($attribute) foreach($this->$attribute as $index => $row) { $error = null; - $requiredValidator->validate($row['priority'], $error); - if (!empty($error)) { - $key = $attribute . '[' . $index . '][priority]'; - $this->addError($key, $error); + foreach (['user_id', 'priority'] as $name) { + $error = null; + $value = isset($row[$name]) ? $row[$name] : null; + $requiredValidator->validate($value, $error); + if (!empty($error)) { + $key = $attribute . '[' . $index . '][' . $name . ']'; + $this->addError($key, $error); + } } } } diff --git a/src/MultipleInput.php b/src/MultipleInput.php index b9a0680..d9bc752 100644 --- a/src/MultipleInput.php +++ b/src/MultipleInput.php @@ -253,8 +253,8 @@ private function renderRowContent($index = null, $data = null) private function collectJsTemplates() { if (is_array($this->getView()->js) && array_key_exists(View::POS_READY, $this->getView()->js)) { - $this->jsTemplates = []; - foreach ($this->getView()->js[View::POS_READY] as $key => $js) { + $this->jsTemplates = []; + foreach ($this->getView()->js[View::POS_READY] as $key => $js) { if (preg_match('/^.*' . $this->options['id'] . '-{multiple-index}.*$/', $js) === 1) { $this->jsTemplates[] = $js; unset($this->getView()->js[View::POS_READY][$key]); @@ -301,17 +301,20 @@ private function renderActionColumn($index = null) * Returns element's name. * * @param string $name the name of cell element - * @param int|null $index + * @param int|null $index current row index + * @param bool $withPrefix whether to add prefix. * @return string */ - public function getElementName($name, $index) + public function getElementName($name, $index, $withPrefix = true) { if (is_null($index)) { $index = '{multiple-index}'; } - return $this->getInputNamePrefix($name) . ( - count($this->columns) > 1 ? '[' . $index . '][' . $name . ']' : '[' . $name . '][' . $index . ']' - ); + $elementName = count($this->columns) > 1 + ? '[' . $index . '][' . $name . ']' + : '[' . $name . '][' . $index . ']'; + $prefix = $withPrefix ? $this->getInputNamePrefix($name) : ''; + return $prefix . $elementName; } /** diff --git a/src/MultipleInputColumn.php b/src/MultipleInputColumn.php index c79483b..7a7543c 100644 --- a/src/MultipleInputColumn.php +++ b/src/MultipleInputColumn.php @@ -92,6 +92,10 @@ public function init() throw new InvalidConfigException("The 'name' option is required."); } + if ($this->enableError && empty($this->widget->model)) { + throw new InvalidConfigException('Property "enableError" available only when model is defined.'); + } + if (is_null($this->type)) { $this->type = self::TYPE_TEXT_INPUT; } @@ -207,16 +211,38 @@ public function renderCellContent($value, $index) return $input; } + $hasError = false; if ($this->enableError) { - $input .= "\n" . Html::tag('div', '', $this->errorOptions); + $attribute = $this->widget->attribute . $this->widget->getElementName($this->name, $index, false); + $error = $this->widget->model->getFirstError($attribute); + $hasError = !empty($error); + $input .= "\n" . $this->renderError($error); } - $input = Html::tag('div', $input, [ - 'class' => 'form-group field-' . $options['id'], - ]); + $wrapperOptions = [ + 'class' => 'form-group field-' . $options['id'] + ]; + + if ($hasError) { + Html::addCssClass($wrapperOptions, 'has-error'); + } + $input = Html::tag('div', $input, $wrapperOptions); return Html::tag('td', $input, [ 'class' => 'list-cell__' . $this->name, ]); } + + /** + * @param string $error + * @return string + */ + private function renderError($error) + { + $options = $this->errorOptions; + $tag = isset($options['tag']) ? $options['tag'] : 'div'; + $encode = !isset($options['encode']) || $options['encode'] !== false; + unset($options['tag'], $options['encode']); + return Html::tag($tag, $encode ? Html::encode($error) : $error, $options); + } } \ No newline at end of file