Yii Framework - CGridView sort related columns

Asked
Active3 hr before
Viewed126 times

6 Answers

framework
90%

This post has seriously helped me out, cheers to everyone involved. There was one thing though that I have extended on this. I use Yii translation files and needed to obviously make these sortable also. Here is my code for those people trying to do the same. Below we have a solution for sorting relational fields, link fields, translated fields, also working with the ecolumns extension.,By default, there appears to be some sorting going on with submitted/requested date, but they really aren’t working right. How would I go about getting this to allow sorting on ALL colums here? There’s three different column types, the LinkColumns, name/value columns and standard fields.,Also, I took a look at the blog demo and they had a CGridView with links in the columns that are also sortable. Interestingly, they are not using the CLinkColumn type, which I still cannot get to sort myself. The technique they used is something I tried, but without setting the ‘type’=‘raw’ parameter, it was coming out as text and not a link.,In sort you declared virtual columns "factura" and "produs", to sort on them you need to use it as columns in CGridView

Here’s what my CGridView looks like when I call it:

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

   'dataProvider' => $dataProvider,

   'columns' => array(

      array(

         'class' => 'CLinkColumn',

         'header' => 'Print Job Id',

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

         'urlExpression' => 'Yii::app()->createUrl("printjob/update",array("id"=>$data->printjob_id))',

      ),

      array(

         'name' => 'Job Type',

         'value' => '$data->job_type->job_type_name',

      ),

      array(

         'class' => 'CLinkColumn',

         'header' => 'Printjob Title',

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

         'urlExpression' => 'Yii::app()->createUrl("printjob/update",array("id"=>$data->printjob_id))',

      ),

      array(

         'name' => 'Customer',

         'value' => '$data->customer->customer_name',

      ),

      array(

         'name' => 'School',

         'value' => '$data->school->school_name',

      ),

      'submitted_date',

      'requested_date',

   ),

)); ? >
load more v
88%

when you list Posts in grid you would like to print author name in column, allow sort on this column and probably filtering by substring of author name. Best solution (in my opinion) to provide all this functionalities is:,I'm just wondering if this rule might cause table fields like xxx and yyy to bypass validation when being directly submitted by TbEditableColumn?,I resolved it initializing a variable like (public $owner_search = '';) this in the model and everything looks fine. I only hope is the right solution, too.,Thats it. We have sorting by user name instead of id_user foreign key column and we have search by user name substring.

Lets say we have two models and relation between them:

class Author extends CActiveRecord {
   ...
}

class Post extends CActiveRecord {
   ...
   function relations() {
      return array(
         'author' => array(self::BELONGS_TO, 'Author', 'id_author'),
      );
   }
   ...
}

First you have to add new attribute to Post model, where search string will be stored. You could use foreign key column to achieve same effect, but I preffer not to overload meaning of this column as in search scenario you will store there string, not foreign id. You have to add this new attribute to 'safe' attributes in search scenario.

class Post extends CActiveRecord {
   public $author_search;
   ...
   public
   function rules() {
      return array(
         ...
         array('xxx,yyy,author_search', 'safe', 'on' => 'search'),
      );
   }
}

Now we have to use this attribute in search criteria (in standard implementation - there is a search() function in every model). Also we have to specify that we want to fetch Post models together with related Author by setting 'with' attribute of criteria (this way there will be only one database query with join instead of many queries fetching related authors in lazy load mode):

$criteria = new CDbCriteria;
$criteria - > with = array('author');
...
$criteria - > compare('author.username', $this - > author_search, true);
...

And since we are editing search function - lets add another tricky feature to returned CActiveDataProvider:

return new CActiveDataProvider('Post', array(
   'criteria' => $criteria,
   'sort' => array(
      'attributes' => array(
         'author_search' => array(
            'asc' => 'author.username',
            'desc' => 'author.username DESC',
         ),
         '*',
      ),
   ),
));

Now we have prepared everything for our grid:

