Yii 1.1: activecolumn

Add some interactive grid columns, which allows you to edit data directly in the grid.
21 followers

Extension a basic set of columns of Yii grid. Allows you to organize interactive editing data inside the grid. The new values ​​will be sent to the server using Ajax. At the moment includes:

  • phaSelectColumn - column, which will allow the new data from a predefined list of values.
  • phaCheckColumn - using this column you will be switched the state between two value.

Requirements

Testing with Yii 1.1.7, but should work since Yii 1.1.

Licence

Choose your favourite of - GPL or MIT.

Installation

  1. Extract the release file under protected/extensions/phaActiveColumn.
  2. Add to your config file in import section:
    ...
    'application.extensions.phaActiveColumn.*',
    ...

Usage

Now in your template you can use the new column. All new collumns must set property actionUrl. It's URL for update action.On this URL will be sent call to update value. If this value is string - value will be used as is. If it's array - will be called CHtml::normalizeUrl.

phaSelectColumn

Because the column type phaSelectColumn is inherited from CDataColumn and CGridColumn, it includes entire set of properties and methods of base classes. Consider the different properties:

  • data - data to build the drop-down list an array {id => name};
  • modelId - name of models key. By default it's "id";
  • actionUrl - see "Usage" section.

phaSelectColumn Example

For example, consider building an interactive grid to edit a list of cities and time zones for this cities:

$this->widget('zii.widgets.grid.CGridView', array(
        'dataProvider'=>$dataProvider,
        'columns'=>array(
            ...........
            array (
                'class' => 'phaSelectColumn',
                'header' => 'Time Zone',
                'name' => 'time_zone_id',
                'data' => CHtml::listData(TimeZones::model()->findAll(), 'id', 'name'),
                'actionUrl' => array('setTimeZone'),
            ),
            ...........
        ),
    ));

After changing any values ​​will be send a POST request, containing:

  • item - unique identifier of model
  • value - selected value

phaCheckColumn

For data that have two states is convenient use a column of phaCheckColumn type. In this column will display the checkbox when the status is change, the new value will be send to server.

phaCheckColumn Example

For example, consider building an interactive grid to activate same item:

$this->widget('zii.widgets.grid.CGridView', array(
        'dataProvider'=>$dataProvider,
        'columns'=>array(
            ...........
            array(
                'class' => 'phaCheckColumn',
                'name' => 'is_active',
                'actionUrl' => array('setIsActive'),
            ),
            ...........
        ),
    ));

After changing any values ​​will be send a POST request, containing:

  • item - unique identifier of model
  • checked - 1 (if box is checked) or 0 (in another case).

phaEditColumn

If you need edit text date without open other page, you can use this type of column. In normal state it's view data as ordinary column. But click on data cell will open input field for edit data. After press Enter new data will be send to server.

phaEditColumn Example

We add column phaEditColumn type for editing attribute name of model.

$this->widget('zii.widgets.grid.CGridView', array(
        'dataProvider'=>$dataProvider,
        'columns'=>array(
            ...........
            array(
                'class' => 'phaCheckColumn',
                'name' => 'name',
                'actionUrl' => array('setName'),
            ),
            ...........
        ),
    ));

After changing any values ​​will be send a POST request, containing:

  • item - unique identifier of model;
  • value - input data.

phaEditColumn usage

If you click on row, view data will change to input field. Enter send data to server, and ESC-key will close input without send data.

Resources

Get last stable version

Total 14 comments

#18204 report it
mplexus at 2014/09/25 02:32pm
Make field width equal to td width.

This is what I did to make input field respect td width (lines commented as new).

function phaACOpenEditField(itemValue, gridUID, grid ) {
            phaACHideEditField( phaACOpenEditItem, phaACOpenEditGrid );
            var id   = $(itemValue).attr("valueid");
 
            //new start
            var width = $(itemValue).closest("td").attr("width");
            //fix for IE because it is providing width:20 instead of width:20px in td.
            if(typeof width !== "undefined"){
                if(width.indexOf("px", width.length - 2) === -1){
                    width += "px";
                }
            }
            //new end
 
            $("#viewValue-" + gridUID + "-"+id).hide();
            $("#field-" + gridUID + "-" + id).show();
            $("#field-" + gridUID + "-" + id+" input")
                .attr("style", "width:"+width+";text-align:right") //new
                .focus()
                .keydown(function(event) {
                    switch (event.keyCode) {
                       case 27:
                          phaACHideEditField( phaACOpenEditItem, gridUID );
                       break;
                       case 13:
                          phaACEditFieldSend( itemValue );
                       break;
                       default: break;
                    }
                });
 
            phaACOpenEditItem = id;
            phaACOpenEditGrid = gridUID;
        }

And this is an example of a grid column declared in the view.

