Yii 1.1: ecolumns

Manage column's visibility and order in GridView
45 followers

EColumns provides widgets for managing column's visibility and order in GridView.
Please, try out a demo. Screenshot

Requirements

Developed and tested on Yii 1.1.10

Usage

1.Put ecolumns from zip to protected/extensions directory.
Extensions contains two widgets:
EColumns - widget based on CJuiSortable that can be attached to CGridView and allows to manage columns. This widget is always shown on the screen.
EColumnsDialog - dialog based on CJuiDialog that includes EColumns and allows to manage columns of CGridView as well.

2.Create required widget in view.
For example, dialog:

$dialog = $this->widget('ext.ecolumns.EColumnsDialog', array(
       'options'=>array(
            'title' => 'Layout settings',
            'autoOpen' => false,
            'show' =>  'fade',
            'hide' =>  'fade',
        ),
       'htmlOptions' => array('style' => 'display: none'), //disable flush of dialog content
       'ecolumns' => array(
            'gridId' => 'grid1', //id of related grid
            'storage' => 'db',  //where to store settings: 'db', 'session', 'cookie'
            'fixedLeft' => array('CCheckBoxColumn'), //fix checkbox to the left side 
            'model' => $dataProvider->model, //model is used to get attribute labels
            'columns' => array(
               'name',
               'age',
                array(
                  'name' => 'login_date',
                  'header' => 'Login Date',
                ), 
                array(
                 'class'=>'CLinkColumn',
                 'header' => 'Link',
                ),
                array(
                 'class'=>'CButtonColumn',
                ),
                array(
                 'class'=>'CCheckBoxColumn',
                ),               
           ),
       )
    ));

Here it is required to set (in ecolumns array):

  • gridId - id of related GridView widget
  • storage - where to store column settings
  • columns - all columns that potentially can be seen in gridview

Storage can be: db, session or cookie. Session and cookie can be used without any setup, but for 'db' you should create following table:

CREATE TABLE `tbl_columns` (
    `id` VARCHAR(100) NOT NULL,
    `data` VARCHAR(1024) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
);

3.Attach widget to CGridView:

$this->widget('zii.widgets.grid.CGridView', array(
       'id' => 'grid1',
       'dataProvider' => $dataProvider,
       'columns' => $dialog->columns(),
       'template' => $dialog->link()."{summary}\n{items}\n{pager}",
));

$dialog->columns() returns columns that are currently visible.
$dialog->link() returns link openning dialog. You can place it anywhere in template property or even outside the grid.

4.Additional parameters:
fixedLeft, fixedRight - array of column names that are fixed on left or right side of grid and cannot be modified by user. Useful for CCheckBoxColumn and CButtonColumn.
userSpecific (boolean) - store settings for each user or for grid globally. Defaults to true.
model - model for getting attribute labels as column headers
buttonApply - html for apply button. Default: <input type="submit" value="Apply" style="float: left">
buttonCancel - html for cancel button. Default: null
buttonReset - html for reset button. Default: <input type="button" class="reset" value="Reset" style="float: right">. CSS class "reset" is required for this button.

If you do not need dialog, you can use EColumns widget itself or inside your own widgets. Parameters of EColumns widget are the same as in ecolumns array config in EColumnsDialog.

Change log

May, 9
- Column headers are taken from attribute labels (for array column definitions)

May, 8
- Added reset button
- Column headers are taken from attribute labels

April, 30
Initial Release

All comments are welcome!

Total 20 comments

#17915 report it
SleepWalker at 2014/08/11 08:05am
Using of aliases

