18

I have a function in my Teacher model which returns categories array.

getCaterogies() {
   return array('1' => 'short tempered', '2' => 'funny', '3' => 'visionary', ...);
}

I am storing indexes in database and displaying values everywhere using the value of the array corresponding to that..

$categories = $teacher->categories;
$category = $categories[$teacher->category];

I am doing this because once somebody suggested to me not to store strings in a database which are statuses, instead store integer values, and either store the conversion in the database or define it in ht model. The problem with strings is that they are more prone to human errors in comparisons. Maybe because of case sensitiveness.

Now the problem I am facing is that while displaying values in gridview, I need to write the 2 lines in a value field, but it is an expression, and outside variables also it doesn't take.

How can I get this working for gridview?

3 Answers 3

49

You can use anonymous function as value which can take $row, $data params where $row holds the row number (zero-based) and $data contains the data model for the row.

That way you can have it defined inside only.

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider,
    'columns'=>array(
        array(
            'name'=>'..',
            'value'=>function($data,$row){
                $categories = $teacher->categories;
                return $categories[$data->category];
            },
        ),
    ),
));

And if you want to use it from outside, you can rely on PHP's use:

$categories = $teacher->categories;
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider,
    'columns'=>array(
        array(
            'name'=>'..',
            'value'=>function($data,$row) use ($categories){
                return $categories[$data->category];
            },
        ),
    ),
));

I would personally recommend second one, because that way the calculation of the array will be only once and will be used in all cases.

Sign up to request clarification or add additional context in comments.

2 Comments

Tip: If need be - you might want to call a model function (for every record), to return multiple values that you want to print in different gridview columns for the said record. Instead of calling the function in every column, you can call it by the first column and update $categories with the result. The other columns could thus just read from $categories. To do this, 'use' the parameter by reference (simply add an ampersand (&) in front of the parameter when included - not inside the function as well). 'value'=>function($data,$row) use (&$categories){ $categories = ... },
Very useful tip! Thanks! function(...) use (...) looks like lambda in c++ :-)
2

You can write

$categories = $teacher->categories;
$category = $categories[$teacher->category];

in one line:

$category = $teacher->categories[$teacher->category];    

Also, I suggest you to use another solution:

class ModelClass
{
    const STATUS_SHORT_TEMPERED = 1;
    const STATUS_FUNNY = 2;
    const STATUS_VISIONARY = 3;
}

This allow you to use a more semantic

ModelClass::STATUS_FUNNY;

instead of less semantic

2;

Also, you can compose your array in this way:

getCaterogies() {
    return array(
        ModelClass::STATUS_FUNNY => 'status funny',
        ...
    );
}

2 Comments

are you sure $category = $teacher->categories[$teacher->category]; will wirk, because it is a dynamic getter in model and the getter which is returning me the array..
thankyou for your time and suggestions, but what i am looking for is precisely answered by the other guy, and I might need that solutions in many other cases..In this case your solution works perfectky, but latr I might need such use stuff..stackoverflow doesn't allow me to upvote..:(
0

'urlCreator' => function ($action, $model, $key, $index) use($under_category) {

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.