Kartik's DetailView not deleting

Hello

I’m trying to use DetailView from Kartik, but using the delete icon/button doesn’t work.

Here is what I’m trying:

Controller




class TestController extends Controller

{

    public function actionView($id)

    {

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

 

        if ($model->load(Yii::$app->request->post()) && $model->save()) {

			return $this->redirect(['view', 'id' => $model->id]);

        } else {

        	return $this->render('view', ['model' => $model]);

		}

    }

 

    public function actionDelete($id)

    {

        $this->findModel($id)->delete();

        return $this->redirect(['index']);

    }

}



View




use kartik\detail\DetailView;

use yii\helpers\Url;

 

    echo DetailView::widget([

            'model' => $model,

            'condensed'=>false,

            'hover'=>true,

            'mode'=>Yii::$app->request->get('edit')=='t' ? DetailView::MODE_EDIT : DetailView::MODE_VIEW,

            'panel'=>[

            'heading'=>$this->title,

            'type'=>DetailView::TYPE_INFO,

        ],

        'attributes' => [

            'id',

            'name',

        ],

        

    	'deleteOptions'=>[

        'url'=>['delete', 'id' => $model->id],

        'data'=>[

        	'confirm'=>Yii::t('app', 'Are you sure you want to delete this item?'),

        	'method'=>'post',

        ],

        ], 

        'enableEditMode'=>true,

    ])



Using firefox inspector I’ve noticed that when I click the delete button, it produces a POST request to view, not to the delete action (actionDelete) specified in the url param in deleteOptions.

I’m using Yii Version 2.0.4 and the instructions from Krajee Webtips (cannot insert link because the forum marks the post as spam :huh: ) but doesn’t work.

Any clues?

I finally made it works!

Problem #1: Kartik’s Detailview version

Checked the vendor/kartik-v/yii2-detail-view/README.md

I was using 1.7.0. Apparently it had a bug that with the delete button. It didn’t work

Solution: upgrade to 1.7.1. Complete instructions at GitHub:

Add to the require section of your composer.json file:


"kartik-v/yii2-detail-view": "dev-master"

And then run:


php composer.phar update

Problem #2: Webtip omissions

Using Krajee Webtips tutorial, I found this issues:

In the controller’s view section, change the ‘deleteOptions’ to:


    	'deleteOptions'=>[

			'params' => ['custom_param'=>true],

        	         'url'=>['delete', 'id' => $model->id],

    	],



Add Json to the use section:


use yii\helpers\Json;

I didn’t notice this error, because the delete action was called via ajax, so I wasn’t receiving the exception page error. I used the debugger to find it out.

With that, it worked. All the rest of the webtip was correct, except that the delete icon didn’t work from the index page/view

For that issue, add this to the else section of the delete action:


public function actionDelete($id) {

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


    	if (Yii::$app->request->isAjax && isset($post['custom_param'])) {

    		if ($this->findModel($id)->delete()) {

    			...

    		} else {

    			...

    		}

    		return;

    	} elseif (Yii::$app->request->post()) {

    		$this->findModel($id)->delete();

    		return $this->redirect(['index']);

    	}

    	throw new InvalidCallException("You are not allowed to do this operation. Contact the administrator.");

    }

The complete code, posted on Gist

Hopes this help to anyone

Hello Abassani

Thanks for the great update which is indeed necessary in order to get the thing working. I’m still having a problem though: when I press the delete button, it deletes the model (which is fine) but I get a red flash message stating “Internal Server Error”.

I’m not sure why this is. Debugging only reveals that the Controller stops at the echo part of the code, but nothing else…

Any suggestions?

This is my code:




public function actionDelete() {

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

        Yii::trace('Entering delete action');

        if (Yii::$app->request->isAjax && isset($post['klantdelete'])) {

            $id = $post['id'];

            if ($this->findModel($id)->delete()) {

               

                echo Json::encode([

                    'success' => true,

                    'messages' => [

                        'kv-detail-info' => 'The book # ' . $id . ' was successfully deleted. <a href="' . 

                            Url::to(['/klant/view']) . '" class="btn btn-sm btn-info">' .

                            '<i class="glyphicon glyphicon-hand-right"></i>  Click here</a> to proceed.'

                    ]

                ]);

            } else {

                echo Json::encode([

                    'success' => false,

                    'messages' => [

                        'kv-detail-error' => 'Cannot delete the klant # ' . $id . '.'

                    ]

                ]);

            }

            return;

        } else {

            $request = Yii::$app->request;

            $id = $request->get('klant_id');

            $this->findModel($id)->delete();

            return $this->redirect(Url::previous());

        }

        throw new InvalidCallException("You are not allowed to do this operation. Contact the administrator.");

    }