array(
  'name'=>'payment',
  'class'=>'phaEditColumn1',
  'actionUrl' => array('uncollected/setAttribute', 'attribute'=>'payment'),
  'htmlOptions'=>array('width'=>'70px', 'style'=>'text-align:right'),
  'headerHtmlOptions'=>array('width'=>'70px'),
),
#9722 report it
Ivanda Nothabeer at 2012/09/06 02:38am
Blank Fields are not Displayed and Cannot Be edited

It has been reported previously, but blank fields are not shown by phaEditColumn.

My solution was to substitute a "-" character in the displayed value. This is done in phaEditColumn.php

protected function renderDataCellContent($row,$data) {
        $value = CHtml::value($data, $this->name);
        if ($value=='') $value='-';  // Substitute a '-' character if field is blank 
        $valueId = $data->{$this->modelId};
 
        $this->htmlEditFieldOptions['itemId'] = $valueId;
        $fieldUID = $this->getViewDivClass();
 
        echo CHtml::tag('div', array(
            'valueid' => $valueId,
            'id' => $fieldUID.'-'.$valueId,
            'class' => $fieldUID
        ), $value);
 
        echo CHtml::openTag('div', array(
            'style' => 'display: none;',
            'id' => $this->getFieldDivClass() . $data->{$this->modelId},
        ));
        echo CHtml::textField($this->name.'[' . $valueId . ']', $value, $this->htmlEditFieldOptions);
        echo CHtml::closeTag('div');
    }
#8049 report it
jward at 2012/05/06 02:21am
Solved: Erroneously duplicated array keys for URL

Several others noted that phaEditColumn will submit the correct URL if used with only one column in the grid because the same key (grid id) is repeatedly used when populating the phaACActionUrls[] array. In comment #7902, jwerd (no relation to jward) was on the right track when $data->id was tried. It only takes a few more changes to complete a fix.

I modified the script in init(). You can spot my changes by finding the commented lines:

public function init() {
        parent::init();
 
        $cs=Yii::app()->getClientScript();
 
        $liveClick ='
/*        phaACActionUrls["'.$this->grid->id.'"]="' . $this->buildActionUrl() . '"; */
        phaACActionUrls["'.$this->id.'"]="' . $this->buildActionUrl() . '";
        jQuery(".'. $this->getViewDivClass() . '").live("click", function(e){
            phaACOpenEditField(this, "' . $this->id . '");
            return false;
        });';
 
        $script ='
        var phaACOpenEditItem = 0;
        var phaACOpenEditGrid = "";
        var phaACActionUrls = [];
        function phaACOpenEditField(itemValue, gridUID, grid ) {
            phaACHideEditField( phaACOpenEditItem, phaACOpenEditGrid );
            var id   = $(itemValue).attr("valueid");
 
            $("#viewValue-" + gridUID + "-"+id).hide();
            $("#field-" + gridUID + "-" + id).show();
            $("#field-" + gridUID + "-" + id+" input")
                .focus()
                .keydown(function(event) {
                    switch (event.keyCode) {
                       case 27:
                          phaACHideEditField( phaACOpenEditItem, gridUID );
                       break;
                       case 13:
/*                          phaACEditFieldSend( itemValue ); */
                          phaACEditFieldSend( itemValue, gridUID );
                       break;
                       default: break;
                    }
                });
 
            phaACOpenEditItem = id;
            phaACOpenEditGrid = gridUID;
        }
        function phaACHideEditField( itemId, gridUID ) {
            var clearVal = $("#viewValue-" + gridUID + "-"+itemId).text();
            $("#field-" + gridUID + "-" + itemId+" input").val( clearVal );
            $("#field-" + gridUID + "-" + itemId).hide();
            $("#field-" + gridUID + "-" + itemId+" input").unbind("keydown");
            $("#viewValue-" + gridUID + "-" + itemId).show();
            phaACOpenEditItem=0;
            phaACOpenEditGrid = "";
        }
/*        function phaACEditFieldSend( itemValue ) { */
        function phaACEditFieldSend( itemValue, gridUID ) {
            var id = $(itemValue).parents(".grid-view").attr("id");
            $.ajax({
                type: "POST",
                dataType: "json",
                cache: false,
/*                url: phaACActionUrls[id], */
                url: phaACActionUrls[gridUID],
                data: {
                    item: phaACOpenEditItem,
                    value: $("#field-"+phaACOpenEditGrid+"-"+phaACOpenEditItem+" input").val()
                },
                success: function(data){
                  $("#"+id).yiiGridView.update( id );
                }
            });
        }
        ';
 
        $cs->registerScript(__CLASS__.'#active_column-edit', $script);
        $cs->registerScript(__CLASS__.$this->grid->id.'#active_column_click-'.$this->id, $liveClick);
    }
#7902 report it
jwerd at 2012/04/25 09:37am
phaEditColumn falling back to last url still

Hey there,

Just thought I'd let you know that the latest version still has issues with the url only working for one field.

But I think I know why, question is, how can we go about fixing it? First here's my entire widget call:

