Skip to content

Dropdown/Select Field

Generates a dropdown (select) field based on given values.

Plugin Types

There are 3 different types of plugins:

SelectArray

Create a dropdown selection based on an associated array:

php
public function ngrestAttributeTypes()
{
    return [
        'genres' => ['selectArray', 'data' => [1 => 'Male', 2 => 'Female']],
    ];
}

SelectRelationActiveQuery

When dealing with large tables the luya\admin\ngrest\plugins\SelectRelationActiveQuery class can handle large amount of data but there is no model callback for the label fields, it returns raw SQL data. In order to use this plugin you need to have a hasOne relation.

php
'user_id' => [
    'class' => SelectRelationActiveQuery::class, 
    'query' => $this->getUser(), 
    'labelField' => 'firstname,lastname'
]

In order to access the data through an eager loaded relation, the relation name must be added into the config. Assuming the example above getUser() would return a $this->hasOne() relation definition the luya\admin\ngrest\plugins\SelectRelationActiveQuery -> $relation property can be configured to load the data from this relation:

php
'user_id' => [
    'class' => SelectRelationActiveQuery::class, 
    'query' => $this->getUser(),
    'relation' => 'user',
    'labelField' => 'firstname,lastname'
]

In order to eager load the user relation within API list calls, the with() definition can be configured in luya\admin\ngrest\base\Api -> prepareListQuery():

php
public function prepareListQuery()
{
    return parent::prepareListQuery()->with(['user']);
}

SelectModel

DANGER

Whenever possible, do not use this plugin. In complex cases, it makes the application slow.

Create a dropdown selection based on a yii\db\ActiveRecord model class:

php
public function ngrestAttributeTypes()
{
    return [
        'genres' => [
            'selectModel', 
            'modelClass' => Customers::className(), 
             'valueField' => 'customer_id', 
             'labelField' => 'name',
         ],
     ];
}

You can define more options for the select model like where statements and which fields should be displayed take a look at class API luya\admin\ngrest\plugins\SelectModel for more information. In order to generate a custom label field you can also pass a closure function:

php
'labelField' => function($model) {
    return $model->firstname . ' ' . $model->lastname;
}

DANGER

Please keep in mind this plugin will override the default values from the database to display the REST API data, this can have bad side effects. To prevent such a behavior use luya\admin\ngrest\plugins\SelectRelationActiveQuery instead!

php
public function getCustomer()
{
    return $this->hasOne(Customer::class, ['id' => 'customer_id']);
}

The above example will not work if the customer_id field as the value is already observed from the selectModel plugin. You can always access the old data (before the after find event) like this:

php
public function getOriginalCustomerId()
{
    return $this->getOldAttribute('customer_id');
}
     
public function getCustomer()
{
    return $this->hasOne(Customer::class, ['id' => 'originalCustomerId']);
}

Handling null empty values

By default a no selection or a reset of a currently selected item will assign the value null to this field as defined in luya\admin\ngrest\plugins\Select -> $initValue. This might make problem with handling empty Yii validation rule inputs as null wont be threated. Therefore you could change initValue to 0 or change the validation rules to have a default value on empty:

php
return [
    ['user_id', 'default', 'value' => 0],
];

This will set value to 0 if null value receives the API. Or change the initValue to 0 when configure the select plugin:

php
return [
    'user_id' => [
        'selectArray',
        'data' => [1 => 'John Doe', 2 => 'Jane Doe'],
        'initValue' => 0,
    ]
];

Assuming the user_id validation rule requires an integer value.