TbExtendedGridView

The most powerful Yii Grid

TbExtendedGridView booster.widgets.TbExtendedGridView

Have you ever thought to display a more elaborated summary of the data displayed on your grid? Or wanted to have a fixed header as you go down on thousand records? What about if you wish to display a chart of the data but not willing to leave the grid? And also, you wish to maintain that awesomeness even throughout AJAX calls? And what about if we tell you that we have done that?

With TbExtendedGridView you will be able to solve all those issues, plus we have also included some other columns that will help make the grid even more powerful:

  • TbJEditableColumn - for inline editing
  • TbTotalSumColumn - to sum up the total of a column and display it at its footer

New by setting the responsiveTable property to true (this is for all extended versions of TbGridView), tables will be automatically converted to suit mobile size. Try it by resizing the browser window and check this first example.

Fixed Header

Thanks to the great jquery plugin StickyTableHeaders we have managed to get this feature and make it as easy as to setup a simple boolean fixedHeader property to true.

Note It is important for the sake of the following examples that you reduce the height of your browser to see the effect.

#First nameLast nameLanguageHours workedEdit
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget(
    'booster.widgets.TbExtendedGridView',
    array(
        'fixedHeader' => true,
        'headerOffset' => 40,
        // 40px is the height of the main navigation at bootstrap
        'type' => 'striped',
        'dataProvider' => $gridDataProvider,
        'responsiveTable' => true,
        'template' => "{items}",
        'columns' => $gridColumns,
    )
);

Fixed header with Filter

#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget(
    'booster.widgets.TbExtendedGridView',
    array(
        'filter' => $person,
        'fixedHeader' => true,
        'type' => 'striped bordered',
        'headerOffset' => 40,
        // 40px is the height of the main navigation at bootstrap
        'dataProvider' => $gridDataProvider,
        'template' => "{items}",
        'columns' => $gridColumns,
    )
);

Sortable Rows

Sometimes, we may need to display a set of records that are ordered by a `position` on the database, and that order is important on the list. Most of the times, they are just a small amount of records that have a preference in a first-in first-out scenario. The extended grid view provides a mechanism to order the rows and report back through a javascript callback the new position of the data, so you could easily make an AJAX request to the server and update the list.

Note: It also will update the keys position, so you can safely use regular $.fn.yiiGridView functions.

#First nameLast nameLanguageHours worked
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'sortableRows'=>true,
    'afterSortableUpdate' => 'js:function(id, position){ console.log("id: "+id+", position:"+position);}',
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'columns' => $gridColumns,
));

Selectable Cells

The TbExtendedGridView allows you also to provide a selectable mechanism to its cells. This is very useful when you wish to display some feedback information related to the selected cells.

The following example demonstrates the above. Select the cells of the Hours worked column to see its total on the span tag with id: 'hours'.

Sum Of Selected Hours: 0
#First nameLast nameLanguageHours worked
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
<span class="label label-info">Sum Of Selected Hours</span>: <span id="hours">0</span>
<?php
$this->widget('booster.widgets.TbExtendedGridView', array(
    'selectableCells'=>true,
    'selectableCellsFilter'=>'td.tobeselected',
    'afterSelectableCells' => 'js:function(selected){
        var sum = 0;
        $.each(selected, function(){
        sum += parseInt($(this).text());
        });
        $("#hours").html(sum);
    }',
    'type' => 'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'columns' => array_slice($gridColumns, 0, count($gridColumns)-1),
));
?>

Bulk Actions

The extended grid allows you to display bulk action buttons on its footer. The configuration options of the buttons are the same as regular TbButton widgets, the only difference is that you can set its 'click' handler, which will be triggered having the selected checkbox elements as a parameter to the function.

Note: The buttons won't be functional (active) until at least one checkbox element is on its checked state.

Note: The the bulk action is working only on the current visible checked items, and does not maintain state between pages, or after sort/filtering

#First nameLast nameLanguageHours workedEdit
    
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'type' => 'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'selectableRows' => 2,
    'bulkActions' => array(
    'actionButtons' => array(
        array(
            'buttonType' => 'button',
            'context' => 'primary',
            'size' => 'small',
            'label' => 'Testing Primary Bulk Actions',
            'click' => 'js:function(values){console.log(values);}'
            )
        ),
        // if grid doesn't have a checkbox column type, it will attach
        // one and this configuration will be part of it
        'checkBoxColumnConfig' => array(
            'name' => 'id'
        ),
    ),
    'columns' => $gridColumns,
));

