[SOLVED] Can't sort a particular column in CGridView

I’m trying to make CGridView to sort a particular column, but so far I’ve been unsuccessful, can anybody figure out the problem?

in model:




	public function relations()

	{

		return array(

			'stats' => array(self::HAS_ONE,'CustomerStat','customerId'),

		);

	}


        public function search()

	{

		$criteria=new CDbCriteria;

		$criteria->compare('name',$this->name,true);

		$criteria->compare('city',$this->city,true);

		$criteria->compare('type',Customer::TYPE_CUSTOMER);

		$criteria->with = array('stats');


		return new CActiveDataProvider('Customer', array(

			'criteria' => $criteria,

			'sort' => array(

				'defaultOrder' => 'id DESC',

				'attributes' => array(

					'name',

					'city',

					'stats.balance',

				),

			),

			'pagination' => array(

				'pageSize' => CustomerController::PAGE_SIZE,

			),

		));

	}



and in the view:




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

	'dataProvider'=>$customer->search(),

	'filter' => $customer,

	'columns'=>array(

		'name',

		'city',

		array(

			'header' => 'Balance',

			'name' => 'stats.balance',

			'sortable' => true, //does not sort

		),

		'stats.balance:text:Balance', //does not sort

		$buttons,

	),

));



The columns “name” and “city” get sorted just fine, the application log shows the SQL to sort the fields just fine. But whenever I clicked the stats.balance the results get sorted based on the ‘defaultOrder’ attribute. Any ideas?

cheers

Ari

Hm… thats a real strange situation. I would bet 90:10 that the problem is related to your code, not Yii, but attempt to find, what is wrong can be a real pain.

First of all, don’t use both columns in the same time (your code defines two exactly the same columns in two different ways). It shouldn’t but can confuse CSort used for sorting purposes. What also come on my mind is, why you are using sortable to set it to TRUE, if this property of CDataColumn is set to TRUE by default? Have you tried sorting this column (first implementation) without sortable set to TRUE?

Found something in CDataColumn.sortable description, saying: “Note that if name is not set, or if name is not allowed by CSort, this property will be treated as false”, what means that CGridView won’t be sorted by that column in that case. Look somewhere around this, maybe this could be a clue to solving your problem.

Check out CSort.attributes: it states about halfway down, “Note, the attribute name should not contain ‘-’ or ‘.’ characters because they are used as separators.” So using “stats.balance” as an attribute name may be your problem.

In the CActiveDataProvider properties array, try changing ‘stats.balance’ to




'balance'=>array(

    'asc'=>'stats.balance',

    'desc'=>'stats.balance DESC',

    'label'=>'Balance Label',

    'default'=>'desc'

)



and in the CGridView properties array, change the name from ‘stats.balance’ to ‘balance’.

I’m not sure if this will work since I haven’t tested it myself, but hopefully it will help you solve the problem.

cheers

Thanks yoda! I tried your suggestion, but I got the "Customer.balance not defined" error.

So I added in the model:




public $balance;



and in the sort attribute:




	'balance'=>array(

		'asc'=>'stats.balance',

		'desc'=>'stats.balance DESC',

		'label'=>'Balance Label',

),



and then the view:




		array(

			'header' => 'Balance',

			'name' => 'balance',

			'sortable' => true,

			'value' => '$data->stats->balance',

		),



problem solved! Thanks all for the help, cheers