Update CGridview row separately using ajax request

You are viewing revision #1 of this wiki article.
This is the latest version of this article.

There are cases you want to update a record on CGridview directly

In this wiki I will show how to do that

In your view file:

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider' => $dataProvider,
    'id' => 'grid-view-id',
    'columns' => array(
        array(
            'header' => 'attribute1',
            'value' => 'CHtml::textField("TheModel[attribute1]",$data->attribute1)',
            'type' => 'raw',
        ),
        array(
            'header' => 'attribute2',
            'value' => 'CHtml::textField("TheModel[attribute2]",$data->attribute2)',
            'type' => 'raw',
        ),
        array(
            'class' => 'CButtonColumn',
            'template' => '{update}{view}{delete}',
            'buttons' => array(
                'update' => array(
                    'options' => array('class' => 'save-ajax-button'),
                    'url' => 'Yii::app()->createUrl("yourController/saveModel", array("id"=>$data->id))',
                ),
                'view',
                'delete',
            ),
        ),
    ),
));

Also in the same view file or in any way you have to load this script

<script>
    $('#grid-view-id a.save-ajax-button').live('click', function(e)
    {
        var row = $(this).parent().parent();

        var data = $('input', row).serializeObject();

        $.ajax({
            type: 'POST',
            data: data,
            url: jQuery(this).attr('href'),
            success: function(data, textStatus, jqXHR) {
                console.log(data);
                console.log(textStatus);
                console.log(jqXHR);
            },
            error: function(textStatus, errorThrown) {
                console.log(textStatus);
                console.log(errorThrown);
            }
        });
        return false;
    });


    $.fn.serializeObject = function() {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o[this.name]) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };
</script>

Now in your controller "yourController" in action "saveModel"

public function actionSaveModel($id){
        //save the data as you did in the properly action. For example
        if ($_POST['TheModel']) {
            $model = new TheModel();
            $model->attributes = $_POST['TheModel'];
            $model->save();
         }
    }

Thats it!