Friday 20 June 2014

Yii Grid filter with relations

In Yii there are 3 simple steps to implement filter for relational column in Gridview. Lets Say we have two models and relation between them.

Eg. Consider following example. Here we have 3 models City, State and Country. City has 2 columns state_id and country_id along with their relations.

<?php
    public function relations() {
        return array(
            'country' => array(self::BELONGS_TO, 'Country', 'country_id'),
            'state' => array(self::BELONGS_TO, 'State', 'state_id')
        );
    }
?>

Now after doing customization in City Gridview we need to implement filter for countries and states. Here are the following 3 simple steps to achieve this.

1) In Gridview:

<?php

$this->widget('bootstrap.widgets.TbGridView', array(
    'id' => 'city-grid',
    'template' => '{items}{summary}{pager}',
    'dataProvider' => $model->search(),
    'filter' => $model,
    'columns' => array(
        array(
            'name' => 'country.name',            
            'filter' => CHtml::activeTextField($model, 'country'),      
        ),
        array(
            'name' => 'state.name',
            'filter' => CHtml::activeTextField($model, 'state'),            
        ),
        array(
            'name' => 'name',
            'type' => 'raw',
            'value' => 'CHtml::link($data->name,"/city/update/$data->city_id")',
        ),        
        array(
            'class' => 'bootstrap.widgets.TbButtonColumn',
        ),
    ),
));
?>

Model:

2) In rules array:

<?php
public function rules() {
        return array(
            array('name', 'unique'),
            array('name, country_id', 'required'),
            array('state, country, city_id, country_id, state_id, name', 'safe', 'on' => 'search'),
        );
?>

3) In search() method:

<?php
    public function search() {    
        $criteria = new CDbCriteria;
        $criteria->together = true;
        $criteria->with = array('state', 'country');
        $criteria->compare('city_id', $this->city_id);        
        $criteria->compare('name', $this->name, true);
        $criteria->addSearchCondition('state.name', $this->state);
        $criteria->addSearchCondition('country.name', $this->country);

        $dataProvider = new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));

        return $dataProvider;
    }
?>

That's it! Hope it'll help you.

...See more Yii stuffs

Wednesday 11 June 2014

Display total amount on Yii Grid

In this example we are displaying total amount of two fields in footer. Here we are calling getTotal() method (Defined in Model. See Step 2) by passing three parameters to it. First parameters is $model->search()->getData() which returns the data items currently available, second and third parameters are the values of amount_1 and amount_2 respectively.

Step 1:

<?php
$this->widget('bootstrap.widgets.TbGridView', array(
    'id' => 'my-grid',
    'dataProvider' => $model->search(),
    'template' => '{items}',
    'columns' => array(
        array(
            'header' =>'Amount 1',
            'name' => 'amount_1',
            'footer'=>'Total (Amount 1 + Amount 2)',
        ),        
        array(
            'header' => 'Amount 2',
            'name' => 'amount_2',
            'footer' => $model->getTotal($model->search()->getData(), 'amount_1','amount_2'),
        ),        
    ),
));
?>

Step 2:

<?php
    public function getTotal($records, $data1, $data2) {
        $total = 0;
        foreach ($records as $record) {
            $total += $record->$data1 + $record->$data2;
        }
        return number_format($total, 2);
    }
?>