$this - > widget('zii.widgets.grid.CGridView', array(
   'dataProvider' => $model - > search(),
   'filter' => $model,
   'columns' => array(
      'title',
      'post_time',
      array('name' => 'author_search', 'value' => '$data->author->username'),
      //post strictly required user but in any case that model has not required user(or another relation) you should replace with it
      array('name' => 'author_search', 'value' => '$data->author ? $data->author->username: "-"'),
      array(
         'class' => 'CButtonColumn',
      ),
   ),
));
load more v
72%

Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers ,There is also good explanation how to do this on Yii web site Wiki page: http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/,I've got the "grid" to show the relation, and am able to use the search feature. What I can't figure out is the sort feature. The column header becomes non-clickable once the below changes have been made. ,I like Mike H's answer. I also want to point out that you could, instead of entering the raw SQL, use with() to perform a relational query and then set select to false to prevent actually loading the related models. You can also use the related attribute's attributeLabel in the view by passing the dot-notated string, e.g.,:

Model Search method:

$sort = new CSort();
$sort - > attributes = array(
'assignedTo' => array(
'asc' => '(SELECT surname from people 
WHERE people.person_id = t.assigned_to) ASC ',       
'desc' => '(SELECT surname from people 
WHERE people.person_id = t.assigned_to) DESC ',     
),
'*', // add all of the other columns as sortable   
);

View file:

$this - > widget('zii.widgets.grid.CGridView', array(
         'id' => 'tasks-grid',
         'dataProvider' => $model - > search(),
         //'filter'=>$model,
         'columns' => array(
            'task',
            array(
               'header' => 'Assigned To',
               'value' => '$data->assignedTo->surname.", ".$data->assignedTo->forename',
               'name' => 'assignedTo',
               'sortable' => TRUE,
            ),
            'due_date',
            'status',
         ),
load more v
65%

  php  -  frameworks  -  gridview  -  jquery-ui-sortable  -  yii ,There is also good explanation how to do this on Yii web site Wiki page: http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/,The Contents are licensed under creative commons.,If you find copyright violations, you can contact us at info-generacodice.com to request the removal of the content.

admin.php - VIEW

< ? php $this - > widget('zii.widgets.grid.CGridView', array(
         'id' => 'employee-grid',
         'dataProvider' => $model - > search(),
         'filter' => $model,
         'columns' => array(
            array(
               'name' => 'company',
               'value' => '$data->company->companyNick',
            ),
            'lastName',
            'firstName',

            ETC...

Employee.php - MODEL

public
function search() {
   // Warning: Please modify the following code to remove attributes that
   // should not be searched.

   $criteria = new CDbCriteria;

   //Company Relation Search
   $criteria - > compare('company.companyNick', $this - > company, true);
   $criteria - > with = 'company';

   //stock
   $criteria - > compare('idEmployee', $this - > idEmployee, true);
   $criteria - > compare('idAccount', $this - > idAccount, true);

   ETC...
load more v
75%

Yii TbGridView\Cgridview width of the table?,Yii cgridview from the graph to the right?,How to put a filter and sort on CGridView column?


array('header' => 'Заголовок', 'type' => 'raw', 'value' => '$data->id + 90', )
40%

I have a custom column in GridView. Actually it's model attribute but I needed to customize it for presenting data in more convenience way. How to add an ability to sort this column?,Even when you use a custom function to display the attribute, the sorting is done on the actual attribute that is stored in the DB.,For more complicated search/sort here is very good documentation related link to tutorial,Obviously, the function needs to do whatever transformations you need. But the sorting will be done on the actual data stored in the DB.

I have a custom column in GridView. Actually it's model attribute but I needed to customize it for presenting data in more convenience way. How to add an ability to sort this column?

< ? = GridView::widget([
   'dataProvider' => $dataProvider,
   'filterPosition' => GridView::FILTER_POS_HEADER,
   'columns' => [
      ['class' => 'yii\grid\SerialColumn'],

      'id',
      'username',
      'about:ntext',
      'birthdate',
      ['attribute' => 'sex',
         'header' => 'Sex',
         'content' => function($model) {
            return $model - > sex == 0 ? 'female' : 'male';
         },
         'label' => 'Sex',
         'enableSorting' => TRUE

      ],

      'email:email',

      ['class' => 'yii\grid\ActionColumn'],
   ],
]); ? >
load more v

Other "framework-undefined" queries related to "Yii Framework - CGridView sort related columns"