diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md
index f624c4437d..35e7942bd8 100644
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -4,7 +4,6 @@ Yii Framework 2 Change Log
2.0.3 under development
-----------------------
-- Enh #7449: `yii\helpers\Html::dropDownList()` and `yii\helpers\Html::listBox()` now supports Unicode characters in option text (yapi68)
- Bug #5457: `yii\web\Cors` should handle `Access-Control-Request-Headers` in a case-insensitive manner (qiangxue)
- Bug #6919: Fixed wrong namespaces under advanced application's TestCase classes (ivokund)
- Bug #6940: `yii\web\Response::sendContentAsFile()` may not send correct `content-length` header (sadgnome)
@@ -43,6 +42,7 @@ Yii Framework 2 Change Log
- Enh #7357: Refactored `yii\db\ColumnSchema` by adding `typecast()` method to decouple `phpTypecast()` from `dbTypecast()` (mcd-php, qiangxue)
- Enh #7361: The `trim` validator now works on the client side too (qiangxue)
- Enh #7446: Added `Schema::DOUBLE` to represent ANSI SQL Double Precision type (samdark)
+- Enh #7449: Added `encode` option to allow not encoding select options for `Html::dropDownList()` and `Html::listBox()` (yapi68, qiangxue)
- Enh: Added support to `yii\di\Container` to instantiate and configure an object that implements `yii\base\Configurable` (qiangxue)
- Chg #5690: adjusted paths in message config generated by `yii message/config` to reflect directory structure better (mikehaertl, samdark)
- Chg #6661: Hyperlinks that are enclosed within an exist form will use the same form for submission if they specify both of the `href` and `data-method` attributes (qiangxue)
diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php
index b721a0d30a..5fa47a53fb 100644
--- a/framework/helpers/BaseHtml.php
+++ b/framework/helpers/BaseHtml.php
@@ -735,8 +735,10 @@ class BaseHtml
*
* - groups: array, the attributes for the optgroup tags. The structure of this is similar to that of 'options',
* except that the array keys represent the optgroup labels specified in $items.
+ * - encodeSpaces: bool, whether to encode spaces in option prompt and option value with ` ` character.
+ * Defaults to false.
* - encode: bool, whether to encode option prompt and option value characters.
- * Defaults to `true`.
+ * Defaults to `true`. This option is available since 2.0.3.
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
@@ -785,8 +787,10 @@ class BaseHtml
* - unselect: string, the value that will be submitted when no option is selected.
* When this attribute is set, a hidden field will be generated so that if no option is selected in multiple
* mode, we can still obtain the posted unselect value.
+ * - encodeSpaces: bool, whether to encode spaces in option prompt and option value with ` ` character.
+ * Defaults to false.
* - encode: bool, whether to encode option prompt and option value characters.
- * Defaults to `true`.
+ * Defaults to `true`. This option is available since 2.0.3.
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
@@ -1373,8 +1377,10 @@ class BaseHtml
*
* - groups: array, the attributes for the optgroup tags. The structure of this is similar to that of 'options',
* except that the array keys represent the optgroup labels specified in $items.
+ * - encodeSpaces: bool, whether to encode spaces in option prompt and option value with ` ` character.
+ * Defaults to false.
* - encode: bool, whether to encode option prompt and option value characters.
- * Defaults to `true`.
+ * Defaults to `true`. This option is available since 2.0.3.
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
@@ -1423,8 +1429,10 @@ class BaseHtml
* - unselect: string, the value that will be submitted when no option is selected.
* When this attribute is set, a hidden field will be generated so that if no option is selected in multiple
* mode, we can still obtain the posted unselect value.
+ * - encodeSpaces: bool, whether to encode spaces in option prompt and option value with ` ` character.
+ * Defaults to false.
* - encode: bool, whether to encode option prompt and option value characters.
- * Defaults to `true`.
+ * Defaults to `true`. This option is available since 2.0.3.
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
@@ -1558,22 +1566,27 @@ class BaseHtml
public static function renderSelectOptions($selection, $items, &$tagOptions = [])
{
$lines = [];
+ $encodeSpaces = ArrayHelper::remove($tagOptions, 'encodeSpaces', false);
$encode = ArrayHelper::remove($tagOptions, 'encode', true);
if (isset($tagOptions['prompt'])) {
$prompt = $encode ? static::encode($tagOptions['prompt']) : $tagOptions['prompt'];
+ if ($encodeSpaces) {
+ $prompt = str_replace(' ', ' ', $prompt);
+ }
$lines[] = static::tag('option', $prompt, ['value' => '']);
}
$options = isset($tagOptions['options']) ? $tagOptions['options'] : [];
$groups = isset($tagOptions['groups']) ? $tagOptions['groups'] : [];
unset($tagOptions['prompt'], $tagOptions['options'], $tagOptions['groups']);
+ $options['encodeSpaces'] = ArrayHelper::getValue($options, 'encodeSpaces', $encodeSpaces);
$options['encode'] = ArrayHelper::getValue($options, 'encode', $encode);
foreach ($items as $key => $value) {
if (is_array($value)) {
$groupAttrs = isset($groups[$key]) ? $groups[$key] : [];
$groupAttrs['label'] = $key;
- $attrs = ['options' => $options, 'groups' => $groups, 'encode' => $encode];
+ $attrs = ['options' => $options, 'groups' => $groups, 'encodeSpaces' => $encodeSpaces, 'encode' => $encode];
$content = static::renderSelectOptions($selection, $value, $attrs);
$lines[] = static::tag('optgroup', "\n" . $content . "\n", $groupAttrs);
} else {
@@ -1582,7 +1595,11 @@ class BaseHtml
$attrs['selected'] = $selection !== null &&
(!is_array($selection) && !strcmp($key, $selection)
|| is_array($selection) && in_array($key, $selection));
- $lines[] = static::tag('option', ($encode ? static::encode($value) : $value), $attrs);
+ $text = $encode ? static::encode($value) : $value;
+ if ($encodeSpaces) {
+ $text = str_replace(' ', ' ', $text);
+ }
+ $lines[] = static::tag('option', $text, $attrs);
}
}
diff --git a/tests/unit/framework/helpers/HtmlTest.php b/tests/unit/framework/helpers/HtmlTest.php
index a1c731e6d2..f38b0e6a9d 100644
--- a/tests/unit/framework/helpers/HtmlTest.php
+++ b/tests/unit/framework/helpers/HtmlTest.php
@@ -296,7 +296,21 @@ EOD;
EOD;
- $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2(), ['encode' => true]));
+ $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2(), ['encodeSpaces' => true]));
+ $expected = <<
+
+
+
+EOD;
+ $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2(), ['encode' => false]));
+ $expected = <<
+
+
+
+EOD;
+ $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2(), ['encodeSpaces' => true, 'encode' => false]));
$expected = <<
@@ -499,7 +513,7 @@ EOD;
'groups' => [
'group12' => ['class' => 'group'],
],
- 'encode' => true,
+ 'encodeSpaces' => true,
];
$this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['value111', 'value1'], $data, $attributes));