<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'procedure-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        array(
            'class' => 'phaEditColumn',
            'name' => 'code',
            'actionUrl' => array('setCode'),
        ),
        array(
            'class' => 'phaEditColumn',
            'name' => 'description',
            'actionUrl' => array('setDescription'),
        ),
        array(
            'class' => 'phaEditColumn',
            'name' => 'price',
            'actionUrl' => array('setPrice'),
        ),
 
        array(
            'class'=>'CButtonColumn',
            'template'=>'{update}{delete}'
        ),
    ),
)); ?>

Now, the generated code that concerns me is:

phaACActionUrls["procedure-grid"]="/procedures/setCode";
        jQuery(".viewValue-procedure-grid_c0").live("click", function(e){
            phaACOpenEditField(this, "procedure-grid_c0");
            return false;
        });
 
        phaACActionUrls["procedure-grid"]="/procedures/setDescription";
        jQuery(".viewValue-procedure-grid_c1").live("click", function(e){
            phaACOpenEditField(this, "procedure-grid_c1");
            return false;
        });
 
        phaACActionUrls["procedure-grid"]="/procedures/setPrice";
        jQuery(".viewValue-procedure-grid_c2").live("click", function(e){
            phaACOpenEditField(this, "procedure-grid_c2");
            return false;
        });

It appears to just override because the $data->grid->id is the same on all of them. When I switch this to $data->id, it starts posting to the same page the grids on, completely ignoring the url.

Any ideas? Thanks in advance!

#6867 report it
lkg0dzre at 2012/02/09 04:14pm
re:re:New bug

But I would like to clarify, does not solve the problem of empty fields use htmlOptions option for a cell?

'htmlOptions'=>array(
    'style'=>'min-height: 2em;',
),

It isn't work.

It solved only by class in htmlOptions + css

#6850 report it
xNicox at 2012/02/09 06:11am
usign with CArrayDataProvider

HI, I tried with CArrayDataProvider, and don't fork for me. First I see that the field is created with this id and class:

<div id="viewValue-yw1_c5-" class="viewValue-yw1_c5">

the id look not ok for me, So i check inside phaEditColumn.php and I found this:

protected function renderDataCellContent($row,$data) {
        $value = CHtml::value($data, $this->name);
        $valueId = $data->{$this->modelId};

where $valueId is used to define the field ID:

echo CHtml::tag('div', array(
            'valueid' => $valueId,
            'id' => $fieldUID.'-'.$valueId,
            'class' => $fieldUID
        ), $value);

I'll try to asign the field manually.

Regards.

#6848 report it
lkg0dzre at 2012/02/09 04:21am
re:re:New bug

But I would like to clarify, does not solve the problem of empty fields use htmlOptions option for a cell?

I think it must work by default.

#6838 report it
Vadim Kruchkov at 2012/02/08 05:30pm
re: New bug

I have prepared a new version that solves this problem with different URL. But I would like to clarify, does not solve the problem of empty fields use htmlOptions option for a cell?

#6836 report it
lkg0dzre at 2012/02/08 03:42pm
New bug

Thank you very much for update!

But now i have another problem (= When i use several editable columns, working only last 'actionUrl' and name of column is don't send with ajax post. So i can have only one phaEditColumn in grid.

see on string 117

url: "' . $this->buildActionUrl() . '",

I tried to fix it. Maybe it help you again. http://dl.dropbox.com/u/11392265/temp/phaEditColumn.php

Also I add after 34 string

'style' => 'min-height: 2em',//++ for edit empty field

for edit empty field

And width: 100% needed for more big click-area

#6835 report it
Vadim Kruchkov at 2012/02/08 01:00pm
new version added

to lkg0dzre: Thx for your version of the code, it helped me understand the problem. The best way to add style to an element to be used in the configuration of the column:

array(
    'class' => 'phaEditColumn',
    ....
    'htmlEditFieldOptions' => array(
        'style' => 'width: 100%'
    ),
),

to Nicolas400: I use CActiveDataProvider. But I think CArrayDataProvider will not have problems with this extension, becouse it exted base column class only. If you have any problem with this extension - write report, I will fix it :)

#6820 report it
xNicox at 2012/02/07 08:28am
ask: Could this work with CArrayDataProvider in the grid ?

hi, I think this is what I need. Do you use it with CArrayDataProvider ? Best Regards.

#6797 report it
lkg0dzre at 2012/02/06 02:25am
re:re:bug in phaEditColumn

I tried to fix it. Maybe it help you. http://dl.dropbox.com/u/11392265/temp/phaEditColumn.php

#6794 report it
Vadim Kruchkov at 2012/02/05 03:23pm
re:bug in phaEditColumn

I'm not counting on such a possibility :) ок, I will include it in the coming version. Thank you for using and reporting!

#6792 report it
lkg0dzre at 2012/02/05 12:32pm
bug in phaEditColumn

phaEditColumn is not working with several grids

Thx for extension!

Leave a comment

Please to leave your comment.

Create extension