Extended Summary

There are so many times that a client wishes to see a summary of the records displayed on your grid. When that occurs, we found ourselves, poor programmers building a sub-grid that will display the summary and forcing us to loop through the data provider once more, slowing down our app.

We have included an extended summary version into this great grid component in order to save us time and headaches. The grid makes use of the following components for different displays:

Name Description
TbSumOperation Will display the sum of an specific column
TbCountOfTypeOperation Displays the number of times a type of value appears in the specified column cell (ie. total of zeros, total of ones).
TbPercentOfTypeOperation Displays the percent number of times a type of value appears in the specified column cell (ie. percent of zeros, percent of ones)
TbPercentOfTypeEasyPieOperation Displays the percent number of times a type of value appears in the specified column cell on pie charts. The handling of its display is taken care by the nice jquery plugin easy-pie-chart.
TbPercentOfTypeGooglePieOperation Well, you guessed right. It is the same operation as TbPercentOfTypeEasyPieOperation but with the difference that this pie is more powerful as it can render a single pie to display the summary results.
Important! when using charts you may need to check browser compatibility. As you know, most of these plugins do use canvas for their rendering.

Examples

TbSumOperation
#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}\n{extendedSummary}",
    'columns' => $gridColumns,
    'extendedSummary' => array(
        'title' => 'Total Employee Hours',
        'columns' => array(
            'hours' => array('label'=>'Total Hours', 'class'=>'TbSumOperation')
        )
    ),
    'extendedSummaryOptions' => array(
        'class' => 'well pull-right',
        'style' => 'width:300px'
    ),
));
TbCountOfTypeOperation
#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}\n{extendedSummary}",
    'columns' => $gridColumns,
    'extendedSummary' => array(
        'title' => 'Expertise',
        'columns' => array(
            'language' => array(
                'label'=>'Total Expertise',
                'types' => array(
                    'CSS'=>array('label'=>'Css'),
                    'JavaScript'=>array('label'=>'Js'),
                    'HTML'=>array('label'=>'html')
                ),
                'class'=>'TbCountOfTypeOperation'
            )
        )
    ),
    'extendedSummaryOptions' => array(
        'class' => 'well pull-right',
        'style' => 'width:300px'
    ),
));
TbPercentOfTypeOperation
#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}\n{extendedSummary}",
    'columns' => $gridColumns,
    'extendedSummary' => array(
        'title' => 'Expertise',
        'columns' => array(
            'language' => array(
                'label'=>'Total Expertise',
                'types' => array(
                    'CSS'=>array('label'=>'Css'),
                    'JavaScript'=>array('label'=>'Js'),
                    'HTML'=>array('label'=>'html')
                ),
                'class'=>'TbPercentOfTypeOperation'
            )
        )
    ),
    'extendedSummaryOptions' => array(
        'class' => 'well pull-right',
        'style' => 'width:400px'
    ),
));
TbPercentOfTypeEasyPieOperation
#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}\n{extendedSummary}",
    'columns' => $gridColumns,
    'extendedSummary' => array(
        'title' => 'Expertise',
        'columns' => array(
            'language' => array(
                'label'=>'Total Expertise',
                'types' => array(
                    'CSS'=>array('label'=>'Css'),
                    'JavaScript'=>array('label'=>'Js'),
                    'HTML'=>array('label'=>'html')
                ),
                'class'=>'TbPercentOfTypeEasyPieOperation',
                // you can also configure how the chart looks like
                'chartOptions' => array(
                    'barColor' => '#333',
                    'trackColor' => '#999',
                    'lineWidth' => 8 ,
                    'lineCap' => 'square'
                )
            )
        )
    ),
    'extendedSummaryOptions' => array(
        'class' => 'well pull-right',
        'style' => 'width:350px'
    ),
))
TbPercentOfTypeGooglePieOperation
#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}\n{extendedSummary}",
    'columns' => $gridColumns,
    'extendedSummary' => array(
        'title' => 'Expertise',
        'columns' => array(
            'language' => array(
                'label'=>'Total Expertise',
                'types' => array(
                    'CSS'=>array('label'=>'Css'),
                    'JavaScript'=>array('label'=>'Js'),
                    'HTML'=>array('label'=>'html')
                ),
                'class'=>'TbPercentOfTypeGooglePieOperation',
            )
        )
    ),
    'extendedSummaryOptions' => array(
        'class' => 'well pull-right',
        'style' => 'width:300px'
    ),
))

The Grid/Chart switcher

