CGridView Default Sort Order Icon

Is there any way we can display the sort order icon (up or down arrow) if ‘defaultOrder’ has been specified in the sort array of CActiveDataProvider?

I have the same question.

I had the same problem a while ago - http://www.yiiframew…7943#entry37943

As I read your post here… I decided to take a look at this… and added this option

http://code.google.c…e/detail?r=2551

NOTE: It will work only for one field defaultOrder like:


'defaultOrder'=>'username desc'

If you use more columns in defaultOreder like


'defaultOrder'=>'name,username desc'

no icons will be set…

Cheers boss, that has worked.

Hi GSTAR… as Qiang commented on this revision… we will probably revert it as it’s not needed…

You can use


'defaultOrder'=>array('username'=>true)

to get the same functionality…

the string version can be used for something totaly different like


'defaultOrder'=>'UPPER(username)'

Cheers mdomba. That works well too, only thing I would add is that it doesn’t really make sense when the array values have to be set to either true or false (true=descending sort, false=ascending sort) - I think we could just use ‘asc’ or ‘desc’ for the values but that’s just my personal opinion.

Also I noticed we can specify multiple sort values and we get multiple icons. But that could confuse the user…

Also I had a look at the updated description text in the trunk. Though I understand that ‘defaultOrder’ is a property of CSort and not CGridView, there is no indication that one would need to use the array format to get the sort icon.

Perhaps ‘defaultOrder’ should always be an array? Also you will need to update the property type in the Public Properties table.

I feel the same on both points… it’s just not intuitive…

Best thing I can tell you is to open an issue so all developers can decide on this…

I had this feeling too (you can read it in the issue comments)… but could not come with a nice sentence about this… because it’s a CSort proterty that can be used with other components not only with CGridView…

My first idea was to add a defaultOrder property to CGridView, there we could describe it more properly… but that would just copy the values to the CSort->defaultOrder property and possibly complicate things…

That would not be enough if someone needs some special sorting option like for example ‘orderDefault’=>‘LOWER(username)’

Thanks for this… just updated…

Hi, I’m using CSort with CArrayDataProvider and ‘orderDefault’=>‘LOWER(username)’ throws an Exception with the message (in spanish):

"Propiedad "Persona"."UPPER(nick)" no se encuentra definida."

Inspecting CArrayDataProvider.getSortDirections() I can see it process asc and desc strings, but not lower and upper. Any suggestions? please help me!

LOWER(username) is an MySql function… so the MySql processes the data and CActivedataProvider gets the needed data…

but as you are using CArrayDataProvider … you cannot use the LOWER() function here…

Thanks for reply! What you say is true, in fact, LOWER is an ANSI SQL function. But, if CSort admits that value for its property defaultOrder and CArrayDataProvider admits CSort as its sorting configuration, then, ideally it should work. The value of the property of an object must not depends on what objects are using the object. Is there some way to perform it? I’m am listing objects from two different tables, that’s why I used CArrayDataProvider:




$personas= Persona::model()->findAll($criteria);

$empresas= Empresa::model()->findAll($criteria);

    	

$dataProvider= new CArrayDataProvider(array_merge($personas, $empresas), array(

	'sort'=> array(

		'attributes'=> array(

			'nick',

			'actividad1',

		),

		'defaultOrder'=>'nick'

	),

    	'pagination'=> array(

		'pageSize'=>self::PAGE_SIZE,

	),

));



the property accepts a string… so it accepts anything you write even something that does not exist anywhere like


'defaultOrder'=>'please sort it by the name but in lowercase'

but that does not mean that it should work :D

The sort for CArrayDataProvider is done in the sortData() method… http://www.yiiframework.com/doc/api/1.1/CArrayDataProvider#sortData-detail

Ok, but, ‘please sort it by the name but in lowercase’ does never work and ‘LOWER(name)’ works depending on the class that uses CSort, and I think this is not ok because, in the doc of CSort explicitly says that you can use the string ‘lower(name)’ (in the same way you can use ‘name ASC’) and in the CArrayDataProvider doc says that sorting is provided by CSort. It implies that you can use CArrayDataProvider with CSort having ‘LOWER(name)’ as its defaultOrder.

Maybe using LOWER(name) with CActiveDataProvider is a hack because we know that in the end, it is used to construct a SQL commmand. If so, I think it should be explicitly said in CSort documentation.

I think it would be very helpful to process lower an upper and I’m going to create MYCArrayDataProvider that extends of CArrayDataProvider to add this functionality :).

To say the truth… it depends on the data provider… as there could be some function implemented in certain dataproviders…

For example as I’m using PostgreSql I can use something like


'defaultOrder'=>'split_part(invoice_id,"-",4)'

but with MySql this does not work… not to mention the CArrayDataProvider…

Sure, ok, thanks a lot for your replies :)

Hello there,

I’m a newbie so please take with a grain of salt and I apologies in advance if this is not the correct location for the post.

I have been spending some time with CSqlDataProvider and getting a default sort to work along with it. According to the class reference CSqlDataProvider should allow for sorting and filtering to be used in a CGridView. I have to manually configure the where condition in my model search method for criteria.

The SQL is a nasty union and I from what I know a union can’t have a default sort, not that I know of anyway, but the class library reference does not get into any specifics regarding the conditions for CSort and defaultOrder.

I tried with both temporary and fixed tables with indexing to store the data for my model search method to access. I can sort on any field, except virtual, but a default sort will not work. I confirmed my syntax from various post and have been reading the forum for a while. I am wanting the ‘id’ field for the default sort which is indexed in both cases.

In the end I am forcing the default sort by using two tables, one to load the union and the second to load the default sort order. The second table is then used for the SELECT of the CSqlDataPorvider. If I place an order by in the SQL for the provider I can’t get paging to work correctly as to the order of the SQL.

Questions:

  1. Has anyone obtained a default sort with CSqlDataProvider? Is there any special setting if so?

  2. Will a virtual field work with CSqlDataPorvider or is there a way of doing this outside the SQL? I would assume the answer is no considering its not an object array being returned by the provider; however, perhaps i am missing something.

>> I have solved number 2 (I think but all is working);

In the model I have virtual property get and set. Include in safe list and attributes, and in my search I include the FK (status_code_id) and Display value (status_description) in the SQL for the provider. I also have manual criteria for the key. I use the following column def.

array(‘name’=>‘status_code_id’,

  'header'=>'Status',


  'value'=>'$data["status_description"]',


  'filter'=> CHtml::listData(StatusCode::model()->findAll(), 'id', 'status_description'),


            ),  

In the search form I have a listData as well.

thanks.

Thank you very much!!