yii2: ActiveForm dropDownList does not set the selected option properly if the underlying model's attribute is of boolean type
What steps will reproduce the problem?
We have a model
class MyModel extends Model
{
public ?bool $value = false;
}
and in some view, we render an an ActiveForm
<div>
<?php $form = ActiveForm::begin([
'action' => '/some/path',
'method' => 'GET'
]) ?>
<?php $form->field($model, 'value')->textInput()->label(
'text')->dropDownList([true => 'Yes', false => 'No'], ['prompt' => 'Please select']) ?>
</div>
What is the expected result?
I expect the rendered dropDownList to have a selection of 'Yes' when $value is true and 'No' when $value is false.
What do you get instead?
The dropDownList always shows the prompt instead.
Additional info
| Q | A |
|---|---|
| Yii version | 2.0.45 |
| PHP version | 8.1.2 |
| Operating system | Debian |
The problem is to be found in https://github.com/yiisoft/yii2/blob/2874e070f3ad88c727b1335ba4f4515855bf5f64/framework/helpers/BaseHtml.php#L1916-L1918 and the fact that arrays with boolean keys are indexed with 0 and 1 in php. When getting to this point
gettype($key) // integer
$key // 0
gettype($selection) // boolean
$selection // false
and
!strcmp($key, $selection)
does not give back that they are equal.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 22 (22 by maintainers)
Commits related to this issue
- Fix #19324 by allowing for direct comparison — committed to adnandautovic/yii2 by adnandautovic 2 years ago
- merge upstream (#3) * Added missing note for $categoryMap (#18834) * fix invalid link & update (#18835) * Fix #18823: Rollback changes #18806 in `yii\validators\ExistValidator::checkTargetRelat... — committed to yus-ham/yii2 by yus-ham 2 years ago
- merge upstream (#4) * Added missing note for $categoryMap (#18834) * fix invalid link & update (#18835) * Fix #18823: Rollback changes #18806 in `yii\validators\ExistValidator::checkTargetRelat... — committed to yus-ham/yii2 by yus-ham 2 years ago
- 19324 dropdownlist selection for boolean attributes (#19331) * Fix #19324 by allowing for direct comparison * Invert meaning of strict * Remove WinterSilence from authors list * Fix improper... — committed to maxodrom/yii2 by adnandautovic 2 years ago
@WinterSilence Thank you for the suggestion, but, you see, these getter and setter functions do not solve the problem in the
renderSelectOptionsfunction.The setting of the value works perfectly fine (although your code for doing so is shorter than what I wrote above when there is only one boolean variable in the model). It is when the value is read inside of
renderSelectOptionsand the booleanfalseis compared to the integer0inside ofstrcmpthat the comparison fails. Have you looked at the function in a debugger?And will my pull request #19331 be considered as a fix? Currently, it is not clear to me whether this issue has been recognized/accepted as a bug.
['No', 'Yes']converts to[['value' => '0', 'text' => 'No'], ['value' => '1', 'text' => 'Yes']], prepend prompt:[['value' => '', 'text' => 'Please select'], ['value' => '0', 'text' => 'No'], ['value' => '1', 'text' => 'Yes']](string)falseis''i.e. prompt valueAn array keys can be
intorstring. Your boolean keys converted to strings.