Passing selected value to model function that renders a dropdown

I have a gridview of jobs. Each job has a status. I am trying to code a solution to allow the status to appear as a dropdown in each cell of the gridview column. The dropdown should display the currently set status of each job. When I get this working then I will add a jQuery onchange event to save changes to the status to the database for the particular job.

My problem is that I have no idea how to pass a job’s set status_id to my model function which renders the dropdown.

My function in the model:




	public function getStatuses($selectedStatus = null) {

		$statusData = Arrayhelper::map(Statuses::find()->orderBy('status')->asArray()->all(), 'id', 'status');

		$statusOptions = '';

		foreach ($statusData as $key => $value) {

			$statusOptions.= '<option value="'.$key.'"';

			if ($selectedStatus != null){

				if ($selectedStatus == $key) {

					$statusOptions.= ' selected="selected"';

				}

			}

			$statusOptions.= '>'.$value.'</option>';

		}

		return '<select class="form-control" style="min-width:130px;"><option>--</option>'.$statusOptions.'</select>';

	}



So as you see I’m trying to use a function parameter to pass the status value.

In my gridview column I can’t figure out how to (or even if it’s possible to) pass the status value for the particular job row to the model function. This is what I’ve tried and it’s not working:




[

	'attribute' => 'Statuses',

	'format'=>'raw',

	'value' => 'Statuses(status.id)',

],



The resulting error is ‘[font=“Courier New”]Getting unknown property: backend\models\Jobs::statuses(status[/font]’

So what should I do to pass the set status value for a job to the getStatuses function in my Job model? Is the set status available in the model already somewhere for the gridview row, to be used? I’m not clear on how data is split between the view and the model and what’s accessible from where.

Any help will, as always, be immensely appreciated. Thanks!

It can be done with xEditable widget. Here is how to:

  1. Add to composer.json to require this line

"2amigos/yii2-editable-widget" : "~1.0",

  1. Composer update

  2. Column in GridView:


[

    'attribute' => 'status',

    'value' => function($model) {

        /** @var $model User */

        return Editable::widget( [

            'model' => $model,

            'attribute' => 'status',

            'url' => '/user/change-status',

            'type' => 'select',

            'mode' => 'pop',

            'value' => function($model){

                /** @var $model User */

                return $model->getStatusLabel();

            },

            'clientOptions' => [

                'placement' => 'right',

                'source' => User::getStatusLabelsXEditable($model->id),

            ]

        ]);

    },

    'format' => 'raw',

    'filter' => User::getStatusLabels()

],

  1. UserConroller:

/**

 * @return mixed|string

 */

public function actionChangeStatus()

{

    $post = Yii::$app->request->post();

    $pieces = explode('-', $post['value']);

    $user = User::findOne($pieces[0]);

    if ($user) {

        $user->status = $pieces[1];

        if ($user->save()) {

            return $user->getStatusLabel();

        }

    }

    return '';

}

  1. Model User

/**

 * @param bool $colored

 * @return array

 */

public static function getStatusLabels($colored = false) {

    return [

        self::STATUS_DISABLED => ($colored ? '<span style="color: #e0e0e0">Выключен</span>' : 'Выключен'),

        self::STATUS_BANNED => ($colored ? '<span style="color: rgb(186,80,81)">Забанен</span>' : 'Забанен'),

        self::STATUS_ACTIVE => ($colored ? '<span style="color: #60b35a">Активен</span>' : 'Активен'),

        self::STATUS_EMAIL_NOT_CONFIRMED => ($colored ? '<span style="color: #687269">Email не подтверждён</span>' : 'Email не подтверждён'),

        self::STATUS_PHONE_NOT_CONFIRMED => ($colored ? '<span style="color: #ffdecf">Номер телефона не подтверждён</span>' : 'Номер телефона не подтверждён'),

        self::STATUS_DELETED => ($colored ? '<span style="color: rgb(200, 217, 204)">Удалён</span>' : 'Удалён'),

    ];

}


/**

 * @param bool $colored

 * @return mixed|string

 */

public function getStatusLabel($colored = false) {

    $labels = self::getStatusLabels($colored);

    return isset($labels[$this->status]) ? $labels[$this->status] : 'Неизвестный статус';

}

/**

 * Формирует список для dosamigos\editable\Editable

 *

 * @param $model_id

 * @return array

 */

public static function getStatusLabelsXEditable($model_id) {

    $labels = self::getStatusLabels();

    $result = [];

    foreach ($labels as $id => $label) {

        $result[] = ['value' => $model_id . '-' . $id, 'text' => $label];

    }

    return $result;

}

Thanks very much for your timely and well-thought-out answer.

Back to the OP.


[

        'attribute' => 'Statuses',

        'format'=>'raw',

        'value' => 'Statuses(status.id)',

],

I think the quotes around Statuses(status.id) is wrong. I believe it needs to be a ‘$data->…’ of $model-> thing. But I could be wrong.