Yii grid

The only way I can think of is to find parent ‘tr’ and then to get ‘td’ data at needed position. For example if company_id is third column you could do:




var company_id = $(this).parents('tr').find('td').eq(3).text();



or something like that.

Anyway this looks ugly and the only good solution here would be to somehow have the entire data row in associative array. Of course this should be handled by the framework.

Although I like GridView implementation I disagree with one design decision: not to have data in client objects. It would be much more intuitive to have client object that holds row collection then having to traverse dom every time you need key for specific row (for example), or when you need data from cell.

@megabr I think I found what you are looking for


     array( 'class'=>'CLinkColumn',

                        'labelExpression'=>'$data->lastname',

                        'urlExpression'=>'Yii::app()->createUrl("participant/list",array("lastname"=>$data->lastname))',

                        'linkHtmlOptions'=>array('title'=>'See all entries with this last name')),

use labelExpression instead of label

also if you use linkHtmlOptions the lib file (CLinkColumn.php) has a typo on line 90, this has now been fixed by qiang.xue (Man! that guy is fast!).

doodle

One short question, isn’t it possible to sort for a related column in this CGridView e.g. for ‘gender.name’ which sorted by the actual name and not the gender_id ?

Hmm 4 days later still no answer so I guess it is not possible through yii directly without modifications??

is there a way to remember the last sort routine and page in a session or cookie?

@horizons: To sort related attributes or use more complex sorts, you need to define sort.attributes via data provider. Then, in the grid column, specify that virtual attribute to sort.

@bas_vdl: you may turn on sort.multiSort=true for data provider. This will enable sorting via multiple columns.

no I mean that yii will remember the page number and sort routine when you come back to the page. like the following scenario.

you’re viewing page 4 of your gridview sorted by the first name (/user/list). you need to edit one of the records so you click on the edit button at the end of the row and the page will display a form (/user/edit/id/2). after hitting the save button you would like to return too the gridview, page 4, sorted by the first name.

@qiang I tried this but I didn’t succed.

e.g. I tried to add the author username to the admin grid view and would also have to make it sortable via the username.

Modifications of the postcontroller of the blog demo in actionAdmin




$sort= new CSort;

$sort->attributes=array(

           'id'=>'id',

           'tags'=>'tags',

           'status'=>'status',

           'author.username'=>array(

                'asc'=>'author.username',

                'desc'=>'author.username DESC',

                'label'=>'Name'

            ),

 );

$sort->multiSort=true;

$dataProvider->setSort($sort);



and admin.php in the related view




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

    'dataProvider'=>$dataProvider,

    'pager'=>array('maxButtonCount'=>2),

    'columns'=>array(

        'id:raw',

        'tags:raw',

        'status:raw',

        array(

                'name'=>'author.username',

                'value'=>'$data->author->username',

                'sortable'=>true,

        ),

        array(

        	'name'=>'title',

        	'type'=>'raw',

        	'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'

        ),

        array(

        	'name'=>'status',

        	'value'=>'Lookup::item("PostStatus",$data->status)',

        ),

        'create_time:datetime',

        'update_time:datetime',

        array(

        	'class'=>'CButtonColumn',

        ),

    ),

    'template'=>"test:{summary}\n{pager}\n{items}\n{pager}",

));



The table column header is clickable, but the result wouldn’t been sorted by that clicked column e.g. by author username.

Thx in advance for showing me the mistake.

@bas_vdl: you need to explicitly write code to keep these parameters in session. When the next time the page is visited, if no page/sort parameters are given, you try to restore from session.

@horizons: rename ‘author.username’ to be a string without dots in CSort because the dots are used to separate different attributes in the GET parameter.

You mean I must add a virtual function to the Post model which access the relation property author.username?

If I only rename ‘author.username’ to ‘author_username’ in csort it doesn’t work.

Could you please post an example?

thx in advance

nono, I mean when you declare the “attributes” property in CSort, use ‘authorName’ as the key instead of ‘author.name’. Similarly, in the grid view, set ‘name’=>‘authorName’. You don’t need to modify Post model.

Thats what I have tested but then I get a

CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'author.username' in 'order clause'

Cause the sql used is only ‘SELECT * FROM tbl_post t ORDER BY author.username LIMIT 20’

Is there a ‘With’ option for the dataProvider so that the author relation is queried in one select and not via lazy loading?

Yes, in the criteria for data provider, you can configure ‘with’ option. See CDbCriteria for details about this option.

ok this was what was missing, thx for the little hint now it works ;)

just one thing this must also be added to my code above if the id column form the post table should also be sortable and showed as a column (caused of ambiguous column names when using a relation with the same column name in this case ‘id’)




'id'=>array(

  'asc'=>'t.id',

  'desc'=>'t.id DESC',

),



this is sadly a bit more coding lines, therefore i would love if there is a possibility to access the relation columns directly.

Glad to hear that. Maybe when you get time, you can help write a cookbook about this so that others can share your experience? Thanks.

Is there a way to show/hide CButtonColumn base on condition, such as only creator of a record in a table can edit/delete ?

rgds.

majin

Hi qiang,

i have just written a small extension to your CGridView. It is a Quickbar, that renders itself after the last row of the Grid.

It contains an empty input-field for every Column. The Button-Column contains an "+" which fires up this action:




  public function actionQuickCreate() {

    $model=new Model;

    if(isset($_POST['Model']))

    {

      $model->attributes=$_POST['Model'];

      if($model->save())

        $this->redirect(array('admin')); //<-- assuming the Grid was used unter view admin/

    }

  }



This adds the new entry and returns back to the Grid. With this technique you can quickly add up new rows in the table.

It can be activated by passing ‘showQuickBar’ => ‘true’ to the widget like this:




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

    'dataProvider'=>$dataProvider,

    'columns' => array(),

    'showQuickBar' => 'true'));



The new file is attached to this Post, maybe you find this useful. I would be really happy if you integrate this (or something better ;) ) in your next Version of CGridView.

If you like this Addition, i could code a ‘makeEditable’-Option that renders every row in an <input> Element and updates the record after leaving the Field (onBlur) by javascript (for “really” quick data manipulation).

What do you (or someone else) think?

Great job! I suggest you extend the existing classes rather than overwriting them. I believe both features you proposed are very nice addition. And users will love the enhanced grid view if you share it in our extension library.

In order to include these new features in the official library, we need to do much more work because we need to think about all possibilities to allow users to customize the widget (e.g. how about allowing users to use checkbox or dropdown list to enter data?)

Anyway, I will keep an eye on your work. I believe you will receive more feedback and realize many details to be filled in.

@thyseus: when i click in a column header for sorting the input fields disappear

I think this is a good example what are you coding:

http://www.pradosoft.com/demos/quickstart/?page=Controls.Samples.TDataGrid.Sample3

@Flavio: Yes, this looks very good, almost what i want, but i want to make the content editable even quicker.

@qiang: You are right, and that’s why i just started the CEditableGridView Extension:

http://www.yiiframework.com/extension/editablegridview/

It now supports check against CCheckBoxColumn and i added a CEditableColumn.

Still need to work on Javascript integration ;)