There will be times, where you wish to see a bit more details on a graphic than just those values on a pie chart. TbExtendedGridView aims to provide an easy to configure chart display, where the data is automatically extracted from its dataProvider.

The way it works, is that you set a couple of configuration options of the chartOptions property and thats it. The grid will automatically display a chart by making use of the great Higcharts JS library. We highly recommend you to get familiar with this library if you are going to make use of this feature.

The chartOptions property is a configurable chart array with three elements:

  • defaultView, which is a flag used to set the chart as the default view of the widget
  • data, which will contain the series attribute of Highcharts JS
  • config, will hold the rest of the chart configuration options
  • htmlOptions, the HTML tag attributes of the chart container.
Important! the style and data-config attributes of the container will be overrided, as they are required for the correct functionality of the chart.

Important: Highcharts JS is not open source for commercial products. We have include this chart library as we thought is one of the best around. We will update the library to support more charts in future releases.

Example

#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}\n{extendedSummary}",
    'columns' => $gridColumns,
    'chartOptions' => array(
        'defaultView' => true,
        'data' => array(
            'series' => array(
                array(
                    'name' => 'Hours worked',
                    'attribute' => 'hours'
                )
            ),
            'xAxis' => array(
                'categories' => 'firstName',
            ),
        ),
        'config' => array(
            'chart' => array(
                // 'width' => '800' // default reflow
            )
        ),
    ),
));

The TbGroupGridView widget

We have worked a bit and modified slightly the great work of Vitaliy Potapov, BootGroupView, to provide our library with a grid that features row and cell merging and/or grouping.

Examples

Merge in one column
#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyMan15
$this->widget('booster.widgets.TbGroupGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'extraRowColumns'=> array('firstLetter'),
    'extraRowExpression' =>  '"<b style=\"font-size: 3em; color: #333;\">".substr($data->firstName, 0, 1)."</b>"',
    'extraRowHtmlOptions' => array('style'=>'padding:10px'),
    'columns' => $gridColumns,
    'mergeColumns' => array('language')
));
Merge in two columns
#First nameLast nameLanguageHours workedEdit
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyMan
$this->widget('booster.widgets.TbGroupGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'extraRowColumns'=> array('firstLetter'),
    'extraRowExpression' =>  '"<b style=\"font-size: 3em; color: #333;\">".substr($data->firstName, 0, 1)."</b>"',
    'extraRowHtmlOptions' => array('style'=>'padding:10px'),
    'columns' => $gridColumns,
    'mergeColumns' => array('language', 'hours')
));
Extra Row
Note That TbGroupGridView now has its own js plugin $.fn.yiiGroupGridView() , it is just o copy of the yiiGridView one with some modifications -same API interface- , for example we use the following code to get the currently selected row id:
$('#grid-id').yiiGroupGridView('getSelection');
#First nameLast nameLanguageHours workedEdit
 
 
M
1MarkOttoCSS10 M
J
2JacobThorntonJavaScript20 J
S
3StuDentHTML15 S
4SunnyManHTML15 S
$groupGridColumns = $gridColumns;
$groupGridColumns[] = array(
    'name' => 'firstLetter',
    'value' => 'substr($data->firstName, 0, 1)',
    'headerHtmlOptions' => array('style'=>'display:none'),
    'htmlOptions' =>array('style'=>'display:none')
);

$this->widget('booster.widgets.TbGroupGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'extraRowColumns'=> array('firstLetter'),
    'extraRowExpression' => '"<b style=\"font-size: 3em; color: #333;\">".substr($data->firstName, 0, 1)."</b>"',
    'extraRowHtmlOptions' => array('style'=>'padding:10px'),
    'columns' => $groupGridColumns
));
Extra Row + Merge
#First nameLast nameLanguageHours workedEdit
 
 
M
1MarkOttoCSS10 M
J
2JacobThorntonJavaScript20 J
S
3StuDentHTML15 S
4SunnyManHTML S
$groupGridColumns = $gridColumns;
$groupGridColumns[] = array(
    'name' => 'firstLetter',
    'value' => 'substr($data->firstName, 0, 1)',
    'headerHtmlOptions' => array('style'=>'display:none'),
    'htmlOptions' =>array('style'=>'display:none')
);

$this->widget('booster.widgets.TbGroupGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $groupDataProvider,
    'template' => "{items}",
    'extraRowColumns'=> array('firstLetter'),
    'extraRowExpression' => '"<b style=\"font-size: 3em; color: #333;\">".substr($data->firstName, 0, 1)."</b>"',
    'extraRowHtmlOptions' => array('style'=>'padding:10px'),
    'columns' => $groupGridColumns,
    'mergeColumns' => array('hours')
));

