Yii2: dropDownList pre Selection not rendering 'selected'

Created on 13 Mar 2014  路  16Comments  路  Source: yiisoft/yii2

The issue

It doesn't select the item unless i have a trailing or leading whitespace before or after the attribute word selected.

In my Code bellow, this is how i setup the dropdownlist and set the 'selected' attribute to true or to 'selected'.

This Issue only appears just for 'selected', if i put 'disabled', 'class', 'myfunnyattribute' i renders fine or gets at least displayed in the source code.

My Config

Apache 2.4.6
PHP 5.5.3
Firefox 27.0.1

Inside the View:
$form->field($model, $key, 
                        ['options' => 
                            [
                                'class' => 'col-xs-3'
                            ]
                        ])
                    ->dropDownList(
                        $model->getTeamName(),
                        ['options' =>
                            [
                                $user->$key => ['selected ' => true]
                            ]
                        ]
                    );
Function in Model:
public function getTeamname()
{
    $team = Team::find()->orderBy('teamName')->all();
    return ArrayHelper::map($team, 'teamID', 'teamName');
}
Renderoutput with ['selected' => 'selected']
<option value="9">
    IT Administration
</option>
Renderoutput with ['selected ' => 'selected']
<option selected="selected" value="9">
    IT Administration
</option>
to be verified

Most helpful comment

The best way IMO is to do this directly in the form view:

if($model->isNewRecord) {
    $model->foo = $myDefaultValue;
}

If you set it in init() it will be set whenever a query returns active records which is not great.

All 16 comments

Pretty interesting situation. I had a quick look and it seems that inBaseHtml::renderSelectOptions() on a new record $selection is always null and your selected option gets false. The following change seems to work for me:

$attrs['selected'] = $selection !== null &&
                    (!is_array($selection) && !strcmp($key, $selection)
                        || is_array($selection) && in_array($key, $selection))
                        || $selection === null && isset($attrs['selected']);

I confirm this change makes sense. It is necessary as we need to have a way to define a default value on a new record.

However it's not very practical, I wonder if we could have a $defaultSelection parameter in ActiveField::dropDownList. Maybe it's too much change though.

Generally, we have two main scenarios here. New record and updating an existing record. With the change I highlighted above the custom selected option will be set only on new records. On existing records the selected option will be determined by the record persistent value and the user provided one will be ignored. Not sure if this is ideal it's just an example. Can you expand on how you anticipate this $defaultSelection to behave?

Exactly the way you described it, just an additional parameter to dropDownList's signature as a shortcut for setting

['options' =>
    [
        $defaultSelection => ['selected' => true]
    ]
]

It is just an idea, I'm not sure of its validity though. Your change might be enough.

Why you expect field will set selected for a specific value if $model->$attribute is empty ?

The idea is to be able to set a default value when the value is not set (in a new record for instance).

Example: I have a dropdown with languages, I want to set the default option to English.

Why not just to set new record pre-defined values in init() method ?

Indeed...

This is how i solve this problem.

So do you need any adjustments?

@RusAlex
i had this issue when updating records, in that case $model->attribute was given. When i was trying to set the selected option via an html option it just wouldn't render if there wasn't a whitespace behind the selected attribute. But as i found a different way to select it, probably the right way, that's solved for me then :+1:

@samdark: for me, its fine now :+1:

The best way IMO is to do this directly in the form view:

if($model->isNewRecord) {
    $model->foo = $myDefaultValue;
}

If you set it in init() it will be set whenever a query returns active records which is not great.

If you set it in init() it will be set whenever a query returns active records which is not great.

the field value should get overridden when data is loaded from db.
See https://github.com/yiisoft/yii2/blob/master/framework/db/BaseActiveRecord.php#L1034

I think there should be another reserved option (defaultValue or something) in the options attribute where you would define which option is selected by default (in case $model->isNewRecord is true).

All other solutions mentioned here aren't the best in my opinion. A lot of times this pre-defined option is a matter of just certain view (form) and you don't want to define it globally (in init()).

I have the same problem.

<?php echo $form->field($malfunctionModel, 'category_id')->dropDownList(
   ArrayHelper::map($categoryModel, 'id', 'title'), [
      'options' => [
         3 => ['selected' => 'selected']
     ]
]); ?>

This doesn't work.
But ['selected ' => 'selected'] - works. Tab after selected )))

Was this page helpful?
0 / 5 - 0 ratings

Related issues

indicalabs picture indicalabs  路  3Comments

Locustv2 picture Locustv2  路  3Comments

skcn022 picture skcn022  路  3Comments

AstRonin picture AstRonin  路  3Comments

sobit picture sobit  路  3Comments