Cgridview -> Sort By Virtual Attribute

Well, this is my "Users" model:

public $fullname;

{other code here - not really important for this problem}

public function search()


         $sort = new CSort();

         $sort->attributes = array('*', 'CONCAT(surname, ", ", forename) AS fullname');

         $sort->defaultOrder = array('fullname' => CSort::SORT_ASC);

$criteria=new CDbCriteria;

         $criteria->select = array('*', 'CONCAT(surname, ", ", forename) AS fullname');

         $criteria->compare('id', $this->id);

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

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

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

         $criteria->compare('email', $this->email);

$criteria->compare('CONCAT(surname, ", ", forename)', $this->fullname, true);

$criteria->compare('company_id', $this->company_id);

$criteria->compare('grupa', $this->grupa);

$criteria->compare('active', $this->active);

return new CActiveDataProvider($this, array(



    'sort' => $sort,



The CGridView widget generated with such a data provider works fine but for whatever reason "Fullname" column is not sortable. Can anybody here give me a clue why this problem occures???

Thanks ahead!

Hi Ziggi,

Did you try this?

         $sort->attributes = array('*', 'fullname'');

Yes, of course.

And I believe I traced the origin of the problem. You may look here for details:


Dear Friend

I hope the following is helpful.

$sort->attributes = array('*', "fullname"=>array(

"asc"=>"CONCAT(surname, ", ", forename) ASC",

"desc"=>"CONCAT(surname, ", ", forename) DESC",


OR just do this.

$sort->attributes = array('*', "fullname"=>array());

High Regards.

Dear Standar Member "seenivasan" - I strongly encurage you to validate your "solutions" prior posting. Yet another time you drop your unfortunately not-really-helpful advice simply because you do not have a habit to test your "solutions"!

Now please (high regards) and read my bug report:

Dear Friend

That is why I avoided the virtual attribute fullname in values in declaration of attributes .

The key contains the virtual attribute.

I tested the things prior to posting.

I doubly cautious.

Dear seenivasan - I tested your solution and this is not working - the column header of the CGridView is not a link, and it is not possible to click on this and reverse the sort order etc.


Indeed - it is now working!

I made a typo - wrote “fulname” not "fullname’

Argh - I apologize!

Dear Friend

This is my code to simulate your scenario.


public $fullname;

public function rules()



		return array(

			array('fname, lname', 'required'),

			array('fname, lname', 'length', 'max'=>64),

			// Please remove those attributes that should not be searched.

			array('id, fname, lname,fullname', 'safe', 'on'=>'search'),



public function search()



		$criteria=new CDbCriteria;

                $criteria->select="*,CONCAT(fname,'-',lname) AS fullname";




		return new CActiveDataProvider($this, array(



			'asc'=>"CONCAT(fname,'-',lname)  ASC",

			'desc'=>"CONCAT(fname,'-',lname)  DESC",



		 // "sort"=>array('attributes'=>array('id'.'fname','lname','fullname'=>array()))




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













)); ?>

Just working fine.

You are my friend forever.

Further to your problem with virtual attributes, it only gets worse when the attribute is an array (eg.multiple languages from a related table).

I will be interested to see the response to your bug report, please post here when they do.

Yeap seenivasan,

You are right - I was wrong! I made a typo.

Apologize once again.

Do you have a getter function for fullname?

If you have getFullname() or getFullname(), then it would interfere with the virtual attribute of "fullname", IIRC.

Definitely, getter function is completely irrelevant in this point.

It was the beginning of my reseach and my conclusion was… irrelevant!