The TbExtendedFilter widget

There are times, where you wish to save your filters and we are forced to use different types of storage systems to keep track of the filters (ie: Session variables with serialized objects, Cookies, Db, etc).

YiiBooster proposed a different approach and even though the first version is working with JSON storage (at the server side) we want to provide filters to be saved at the database instead.

It use is a bit tricky, you can use it with any CGridView instance of Booster or even the CGridView itself, but the grid has to be extended and then override renderTableHeader() to display it.

Example

Overriding TbGridView

As previously said, we first need to override an CGridView, for the example we are going to make use of TbGridView

// import required classes to my widget
Yii::import('booster.widgets.TbGridView');
Yii::import('booster.widgets.TbExtendedFilter');

class WMyGridView extends TbGridView {

    /**
    * We need this attribute in order to fire the saved filter.
    * In fact, you could remove its requirement from TbExtendedFilter but
    * we thought is better to provide 'less' magic.
    */
    public $redirectRoute;

    public function renderTableHeader()
    {
        if(!$this->hideHeader)
        {
            echo ">thead<\n";
            // Heads up! We are going to display our filter here
            $this->renderExtendedFilter();
            if($this->filterPosition===self::FILTER_POS_HEADER)
                $this->renderFilter();

            echo "<tr>\n";
            foreach($this->columns as $column)
                $column->renderHeaderCell();
            echo "</tr>\n";

            if($this->filterPosition===self::FILTER_POS_BODY)
                $this->renderFilter();

            echo "</thead>\n";
        }
        elseif($this->filter!==null && ($this->filterPosition===self::FILTER_POS_HEADER || $this->filterPosition===self::FILTER_POS_BODY))
        {
            echo "<thead>\n";
            // Heads up! We are going to display our filter here
            $this->renderExtendedFilter();
            $this->renderFilter();
            echo "</thead>\n";
        }
    }

    protected function renderExtendedFilter()
    {
        // at the moment it only works with instances of CActiveRecord
        if(!$this->filter instanceof CActiveRecord)
        {
            return  false;
        }
        $extendedFilter =  Yii::createComponent(array(
            'class' => 'TbExtendedFilter',
            'model' => $this->filter,
            'grid' => $this,
            'redirectRoute' => $this->redirectRoute //ie: array('/report/index', 'ajax'=>$this->id)
        ));

        $extendedFilter->init();
        $extendedFilter->run();
    }
}
Using our widget
Can't see it? Filter the next grid in order to see how the extended grid appears!
Note We save filters on the server, please make good use of this.
Country Code Region Name
CAAlberta
CABritish Columbia
CAManitoba
CANew Brunswick
 $this->widget('WMyGridView', array(
    'type' => 'striped bordered',
    'redirectRoute' => CHtml::normalizeUrl(''),
    'dataProvider' => $region->search(),
    'template' => "{items}",
    'filter' => $region,
    'columns' => array(
        array('name' => 'country_code', 'header' => 'Country Code'),
        array('name' => 'name', 'header' => 'Region Name'),
    ))
);?>
Extra Row
#First nameLast nameLanguageHours workedEdit
 
 
M
1MarkOttoCSS10 M
J
2JacobThorntonJavaScript20 J
S
3StuDentHTML15 S
4SunnyManHTML15 S
$groupGridColumns = $gridColumns;
$groupGridColumns[] = array(
    'name' => 'firstLetter',
    'value' => 'substr($data->firstName, 0, 1)',
    'headerHtmlOptions' => array('style'=>'display:none'),
    'htmlOptions' =>array('style'=>'display:none')
);

$this->widget('booster.widgets.TbGroupGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'extraRowColumns'=> array('firstLetter'),
    'extraRowExpression' => '"<b style=\"font-size: 3em; color: #333;\">".substr($data->firstName, 0, 1)."</b>"',
    'extraRowHtmlOptions' => array('style'=>'padding:10px'),
    'columns' => $groupGridColumns
));
Extra Row + Merge
#First nameLast nameLanguageHours workedEdit
 
 
M
1MarkOttoCSS10 M
J
2JacobThorntonJavaScript20 J
S
3StuDentHTML15 S
4SunnyManHTML S
$groupGridColumns = $gridColumns;
$groupGridColumns[] = array(
    'name' => 'firstLetter',
    'value' => 'substr($data->firstName, 0, 1)',
    'headerHtmlOptions' => array('style'=>'display:none'),
    'htmlOptions' =>array('style'=>'display:none')
);

