1

I've detail showed using Kartik Detail View. This widget has Edit inline function by clicking pencil icon button in top right side like this enter image description here

And then the table will be editable like this: enter image description here I've edit the data, and then click the Floopy Disk Icon button as Save.

And nothing happen, my data still the same, my update not success.

This is my code in view.php

<?=
DetailView::widget([
    'model' => $model,
    'condensed' => true,
    'hover' => true,
    'mode' => DetailView::MODE_VIEW,
    'panel' => [
        'heading' => 'Data Details',
        'type' => DetailView::TYPE_INFO,
    ],
    'attributes' => [
        'product',
        'productId',
        'distDate',
        'created_at',
        'created_by',
        [
            'attribute' => 'is_exported',
            'value' => $model->isExported->name,
        ],
    ],
    'buttons1' => '{update}',
])
?>

Why does the widget didn't save the edited data? What's wrong with my code?

UPDATE:

This is the action in my controller:

public function actionUpdate($id) {
    $model = $this->findModel($id);

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['view', 'id' => $model->productId]);
    } else {
        return $this->render('update', [
                    'model' => $model,
        ]);
    }
}

I use the pure action, I didn't change the code in Controller.

this is my model

<?php

namespace app\modules\vatout\models;

use Yii;

class VatoutFakturOut extends \yii\db\ActiveRecord
{
/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'vatout_faktur_out';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['user_id', 'parent_id', 'product'], 'required'],
        [['user_id', 'parent_id', 'is_exported'], 'integer'],
        [['distDate', 'updated_at', 'created_at'], 'safe'],
        [['updated_by', 'created_by'], 'string', 'max' => 16],
        [['product'], 'string', 'max' => 128],
        ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'producrID' => 'Product ID',
        'user_id' => 'User ID',
        'parent_id' => 'Parent ID',
        'distDate' => 'Dist Date',
        'Product' => 'Product',
        'is_exported' => 'Is Exported',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getIsExported()
{
    return $this->hasOne(VatoutStatus::className(), ['id' => 'is_exported']);
}
}
4

1 回答 1

2

Line $model = $this->findModel($id);:

You're using $this on Controller, so it attempts to find a controller's data from database (which doesn't exist). Also, there is no such method findModel() in controller, this should be used on model that has ActiveRecord extension. The correct usage would be:

$model = VatoutFakturOut::findOne($id);

However, it seems that this widget does not pass any $id (therefore, parameter $id in actionUpdate($id) is useless). How to get the ID? From Yii::$app->request->post()['VatoutFakturOut']['productId']. But it should be checked if it's defined, otherwise you will get a warning:

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

if (empty($post['VatoutFakturOut']['productId'])) {
    throw new NotFoundHttpException('Not found.');
}

The 3rd thing is that you're giving the ability for user to edit the ID (even though it's not overwritten)... Which is something you shouldn't do. I would slightly change the code for view file:

'attributes' => [
    'product',
    [
        'attribute' => 'productId', 
        'options' => ['readonly' => true],
    ],
    'distDate',
    'created_at',
    'created_by',
    [
        'attribute' => 'is_exported',
        'value' => $model->isExported->name,
    ],
],

Assuming that productId is the primary key. This will not allow user to edit this field but it will still be sent to controller.

The final result:

public function actionUpdate()
{
    $post = Yii::$app->request->post();

    if (empty($post['VatoutFakturOut']['id'])) {
        throw new NotFoundHttpException('VatoutFakturOut not found.');
    }

    $model = VatoutFakturOut::findOne($post['VatoutFakturOut']['id']);

    if ($model->load($post) && $model->save()) {
        return $this->redirect(['view', 'id' => $model->productId]);
    } else {
        return $this->render('update', [
            'model' => $model,
        ]);
    }
}
于 2017-07-24T09:03:14.977 回答