I have added Yii::setPathOfAlias('ecolumns', dirname(__FILE__)); to the beginning of ::init() methods to use this alias instead of `ext.ecolumns'.

This makes the extension independent of project's file structure. I hope this tip would be useful for others too.

#16936 report it
davidgraybeard at 2014/04/14 09:36am
Excellent Extension

Although this extension seems to have had little activity for awhile I can verify that it is still excellent for what it does. I am using it for a generalized data viewing site for semi-technical people, and it works great!

I added one feature, which is to use the attributeLabels() of the model for display, if it exists. In the first few lines of EColumns::run() I replaced the innards of the for loop:

foreach ($widgetColumns as $key => $column) {
            $hdr = $column['header'];
            if (!empty($this->model->model->attributeLabels()[$key])) {
                $hdr = $this->model->model->attributeLabels()[$key];
            }
            $this->items[$key] = '<label><input type="checkbox" name="' . $this->getRequestParam() . '[]" value="' . $key . '" ' . (isset($column['visible']) ? 'checked' : '') . '>&nbsp;' . CHtml::encode($hdr) . '</label>';
        }
#15616 report it
PolarBear at 2013/11/28 04:05pm
A little bug

Hello, very useful extension.

I have an array in CButtonColumn

array(
'class'=>'CButtonColumn',
'header'=>CHtml::dropDownList('pageSize',$pageSize,array('10'=>'10','20'=>'20','50'=>'50','100'=>'100','500'=>'500'),array('onchange'=>"$.fn.yiiGridView.update('hard-grid',{ data:{pageSize: $(this).val() }})")),
'template'=>'{view}{tooltip}',
...

and as a result you can see bug

please fix it

#11370 report it
Vitalets at 2013/01/10 02:20am
Re: reset issue

hi, seems it's because column from related table as you mentioned. try to set header manually, e.g.

array(
    'name'=>'shop.sid',
    'header' => 'sid'
  ),
#11356 report it
hehbhehb at 2013/01/08 09:01am
reset issue
'ecolumns' => array(
...
'columns'=>array(
  array(
    'name'=>'shop.sid',
  ),    
)
...
)

if I click the reset button in the dialog, the shop.sid field is lost.

shop is a relation table

#10597 report it
Vitalets at 2012/11/06 02:15pm
RE: Delete option is not working

hi, could you provide more details wich delete option you mean?
Extension does not have such option in config..

#10584 report it
Sanjeev at 2012/11/06 02:46am
Delete option is not working

Here delete option is providing Error:500 can any one fix it..?

#9272 report it
Vitalets at 2012/08/01 07:35am
RE: cannot get this to work correctly

hi lifeinthefridge

in your example in search grid you defined 'columns' twice. I suppose it's the reason.
When using ecolumns you should define all columns in EColumnsDialog. In grid you just make link to it as

'columns' => $dialog->columns(),

If you want you button columns to be shown always - use fixedRight property of ecolumns.

Hope this helps!

#9196 report it
lifeinthefridge at 2012/07/27 10:41am
cannot get this to work correctly

Hi! I would really like to utilize this great extension. However, I am having issues.

I cannot seem to retain the cgridview search functionality, as well as having my button customization remain with the extension functioning. Perhaps you have experience solving this issue?

<?php
$dialog = $this->widget('ext.ecolumns.EColumnsDialog', array(
       'options'=>array(
            'title' => 'Layout settings',
            'autoOpen' => false,
            'show' =>  'fade',
            'hide' =>  'fade',
        ),
       'htmlOptions' => array('style' => 'display: none'), //disable flush of dialog content
       'ecolumns' => array(
            'gridId' =>'packaging-metric-grid', //id of related grid
            'storage' => 'cookie',  //where to store settings: 'db', 'session', 'cookie'
            'fixedRight' => array('CButtonColumn'), //fix button column to the right side 
            'model' =>  $model=new PackagingMetric, //model is used to get attribute labels
            'columns' => array(
                'room',
                'lot',
                'country',
                'total_labor_hours',
                'total_run_time',
                'std_rate',
                'rate_syr_mh', 
                'date',
 
 
           ),
       )
    ));
?>
//grid search
    $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'packaging-metric-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns' => $dialog->columns(),
    'template' => $dialog->link()."{summary}\n{items}\n{pager}",
 
    'enablePagination'=>true,       
    'columns'=>array(
        //'id',
        //'room',
        'lot',
        'country',
        //'total_labor_hours',
        /*
        'total_run_time',
        'std_rate',*/
        'rate_syr_mh', 
        'date',
 
        array(
 
 
            'class'=>'CButtonColumn',
 
            'template'=>'{view}',
            'viewButtonLabel' => 'View Detailed',
 
            'buttons'=>array(
 
            'view'=> array(
            'url'=>'Yii::app()->createUrl("PackagingMetric/view", array("id"=>$data->id,"asDialog"=>1))',
            'options'=>array(  
            'ajax'=>array(
                'type'=>'POST',
                    // ajax post will use 'url' specified above 
                'url'=>"js:$(this).attr('href')", 
                'update'=>'#id_view',
               ),      
        ),
     ),
 
 
   ),
 
 
 
        ),
    ),
));

I want to retain the same default columns I have defined I currently have in my gridview. I am not sure how to replace $dialog->columns() within my original implemenation and keep everything functioning

#8588 report it
Vitalets at 2012/06/13 05:53am
RE: gridview id must be "grid1"?

hi hehbhehb,

1.have you also changed 'id' => 'grid2' for CGridView widget itself?

$this->widget('zii.widgets.grid.CGridView', array(
       'id' => 'grid2',
...

2.I agree, it's nice to have pageSize, it allowes to setup whole layout in one dialog. Thanks, I will try find time to add it.

#8583 report it
hehbhehb at 2012/06/13 12:38am
gridview id must be "grid1"?
  1. if gridview 'id' = 'grid1', everything is ok, but if set 'id' = 'grid2' or other name, it doesnt work...
  2. hope to add a parameter to define the itemsPerPage of gridview.
#8472 report it
Vitalets at 2012/06/06 07:36am
RE: Button text & empty columns

Hi artur_oliveira,

thanks for feedback! 1. For empty columns it is good idea, I will add it! 2. For button text I thought about it. I think we also should keep number of params at minimum, and I set only button html as more universal.

#8461 report it
Artur Oliveira at 2012/06/05 09:46pm
Button text translation

I noticed that the buttons text is hardcoded.

Could you please add a parameter to define only the button text instead off the all button

Thanks in advance

PS: Again great work!!!!!

#8460 report it
Artur Oliveira at 2012/06/05 09:16pm
Empty columns array

Hi vitalets

Nice work !!!!

I found a small issue with your extension, if the columns array is empty then the dialog shows no entries.

To solve this i added a small piece of code:

In EColumns.php add the following in the init() function:

...
if(is_string($this->fixedRight)) $this->fixedRight = array($this->fixedRight);
 
// ADD THIS - START
if(empty($this->columns)) {
        $this->columns = array_keys($this->model->getAttributes());
} 
// ADD THIS - END
 
//rewriting columns with unique keys
...
#8260 report it
Vitalets at 2012/05/22 02:31am
RE: "Many" Relationship

@Patrigan: hi, I see two ways for getting list of visible columns for this task:

  1. You can use $dialog->columns() that returns array of columns with visible property according to layout (as well as it used in CGridView confing). But it seems to be too late because renedring usually starts after dataprovider initialization.

  2. You can manually read visible columns from storage (session, db, cookie), it's just list separated by "|". But you also should pay attention that when user submits new layout, you need to read columns from POST, not storage (as storage was not updated yet)

hope this helps!

PS: for dublicated values in grid you may be intrested in my groupgridview extension :)

#8240 report it
Patrigan at 2012/05/21 04:01am
"Many" Relationship

So I currently use this with an SQL Data Provider combining a many-many relationship. The request is as follows: When I throw everything together, I have a combination of every related model. For example: a training can have multiple attendees and a user can attend multiple trainings. So the user and the training will be multiplied. The table will also contain additional information of each training and each user. Now the issue is as follows: When I select only the trianing title, I get a lot of duplicates (obviously). So how can I solve this? My idea was simple, I would just look at which columns are currently shown and adjust my SQL accordingly. At this point, however, I have been unable to find out where I could look at a list of enabled columns. Any ideas?

#8109 report it
Vitalets at 2012/05/10 04:04pm
named column layouts

@nitropenta: I also work with redmine :) Saving named column layouts is very usefull sometimes, I will think about it. But I assume it should be another widget as this feature is not always required.

Thank you!

#8076 report it
nitropenta at 2012/05/08 02:27pm
killer feature: save colums

Hi, I have the next big wish for the next version: save the columns adustment.

I work with the ticket system Redmine. Redmine have a similar feature at the filter options - you can see this at www.redmine.org/projects/redmine/wiki/RedmineIssueList#Applying-and-saving-filters

In a big table can I save different views with a name and reopen the adjustment with a link - and I should delete the link with an icon.

Yes! its christmas time ;-)

#8073 report it
Vitalets at 2012/05/08 12:17pm
attribute labels

@dkrochmalny:
1.I've modified code for pulling headers from attribute labels. For this you need to set model parameter in ecolumns config. Thanks for idea!

2.Reset button is managed by parameter buttonReset. But it should be visible by default. Could you re-check once again?

#8072 report it
nitropenta at 2012/05/08 11:12am
looks good

nitropenta

Leave a comment

Please to leave your comment.

Create extension