$this->widget('booster.widgets.TbGroupGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $groupDataProvider,
    'template' => "{items}",
    'extraRowColumns'=> array('firstLetter'),
    'extraRowExpression' => '"<b style=\"font-size: 3em; color: #333;\">".substr($data->firstName, 0, 1)."</b>"',
    'extraRowHtmlOptions' => array('style'=>'padding:10px'),
    'columns' => $groupGridColumns,
    'mergeColumns' => array('hours')
));

Additional Columns

If you thought the above wasn't enough, we have created a couple of extra components (that we expect to grow) that increase the beauty of this grid.

Note: You can also use this column types with regular TbGridView widget.

TbImageColumn

Display an image on your grid. In order to display an image related to the data provider of the grid, you set its imagePathExpression. The expression string will have the following variables passed to it: $row (the row number), $data (the data module of the row) and $this (the column object).

 #First nameLast nameLanguageHours workedEdit
 
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'columns' => array_merge(array(array('class'=>'booster.widgets.TbImageColumn')),$gridColumns),
));

TbRelationalColumn

Display relational data or extra info from an ajax call into a dynamically created sub-row. This column is thought in order to display sub-grids or a more extended information about a model. The TbPopoverColumn has a similar behavior but the amount of information that we can display is a less that with TbRelationalColumn.

Important: Do not use this type of column to display a link. It is recommended to work with css classes instead to change the style of its contents.

Important: Be sure to include the required js files if your ajax returns a partial view that requires specific js files.

firstLetter#First nameLast nameLanguageHours workedEdit
 
