0
votes

Having some trouble with CGridView on Yii Framework...

I'm looking to replace the contents of a column based on the value it holds. I need to handle special cases so I added a function into the model to return a value to the GridView. I get the resulting error " Undefined variable: model ".

I'm sure it's likely something simple. Is it because my dataProvider is not model?

Here is a shortened version of my code:

<?php
/* @var $this BookController */
/* @var $dataProvider CActiveDataProvider */
/* @var $model Book */

<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'book-grid',
    'dataProvider'=>$dataProvider,
    'columns'=>array(
        array(
            'name'=>'userName',
            'header'=>'Name',
            ),
        array(
            'name'=>'status',
            'header'=>'Status',
            'type'=>'raw',
            'value'=>array($model, 'statusText')
            ),
    )
));

?>

And here is code in models/Book.php

class Book extends CActiveRecord
{
    ...
    ...

    public function statusText($data, $row) {
        $content = '';

        if (CHtml::encode($data->status) == "processed") {
            $content = "Process completed";
        }
        else if ($data->status=="") {
            $content = "Queued for Processing";
        }
        else {
            $content = CHtml::encode($data->status);
        }

        return $content;
    }

    ...
    ...
}
2
I'm probably wrong, but have you actually passed your model to the view file? That would explain the error you're getting. Your controller should have something like $this->render('view', array('dataProvider' => $dataProvider, 'model' => $model)); to make model available in the view file. - Joe Miller
@JoeMiller This is wrong indeed. The CGridView uses the given CActiveDataProvider, and kind of iterates through it. So, the '$model' here is dynamic, it is depanding on the iteration of the CGridView widget. Inside this iteration, $data is used and not $model. - veelen
Ah, that's not quite correct. In the definition of CGridView, if your declaring a user defined function in the way that you are, then you need to be referring directly to the model. Your CGridView statement is correct, but the view file doesn't have access to a variable called $model yet, which is why you're getting the errror message. Try adding the model to your controller render statement and see if that works. - Joe Miller
@JoeMiller But why should you do that, if you are already supplying a bunch of the same models, via the DataProvider? - veelen
@veelen because you want to refer to the variable $model in your view file. If you don't then you won't be able to access the user defined function that you want to. What I usually do is just pass the model to the view file, then declare the dataProvider for CGridView as being $model->search(), or something like that. Either way, CGridView needs to know the model you are using to declare the function, and the dataProvider does not have that information. - Joe Miller

2 Answers

1
votes

Here is a simplified example from my current project;

    <?php

    //My controller
    class NewsController extends CController {


//The admin action
        public function actionAdmin() {
            $model = new News;

            $this->render('admin', array(
                'model' => $model
            ));
        }

    }

    //In my view file
    $this->widget('ext.widgets.MyTbGridView', array(
        'dataProvider' => $model->search(),
        'columns' => array(
            array(
                'name' => 'id',
                'filter' => false,
            ),
            array(
                'name' => 'title',
            ),
            array(
                'value' => array($model, 'gridDate')
            ),
        ),
    ));

    //My model function
    class News extends CActiveRecord {

        public function gridDate($data, $row) {
            return 'Date formatted!';
        }

    }
    ?>

The code 'value' => array($model, 'gridFormatDate'), is important. there are two possibilities here. The function can reside in the controller, in which case it should be 'value' => array($this, 'gridFormatDate'), or it can be in the model, in which case the correct code is given

0
votes

In stead of array($model, 'statusText'), try '$data->statusText'.

The method in your model should be like this:

public function getStatusText() {
        $content = '';

        if (CHtml::encode($this->status) == "processed") {
            $content = "Process completed";
        }
        else if ($this->status=="") {
            $content = "Queued for Processing";
        }
        else {
            $content = CHtml::encode($this->status);
        }

        return $content;
    }