Jump to content
Larry Ullman's Book Forums

Problem With "Columns" Property Of Cgridview Widget


lrzins
 Share

Recommended Posts

Hi there, I've got a column defined in a CGridView widget, in the view file admin.php, that correctly returns the course_number attribute from a related table:

 

<?php $this->widget('zii.widgets.grid.CGridView', array(
        'id'=>'course-taken-grid',
        'dataProvider'=>$model->search(),
        'columns'=>array(
        'course.course_number',
        // Other columns
       array(
                        'class'=>'CButtonColumn',
                ),
        ),
)); ?>

For some reason, if I use the name/value syntax to do the same thing:

 

array('name'=>'Course', 'value'=>'$data->course->course_number'),

I get the error "Trying to get property of non-object".

 

I can't figure out why. In the same CGridView widget, in the same file, a simliar query works:

 

array('name'=>'Student Name', 'value'=>'$data->studentRecord->user->first_name . " " . $data->studentRecord->user->last_name'),

 

And I need to do something similiar in order to obtain the course number and department abbreviation from related tables.

 

Weird right?

 

Thanks for any tips.

 

Larry Z.

 

 

Link to comment
Share on other sites

Sorry to spam the list again. I just deleted all rows from the course_taken table, and it works now:

 

array('name'=>'Course', 'value'=>'$data->course->department->department_abbreviation . " " . $data->course->course_number'),
 

I did'nt even look at the data first, before deleting it, so it's not clear what the cause was. Onward!

 

Larry Z.

Link to comment
Share on other sites

I found the cause of the problem. It's that I need to have a NULL value in a foreign key. I have the foreign key "course_id" defined in a course_taken table, that references the course table, that needs to be NULL sometimes. In the CGridView widget, with a NULL value for "course_id" this way works:

 

'course.course_number',

and this way generates the error "Trying to get property of non-object":

 

array('name'=>'Course', 'value'=>'$data->course->course_number'),

So I believe the best solution is to check for a NULL in the 'value' property (above). Unfortunately this level of detail is not explained in the  Yii documentation.

 

Larry, will you be covering this stuff in the Widgets chapter of your wonderful book?

 

Larry Z.

Link to comment
Share on other sites

Well in fact that column is defined as:

 

array('name'=>'Course', 'value'=>'CValidator::isEmpty($data->course) ? "Other University" : $data->course->department->department_abbreviation . " " . $data->course->course_number'),

but now it's not sortable when clicking the column header.

 

I can't figure out how to sort this column. Is it easy?

 

Larry Z.

Link to comment
Share on other sites

Hey Larry,

 

Yes, I hope to cover this kind of thing, if I remember all the possible issues and permutations and such. As for your specific problem, I don't know the answer off the top of my head but will take some time to research it over the weekend if you're still struggling with it. Although I suspect you'll have figured it out by the time I click "Post"!

Link to comment
Share on other sites

Hi Larry, I got the column to sort. I'm fairly comfortable with the solution, but still wonder if there is a better way. I'll definitely revisit this later. Here's what I did:

 

Created a new attribute called $dept_course in my Model:

class Course extends CActiveRecord
{
        public $dept_course;
 

Then set up the search() method in the Course Model to use this attribute to access the related fields in the Department Model, and sort the returned values:

public function search()
        {
                $criteria=new CDbCriteria;
                $criteria->with = array('department');
                $criteria->compare('department.department_abbreviation',$this->dept_course,true);
                // Other compare criteria

                return new CActiveDataProvider($this, array(
                        'criteria'=>$criteria,
                        'sort'=>array(
                                'attributes'=>array(
                                        'dept_course'=>array(
                                                'asc'=>'department.department_abbreviation',
                                                'desc'=>'department.department_abbreviation desc',
                                        ),
                                        '*',
                                ),
                        ),
                ));

It was not necessary to add "dept_course" to the 'safe' scenario in the rules method of the Model.

 

Then in the admin.php view file, assign the new attribute to the name parameter of the columns array in the CGridView:

<?php $this->widget('zii.widgets.grid.CGridView', array(
        'id'=>'course-grid',
        'dataProvider'=>$model->search(),
        'columns'=>array(
                array('name'=>'dept_course', 'value'=>'$data->department->department_abbreviation . " " . $data->course_number', 'header'=>'Course'),

This solution was gleaned from the following wiki article:

 

http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview

 

Larry Z.

 

Link to comment
Share on other sites

Update: To sort by department abbreviation + course number, I had to use this in the Course model:

        public function search()
        {
                $criteria=new CDbCriteria;
                $criteria->with = array('department');
                $criteria->compare('department.department_abbreviation',$this->dept_course,true);
                // Other criteria

                return new CActiveDataProvider($this, array(
                        'criteria'=>$criteria,
                        'sort'=>array(
                                'attributes'=>array(
                                        'dept_course'=>array(
                                                'asc'=>'department.department_abbreviation, course_number',
                                                'desc'=>'department.department_abbreviation desc, course_number',
                                        ),
                                        '*',
                                ),
                        ),
                ));

Whew!

Link to comment
Share on other sites

Wow!!!!! I got it working!!!!  Iiiiieeeeeeeeyyyaaaaa!!!

 

I just had to change the 'desc' value (above) to this:

 

'desc'=>'department.department_abbreviation desc, course_number desc',

and now it finally sorts with two related fields.

 

Happy happy

 

Larry Z.

Link to comment
Share on other sites

 Share

×
×
  • Create New...