Search code examples
model-view-controlleryii2yii2-basic-app

gridview check box multi delete in yii2


i simply want to have a gridview that has checkbox column in front of each row and my admins can delete row by check all or check one or check how many box they disire and then by click on delete button all checked row remove from their view

in the back its important to update their delete column to 1 a row not delete

here is my code for delete one id

controller(ignore persian words)

    public function actionDelete($id=[])
    {
    $model = \Yii::$app->db->createCommand()
        ->update('tbl_post',['Delete'=>1],['id'=>$id])->execute();

    if($model==true){
        \Yii::$app->session->setFlash('با موفقیت نیست شد');
    }else{
        \Yii::$app->session->setFlash('با موفقیت نیست نشد');
    }
    return $this->redirect('index');
    }

here is view(ignore persian words)

//in baraye ine ke form taiid shod payam bede
foreach (Yii::$app->session->getAllFlashes() as $key => $message) {
    echo '<div class="alert alert-' . $message . '">' . $key . '</div>';
}
//-------------------------table it self
echo \yii\grid\GridView::widget([
    'dataProvider' => $adp,
    'caption' => 'لیست تمامی محتوا ها',
    'captionOptions' => ['id' => 'atro-caption'],
    'headerRowOptions' => ['class' => 'atro-th'],
    'columns' => [
        ['class' => \yii\grid\SerialColumn::className(),],
        ['class' => \yii\grid\CheckboxColumn::className(),
            'checkboxOptions' => function ($a) {
                return ['value' => $a->id];
            }],
        'Title',
        'FK_PostType',
        'FK_Author',
    ]
]);

Solution

  • Before I suggest you anything about your problem you should know the basic rules of programming that never use reserved keywords for function naming variable or database field names, you have used the Delete as a column name you should change it immediately to something like is_deleted. i will be using this name in my example reference.

    About your problem, you have 2 ways to do it.

    1. Add a button and bind javascript click event to it which will serialize all the selected checkboxes and then use an ajax post request to submit the selected ids and mark them delete.

    2. Wrap your Gridview inside a form tag and then use a submit button to submit that for to the delete action.

    I will demonstrate the first option to you

    add the button on top of your GridView

    <?=Html::button('Delete', ['class' => 'btn btn-danger', 'id' => 'delete'])?>
    

    Then assign an ID to the pjax container

    <?php Pjax::begin(['id' => 'my-grid']);?>
    

    Paste this javascript on top of your view but update the url of the ajax call to your actual controller/delete action

    $this->registerJs('
    $(document).on("click","#delete",function(e){
        let selected=$(".grid-view>table>tbody :input");
        let data=selected.serialize();
        if(selected.length){
            let confirmDelete  =   confirm("Are you sure you want to delete?");
            if(confirmDelete){
                $.ajax({
                    url:"/test/delete",
                    data:data,
                    dataType:"json",
                    method:"post",
                    success:function(data){
                        if(data.success){
                            $.pjax({container:"#my-grid"});
                        }else{
                            alert(data.msg);
                        }
                    },
                    error:function(erorr,responseText,code){}
                });
            }
        }else{
            alert("select someitems to delete");
        }
    });
    ', \yii\web\view::POS_READY);
    

    And change your delete action to the following, try using transaction block so that if something happens in the middle of the operation it will revert all the changes back, change the model name and namespace to the appropriate model, I assumed your model name is Post.

     public function actionDelete()
        {
            if (Yii::$app->request->isPost) {
                $selection = Yii::$app->request->post('selection');
                $response['success'] = false;
    
                $transaction = Yii::$app->db->beginTransaction();
    
                try {
                    \frontend\models\Post::updateAll(['is_deleted' => 1], ['IN', 'id', $selection]);
                    $response['success'] = true;
                    $transaction->commit();
                } catch (\Exception $ex) {
                    $transaction->rollBack();
                    $response['msg'] = $ex->getMessage();
                }
    
                echo \yii\helpers\Json::encode($response);
    
            }
        }