and the view




    echo DetailView::widget([

        'model' => $model,

        'attributes' => $attributes,

        'mode' => 'view',

        'panel' => [

            'heading' => 'Klantgegevens voor ' . $model->klant_naam,

            'type' => DetailView::TYPE_INFO,

        ],

        'deleteOptions' => [ // your ajax delete parameters

            'params' => ['id' => $model->klant_id, 'klantdelete' => true],

            'url' => ['delete','id' => $model->klant_id]

        ],

        'alertMessageSettings' => [

            

        ],

        'bordered' => $bordered,

        'striped' => $striped,

        'condensed' => $condensed,

        'responsive' => $responsive,

    ]);

    ?>



Hello eothein, and thanks Abassani for your post!

I had the same problem and the solution was to activate the PretyURL Component…

But I still have the "Internal Server Error" same as eothein.

Did you solve it?

Thanks

Solved!

Just missed


use yii\helpers\Json;

in the Controller

Hi all,

i have a view with 2 widgets

kartik detail view displaying Master Model and a kartik grid view displaying Detail Model.

my problem is Ajax delete button from the view will hide only detail view body and not the grid.

in this case i have few options

  1. disable ajax delete and use Post method only to redirect after deleting to index page

  2. overwrite delete ajax settings

  3. include the grid in detail view body in this case will be hidden also.

For first one the widget don’t has an option to disable ajax request.

Second i try to overwrite delete Ajax settings to be able to hide the grid

kartik settings


 'deleteOptions'=>[

	        'params' => ['custom_param'=>true],

        	'url'=>['delete','id'=>$model->id],

            'ajaxSettings' => ['success' => new \yii\web\JsExpression("

                function(data) {

                    if (data.success) {

                        $('.company-licenses-index').hide(); // add to hide the grid

                        $('.kv-detail-view').hide();

                        $('.kv-btn-delete').attr('disabled', 'disabled');

                        $('.kv-btn-update').attr('disabled', 'disabled');

                        $('.kv-btn-view').attr('disabled', 'disabled');

                        $('.kv-btn-save').attr('disabled', 'disabled');

                    };

                    $.each(data.messages, function(key, msg) {

                        $('.kv-alert-container').append(self.alert(key, msg));

                    });

                    $('.kv-alert-container').hide().fadeIn('slow', function() {

                        $('.kv-detail-view').removeClass('kv-detail-loading');

                        self.initAlert();

                    });

                }

            "),

            ],

    	],



but is not working because of self.initAlert(); is not declared in my script i could include that function body in my script… but i do not want… is looks like i am overwriting the widget in my view… too complex…

Third i use DetailView::begin() … end and place the grid view inside but is included only in form tag what is not hidden on delete…

maybe somebody has an ease solution…

the best will be to disable ajax request

PS. sorry for my eanglish

i cannot disable ajax delete but i overwrite the settings in this case is no impact on view


        'deleteOptions'=>[

			'params' => ['custom_param'=>true],

        	'url'=>['delete','id'=>$model->id],

            'ajaxSettings' => ['beforeSend' => new \yii\web\JsExpression("function() {}"),

                               'success' => new \yii\web\JsExpression("function(data) {}"),

                                 'error' => new \yii\web\JsExpression("function(data) {}")],

    	],



controller action




\ public function actionDelete($id)

    {

        $this->findModel($id, 'app\models\Company')->delete();

        return $this->redirect(['index']);

    }



I’m still having issues here… When debugging it seems my delete action in the controller is called two times. First time it deletes the entity and the second time it tries to delete again, but the previous action already deleted the entity…

Does anybody know why the delete action in the controller is called two times?




echo DetailView::widget([

    'model' => $model,

    'attributes' => $attributes,

    'mode' => Yii::$app->request->get('edit') == 't' ? DetailView::MODE_EDIT : DetailView::MODE_VIEW,

    'striped' => $striped,

    'panel' => [

        'heading' => $this->title,

        'type' => DetailView::TYPE_INFO,

    ],

    'hover' => $hover,

    'hAlign' => $hAlign,

    'vAlign' => $vAlign,

    'fadeDelay' => $fadeDelay,

    'deleteOptions' => [

        'params' => ['custom_param' => true, 'id' => $model->contactpersoon_id],

        'url' => ['delete', 'id' => $model->contactpersoon_id],

        'data' => [

            'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'),

            'method' => 'post',

        ],

    ],

    'enableEditMode' => true,

]);






 public function actionDelete($id) {

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

        if (Yii::$app->request->isAjax) {

            $id = $post['id'];

            if ($this->findModel($id)->delete()) {

                echo Json::encode([

                    'success' => true,

                    'messages' => [

                        'kv-detail-info' => 'The book # ' . $id . ' was successfully deleted.' .

                         Url::to(['/contactpersoon/index'])

                    ]

                ]);

            } else {

                echo Json::encode([

                    'success' => false,

                    'messages' => [

                        'kv-detail-error' => 'Cannot delete the book # ' . $id . '.'

                    ]

                ]);

            }

            return ;

        } else if (Yii::$app->request->post()) {

            $this->findModel($id)->delete();

            return $this->redirect(['index']);

        }

        throw new InvalidCallException("You are not allowed to do this operation. Contact the administrator.");

    }



The include Json did the trick! Thanks for the help! (Stupid mistake though :) )