diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 9bb585d772..2e71b2193e 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -21,6 +21,7 @@ Yii Framework 2 Change Log - Bug #3204: `yii\di\Container` did not handle the `$config` parameter well in case when it does not have a default value (qiangxue) - Bug #3216: Fixed the bug that `yii.activeForm.destroy()` did not remove `submit` event handlers (qiangxue) - Enh #2837: Error page now shows arguments in stack trace method calls (samdark) +- Enh #3008: Added `Html::errorSummary()` (qiangxue) - Enh #3088: The debug and gii modules will manage their own URL rules now (hiltonjanfield, qiangxue) - Enh #3103: debugger panel is now not displayed when printing a page (githubjeka) - Enh #3108: Added `yii\debug\Module::enableDebugLogs` to disable logging debug logs by default (qiangxue) diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php index 95cf2e0593..7f81db7a89 100644 --- a/framework/helpers/BaseHtml.php +++ b/framework/helpers/BaseHtml.php @@ -1031,6 +1031,43 @@ class BaseHtml return static::label($label, $for, $options); } + /** + * Generates a summary of the validation errors. + * If there is no validation error, an empty error summary markup will still be generated, but it will be hidden. + * @param Model|Model[] $models the model(s) whose validation errors are to be displayed + * @param array $options the tag options in terms of name-value pairs. The following options are specially handled: + * + * - header: string, the header HTML for the error summary. If not set, a default prompt string will be used. + * - footer: string, the footer HTML for the error summary. + * + * The rest of the options will be rendered as the attributes of the container tag. The values will + * be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. + * @return string the generated error summary + */ + public static function errorSummary($models, $options = []) + { + $lines = []; + foreach ((array)$models as $model) { + /** @var Model $model */ + foreach ($model->getFirstErrors() as $error) { + $lines[] = Html::encode($error); + } + } + + $header = isset($options['header']) ? $options['header'] : '

' . Yii::t('yii', 'Please fix the following errors:') . '

'; + $footer = isset($options['footer']) ? $options['footer'] : ''; + unset($options['header'], $options['footer']); + + if (empty($lines)) { + // still render the placeholder for client-side validation use + $content = ""; + $options['style'] = isset($options['style']) ? rtrim($options['style'], ';') . '; display:none' : 'display:none'; + } else { + $content = ""; + } + return Html::tag('div', $header . $content . $footer, $options); + } + /** * Generates a tag that contains the first validation error of the specified model attribute. * Note that even if there is no validation error, this method will still return an empty error tag. diff --git a/framework/widgets/ActiveForm.php b/framework/widgets/ActiveForm.php index f9695bdf4b..497d1fd5b8 100644 --- a/framework/widgets/ActiveForm.php +++ b/framework/widgets/ActiveForm.php @@ -217,41 +217,12 @@ class ActiveForm extends Widget * The rest of the options will be rendered as the attributes of the container tag. The values will * be HTML-encoded using [[\yii\helpers\Html::encode()]]. If a value is null, the corresponding attribute will not be rendered. * @return string the generated error summary + * @see errorSummaryCssClass */ public function errorSummary($models, $options = []) { - if (!is_array($models)) { - $models = [$models]; - } - - $lines = []; - foreach ($models as $model) { - /** @var Model $model */ - foreach ($model->getFirstErrors() as $error) { - $lines[] = Html::encode($error); - } - } - - $header = isset($options['header']) ? $options['header'] : '

' . Yii::t('yii', 'Please fix the following errors:') . '

'; - $footer = isset($options['footer']) ? $options['footer'] : ''; - unset($options['header'], $options['footer']); - - if (!isset($options['class'])) { - $options['class'] = $this->errorSummaryCssClass; - } else { - $options['class'] .= ' ' . $this->errorSummaryCssClass; - } - - if (!empty($lines)) { - $content = ""; - - return Html::tag('div', $header . $content . $footer, $options); - } else { - $content = ""; - $options['style'] = isset($options['style']) ? rtrim($options['style'], ';') . '; display:none' : 'display:none'; - - return Html::tag('div', $header . $content . $footer, $options); - } + Html::addCssClass($options, $this->errorSummaryCssClass); + return Html::errorSummary($models, $options); } /**