test-subgrid1MarkOttoCSS10
test-subgrid2JacobThorntonJavaScript20
test-subgrid3StuDentHTML15
test-subgrid4SunnyManHTML15
// on your view
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'columns' => array_merge(array(
        array(
            'class'=>'booster.widgets.TbRelationalColumn',
            'name' => 'firstLetter',
            'url' => $this->createUrl('site/relational'),
            'value'=> '"test-subgrid"',
            'afterAjaxUpdate' => 'js:function(tr,rowid,data){
                bootbox.alert("I have afterAjax events too!
This will only happen once for row with id: "+rowid); }' ) ),$gridColumns), )); // on your controller // example code for action rendering the relational data public function actionRelational() { // partially rendering "_relational" view $this->renderPartial('_relational', array( 'id' => Yii::app()->getRequest()->getParam('id'), 'gridDataProvider' => $this->getGridDataProvider(), 'gridColumns' => $this->getGridColumns() )); } // example code for the view "_relational" that returns the HTML content echo CHtml::tag('h3',array(),'RELATIONAL DATA EXAMPLE ROW : "'.$id.'"'); $this->widget('booster.widgets.TbExtendedGridView', array( 'type'=>'striped bordered', 'dataProvider' => $gridDataProvider, 'template' => "{items}", 'columns' => array_merge(array(array('class'=>'booster.widgets.TbImageColumn')),$gridColumns), ));

TbTotalSumColumn

Sometimes we just need to sum up and there is no need to display it on a summary.

#First nameLast nameLanguageHours worked 
 
   Total Hours60 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget('booster.widgets.TbExtendedGridView', array(
    'filter'=>$person,
    'type'=>'striped bordered',
    'dataProvider' => $gridDataProvider,
    'template' => "{items}",
    'columns' =>array(
        array('name'=>'id', 'header'=>'#', 'htmlOptions'=>array('style'=>'width: 60px')),
        array('name'=>'firstName', 'header'=>'First name'),
        array('name'=>'lastName', 'header'=>'Last name'),
        array('name'=>'language', 'header'=>'Language', 'footer'=>'Total Hours'),
        array(
            'name'=>'hours',
            'header'=>'Hours worked',
            'class'=>'booster.widgets.TbTotalSumColumn'
        ),
        array(
            'htmlOptions' => array('nowrap'=>'nowrap'),
            'class'=>'booster.widgets.TbButtonColumn',
            'viewButtonUrl'=>null,
            'updateButtonUrl'=>null,
            'deleteButtonUrl'=>null,
        )
    ),
));

TbToggleColumn

Allows to modify the value of column on the fly. This type of column is good when you wish to modify the value of a displayed model that has two states: yes-no, true-false, 1-0, yin-yan, etc...

The widget works in conjunction with an action that will receive the id and the attribute parameters. YiiBooster comes with an action ready to use for that purpose: TbToggleAction.

See the next example on how to use:

Country Code Region Name Toggle
CAAlberta
CABritish Columbia
CAManitoba
CANew Brunswick
$this->widget(
    'booster.widgets.TbGridView',
    array(
        'type' => 'striped bordered',
        'dataProvider' => new CActiveDataProvider('Region', array('criteria' => array('condition' => 'id<5'))),
        'template' => "{items}",
        'columns' => array(
            array('name' => 'country_code', 'header' => 'Country Code'),
            array('name' => 'name', 'header' => 'Region Name'),
            array(
                'class' => 'booster.widgets.TbToggleColumn',
                'toggleAction' => 'example/toggle',
                'name' => 'status',
                'header' => 'Toggle'
            ),
        )
    )
);

At the toggleAction endpoint you should have something like this:

public function actions()
{
    return array(
        'toggle' => array(
            'class'=>'booster.actions.TbToggleAction',
            'modelName' => 'Region',
        )
    );
}

Here you see that we install TbToggleAction from YiiBooster inside our controller actions.

TbPopoverColumn

Display whatever content you wish with this cool plugin. It makes use of a bootstrap tooltip plugin that we have developed, so you can configure your picker with the regular bootstrap tooltip options plus an extra one: width.

#First nameLast nameLanguageHours worked 
 
1MarkOttoCSS10
2JacobThorntonJavaScript20
3StuDentHTML15
4SunnyManHTML15
$this->widget(
    'booster.widgets.TbExtendedGridView',
    array(
        'filter' => $person,
        'type' => 'striped bordered',
        'dataProvider' => $gridDataProvider,
        'template' => "{items}",
        'columns' => array(
            array(
                'name' => 'id',
                'header' => '#',
                'htmlOptions' => array('style' => 'width: 60px')
            ),
            array('name' => 'firstName', 'header' => 'First name'),
            array('name' => 'lastName', 'header' => 'Last name'),
            array('name' => 'language', 'header' => 'Language'),
            array(
                'name' => 'hours',
                'header' => 'Hours worked',
                'class' => 'booster.widgets.TbPopoverColumn',
                'options' => array(
                    'title' => 'Where did I spend my hours',
                    'content' => 'js:function(){ return "Why do you want to know?"; }',
                )
            ),
            array(
                'htmlOptions' => array('nowrap' => 'nowrap'),
                'class' => 'booster.widgets.TbButtonColumn',
                'viewButtonUrl' => null,
                'updateButtonUrl' => null,
                'deleteButtonUrl' => null,
            )
        )
    )
);

TbEditableColumn

You can provide of inline editing capabilities with this column to your grid. The following example show how it works. Please, click on any of the region names to edit.

# Country Code Region Name 
3577TRMalatya
1501HNCholuteca
2362MNHovsgol
1665INJammu and Kashmir
1148GBRichmond upon Thames
1286GEAdigenis Raioni
3150SDDarfur
3384SVLa Paz
1395GNLabe
605CHThurgau
$this->widget(
    'booster.widgets.TbExtendedGridView',
    array(
        'type' => 'striped bordered',
        'dataProvider' => new CActiveDataProvider('Region', array(
            'criteria' => array(
                'limit' => 10,
                'order' => 'RAND()'
            )
        )),
        'template' => "{items}",
        'columns' => array(
            array(
                'name' => 'id',
                'header' => '#',
                'htmlOptions' => array('style' => 'width: 60px')
            ),
            array('name' => 'country_code', 'header' => 'Country Code'),
            array(
                'name' => 'name',
                'header' => 'Region Name',
                'class' => 'booster.widgets.TbEditableColumn',
                'headerHtmlOptions' => array('style' => 'width:200px'),
                'editable' => array(
                    'type' => 'text',
                    'url' => '/example/editable'
                )
            ),
            array(
                'htmlOptions' => array('nowrap' => 'nowrap'),
                'class' => 'booster.widgets.TbButtonColumn',
                'viewButtonUrl' => null,
                'updateButtonUrl' => null,
                'deleteButtonUrl' => null,
            )
        )
    )
);

For the sake of the example, we have just echo the value to the client, but you get the idea on how it should work on the server

$r = Yii::app()->getRequest();
// we can check whether is comming from a specific grid id too
// avoided for the sake of the example
if($r->getParam('editable'))
{
    //echo $r->getParam('attribute');
    echo $r->getParam('value');
    Yii::app()->end();
}