Yii2: dropDownList exception on array nested

Created on 13 Mar 2018  路  12Comments  路  Source: yiisoft/yii2

The render of dropDownList as active field in an active form generate an array to string conversion exception. The same view with the same data structure with version 2.0.12 not generate the same error. The array is structured as follow:

[
  $key1 => [
      $key11 => $val11,
      $key12 => $val12,
  ],
  $key2 => [
     $key21 => $val21,
     $key22 => $val22,
  ],
...
]

In the version 2.0.12 the result is a render of a select wich have the options grouped by main key (in the data structure example $key1 and $ke2)

Temporary the substitution of the class BaseHtml with the same of the 2.0.12 version solve the problem.

Additional info

| Q | A
| ---------------- | ---
| Yii version | 2.0.14.1
| PHP version | 7.0
| Operating system | Ubuntu 16

BC breaking to be verified bug

Most helpful comment

@Bertagit I think you are mixing things up, like @Alex-Code said.
You can surely set a default value for attributes, but the value needs to make sense for your application.

You said that you override the init() method to populate the TempleCode with the possible values, but TempleCode only need to carry a single code that user will choose in the dropdown (Correct me if I'm wrong);

If so I suggest you to refact your model. Remove the part that you are assign TempleCode in model's init() method. And add a method like that in your model:

public function getTempleCodeOptions()
{
    // return the array of possible temple code options
}

and you can build a dropDownList like that:

<?= $form->field($model, 'TempleCode')->dropDownList($model->getTempleCodeOptions(), ['prompt' => 'text-prompt','class' => 'form-control select2',]) ?>

All 12 comments

Thank you for the report. Would you like to help us fixing this bug by submitting a pull request?

Yes sure! I'm not sure to know how do a pull request but this is the moment to learn!

Are you able to reproduce with a small example?
This works fine for me on 2.0.14.1,

echo yii\helpers\Html::activeDropDownList($model, 'test', [
  '$key1' => [
      '$key11' => '$val11',
      '$key12' => '$val12',
  ],
  '$key2' => [
     '$key21' => '$val21',
     '$key22' => '$val22',
  ],
]);

image

I can send the original array, can this help or you need more data?

More data is good :)
Can you show the part of the view that renders the dropdown?

<?= $form->field($model, 'TempleCode')->dropDownList($model->TempleCode, [  'prompt' => 'text-prompt','class' => 'form-control select2',]) ?>

$form is an instance of ActiveForm widget, follow the dump of $model->TempleCode

array(2) {
  [140]=>
  array(14) {
    ["ASP0000434"]=>
    string(24) "ASTE SO 140mm C045(BLUE)"
    ["ASP0000436"]=>
    string(40) "ASTE SO 140mm C549(DARK RED BLACK HAVAN)"
    ["ASP0000437"]=>
    string(25) "ASTE SO 140mm C001(BLACK)"
    ["ASP0000440"]=>
    string(29) "ASTE SO 140mm C015(DARK GRAY)"
    ["ASP0000442"]=>
    string(28) "ASTE SO 140mm C017(DARK RED)"
    ["ASP0000444"]=>
    string(27) "ASTE SO 140mm C010(CRYSTAL)"
    ["ASP0000446"]=>
    string(33) "ASTE SO 140mm C069(FLAMED HAVANA)"
    ["ASP0000459"]=>
    string(26) "ASTE SO 140mm C009 (WHITE)"
    ["ASP0000460"]=>
    string(35) "ASTE SO 140mm C089 (PETROL PATTERN)"
    ["ASP0000461"]=>
    string(27) "ASTE SO 140mm C622 (ORANGE)"
    ["ASP0000463"]=>
    string(25) "ASTE SO 140mm C624 (BLUE)"
    ["ASP0000464"]=>
    string(25) "ASTE SO 140mm C394 (HORN)"
    ["ASP0000468"]=>
    string(25) "ASTE SO 140mm C619 (PINK)"
    ["ASP0000473"]=>
    string(29) "ASTE SO 140mm C087 (RED POIX)"
  }
  [145]=>
  array(14) {
    ["ASP0000435"]=>
    string(33) "ASTE SO 145mm C069(FLAMED HAVANA)"
    ["ASP0000438"]=>
    string(27) "ASTE SO 145mm C010(CRYSTAL)"
    ["ASP0000439"]=>
    string(25) "ASTE SO 145mm C001(BLACK)"
    ["ASP0000441"]=>
    string(28) "ASTE SO 145mm C017(DARK RED)"
    ["ASP0000443"]=>
    string(24) "ASTE SO 145mm C045(BLUE)"
    ["ASP0000445"]=>
    string(29) "ASTE SO 145mm C015(DARK GRAY)"
    ["ASP0000447"]=>
    string(40) "ASTE SO 145mm C549(DARK RED BLACK HAVAN)"
    ["ASP0000462"]=>
    string(25) "ASTE SO 145mm C394 (HORN)"
    ["ASP0000465"]=>
    string(25) "ASTE SO 145mm C619 (PINK)"
    ["ASP0000469"]=>
    string(26) "ASTE SO 145mm C009 (WHITE)"
    ["ASP0000470"]=>
    string(35) "ASTE SO 145mm C089 (PETROL PATTERN)"
    ["ASP0000471"]=>
    string(27) "ASTE SO 145mm C622 (ORANGE)"
    ["ASP0000472"]=>
    string(29) "ASTE SO 145mm C087 (RED POIX)"
    ["ASP0000474"]=>
    string(25) "ASTE SO 145mm C624 (BLUE)"
  }
}

I'm sorry but I'm not able to format better the array.
Now I'm not able to reproduce the error because is on a project I'm working but if it is useful for understand I can try to reproduce

Ok, I'm pretty sure your error is to do with passing an array as a value.
<?= $form->field($model, 'TempleCode') ... ?>

If $model->TempleCode is an array it won't work as it expects a single value which would be the index of an array item.

Ok but TempleCode is the name of attribute, in the model I've override a init() function to populate the attribute with the possible values for the dropdownList, whith other fields work fine, the only difference is the array structure, the others are simple key => value array. Furthermore with yii2 2.12 this work fine

What type of column is TempleCode in the DB?
You're mixing things up. The selectable items in the dropdown should be separate.

$values = []; // Nested array with values
$form->field($model, 'TempleCode')->dropDownList($values, ['prompt' => 'text-prompt', 'class' => 'form-control select2',])

I think (is only my opinion) that set a default value for the attribute is more clear, in this case I have a list of possible values to chose, is this not possible or not correct in Yii? The database attribute is a varchar(50)

@Bertagit I think you are mixing things up, like @Alex-Code said.
You can surely set a default value for attributes, but the value needs to make sense for your application.

You said that you override the init() method to populate the TempleCode with the possible values, but TempleCode only need to carry a single code that user will choose in the dropdown (Correct me if I'm wrong);

If so I suggest you to refact your model. Remove the part that you are assign TempleCode in model's init() method. And add a method like that in your model:

public function getTempleCodeOptions()
{
    // return the array of possible temple code options
}

and you can build a dropDownList like that:

<?= $form->field($model, 'TempleCode')->dropDownList($model->getTempleCodeOptions(), ['prompt' => 'text-prompt','class' => 'form-control select2',]) ?>
Was this page helpful?
0 / 5 - 0 ratings