diff --git a/extensions/bootstrap/ActiveField.php b/extensions/bootstrap/ActiveField.php index 35e1db8ffb..6c026c0661 100644 --- a/extensions/bootstrap/ActiveField.php +++ b/extensions/bootstrap/ActiveField.php @@ -207,8 +207,7 @@ class ActiveField extends \yii\widgets\ActiveField $this->labelOptions['class'] = null; } - parent::checkbox($options, false); - return $this; + return parent::checkbox($options, false); } /** @@ -230,8 +229,7 @@ class ActiveField extends \yii\widgets\ActiveField $this->labelOptions['class'] = null; } - parent::radio($options, false); - return $this; + return parent::radio($options, false); } /** diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 58e70ce3f7..0f3eadec3e 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -289,6 +289,7 @@ Yii Framework 2 Change Log - Chg: `yii\web\Request::cookieValidationKey` must be explicitly specified for each application that wants to use cookie validation (qiangxue) - Chg: Added `yii\composer\Installer::postCreateProject()` and modified the syntax of calling installer methods in composer.json (qiangxue) - Chg: When an ID is found to be in both `Application::controllerMap` and `Application::modules`, the former will take precedence (qiangxue) +- Chg: `yii\helpers\Html::activeCheckbox()` and `activeRadio()` will generate labels by default using the corresponding attribute labels (qiangxue) - New #1280: Gii can now be run from command line (schmunk42, cebe, qiangxue) - New #3911: Added `yii\behaviors\SluggableBehavior` that fills the specified model attribute with the transliterated and adjusted version to use in URLs (creocoder) - New #4193: Added `yii\filters\Cors` CORS filter to allow Cross Origin Resource Sharing (pgaultier) diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php index 83972b2420..829632b288 100644 --- a/framework/helpers/BaseHtml.php +++ b/framework/helpers/BaseHtml.php @@ -1232,7 +1232,7 @@ class BaseHtml } /** - * Generates a radio button tag for the given model attribute. + * Generates a radio button tag together with a label for the given model attribute. * This method will generate the "checked" tag attribute according to the model attribute value. * @param Model $model the model object * @param string $attribute the attribute name or expression. See [[getAttributeName()]] for the format @@ -1245,7 +1245,9 @@ class BaseHtml * via the hidden input. * - label: string, a label displayed next to the radio button. It will NOT be HTML-encoded. Therefore you can pass * in HTML code such as an image tag. If this is is coming from end users, you should [[encode()]] it to prevent XSS attacks. - * When this option is specified, the radio button will be enclosed by a label tag. + * The radio button will be enclosed by the label tag. Note that if you do not specify this option, a default label + * will be used based on the attribute label declaration in the model. If you do not want any label, you should + * explicitly set this option as null. * - labelOptions: array, the HTML attributes for the label tag. This is only used when the "label" option is specified. * * The rest of the options will be rendered as the attributes of the resulting tag. The values will @@ -1266,6 +1268,9 @@ class BaseHtml if (!array_key_exists('uncheck', $options)) { $options['uncheck'] = '0'; } + if (!array_key_exists('label', $options)) { + $options['label'] = static::encode($model->getAttributeLabel(static::getAttributeName($attribute))); + } $checked = "$value" === "{$options['value']}"; @@ -1277,7 +1282,7 @@ class BaseHtml } /** - * Generates a checkbox tag for the given model attribute. + * Generates a checkbox tag together with a label for the given model attribute. * This method will generate the "checked" tag attribute according to the model attribute value. * @param Model $model the model object * @param string $attribute the attribute name or expression. See [[getAttributeName()]] for the format @@ -1290,7 +1295,9 @@ class BaseHtml * via the hidden input. * - label: string, a label displayed next to the checkbox. It will NOT be HTML-encoded. Therefore you can pass * in HTML code such as an image tag. If this is is coming from end users, you should [[encode()]] it to prevent XSS attacks. - * When this option is specified, the checkbox will be enclosed by a label tag. + * The checkbox will be enclosed by the label tag. Note that if you do not specify this option, a default label + * will be used based on the attribute label declaration in the model. If you do not want any label, you should + * explicitly set this option as null. * - labelOptions: array, the HTML attributes for the label tag. This is only used when the "label" option is specified. * * The rest of the options will be rendered as the attributes of the resulting tag. The values will @@ -1310,6 +1317,9 @@ class BaseHtml if (!array_key_exists('uncheck', $options)) { $options['uncheck'] = '0'; } + if (!array_key_exists('label', $options)) { + $options['label'] = static::encode($model->getAttributeLabel(static::getAttributeName($attribute))); + } $checked = "$value" === "{$options['value']}"; diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index 5bc62818d0..d19d6374c5 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -436,13 +436,16 @@ class ActiveField extends Component public function radio($options = [], $enclosedByLabel = true) { if ($enclosedByLabel) { - if (!isset($options['label'])) { - $attribute = Html::getAttributeName($this->attribute); - $options['label'] = Html::encode($this->model->getAttributeLabel($attribute)); - } $this->parts['{input}'] = Html::activeRadio($this->model, $this->attribute, $options); $this->parts['{label}'] = ''; } else { + if (isset($options['label']) && !isset($this->parts['{label}'])) { + $this->parts['{label}'] = $options['label']; + if (!empty($options['labelOptions'])) { + $this->labelOptions = $options['labelOptions']; + } + } + unset($options['label'], $options['labelOptions']); $this->parts['{input}'] = Html::activeRadio($this->model, $this->attribute, $options); } $this->adjustLabelFor($options); @@ -474,13 +477,16 @@ class ActiveField extends Component public function checkbox($options = [], $enclosedByLabel = true) { if ($enclosedByLabel) { - if (!isset($options['label'])) { - $attribute = Html::getAttributeName($this->attribute); - $options['label'] = Html::encode($this->model->getAttributeLabel($attribute)); - } $this->parts['{input}'] = Html::activeCheckbox($this->model, $this->attribute, $options); $this->parts['{label}'] = ''; } else { + if (isset($options['label']) && !isset($this->parts['{label}'])) { + $this->parts['{label}'] = $options['label']; + if (!empty($options['labelOptions'])) { + $this->labelOptions = $options['labelOptions']; + } + } + unset($options['label'], $options['labelOptions']); $this->parts['{input}'] = Html::activeCheckbox($this->model, $this->attribute, $options); } $this->adjustLabelFor($options);