Let's assume you have active record with Status attribute. Status can be Created, Confirmed and Rejected. In database table you have column status_id and store ID of each status according to some map, e.g.
ID Status
0 Created
10 Confirmed
20 Rejected

There are two ways of storing text representation of statuses:
1. create additional table in database, e.g. tbl_status (id, text), create Status model and setup relation
2. store in php code as constants (and this extension should help)
If you have many statuses or they are changing frequently I suggest to use first way.
But if statuses more or less fixed and you don't want to create additional table/model you can try ListBehavior. With it you can easliy use constants (such as STATUS_CREATED etc.), show text and html representations and get array with all values (for dropdown).
Developed and tested on Yii 1.1.10
1.Copy ListBehavior.php into protected/components folder.
2.Create your class extending ListBehavior like this:
class StatusBehavior extends ListBehavior { const CREATED = 1; const CONFIRMED = 10; const CANCELLED = 20; public function data() { return array( self::CREATED => array('text' => 'Created', 'color' => 'gray'), self::CONFIRMED => array('text' => 'Confirmed', 'color' => 'green'), self::CANCELLED => array('text' => 'Rejected', 'color' => 'red'), ); } /* or if you need only text public function data() { return array( self::CREATED => 'Created', self::CONFIRMED => 'Confirmed', self::CANCELLED => 'Rejected', ); } */ }
You can put this file to models directory as it's looks like tiny model.
3.Attach your behavior to active record (attribute parameter is requred):
class Document extends CActiveRecord { ... public function behaviors() { return array( 'status' => array( 'class' => 'StatusBehavior', 'attribute' => 'status_id', ), ); } }
4.That's it! Now you can use it via $model->status->text and $model->status->html.
$model = Document::model()->findByPk($pk); echo $model->status->html;
Or in columns property of CGridView:
$this->widget('zii.widgets.grid.CGridView', array( 'id'=>'grid-1', 'dataProvider'=>$model->search(), 'columns' = array( 'created_date', 'document_number', array( 'type' => 'raw', 'header' => 'Document Status', 'value' => '$data->status->html', ), ), ));
To get array with all possible values (e.g. for dropdown in form):
$listData = Document::model()->status->getList(); echo $form->activeDropDownList($model, 'status_id', $listData);
<span style="color: {color}">{text}</span>
There can be any tokens taken from array keys of data() method.
if($model->status_id == StatusBehavior::CREATED) { ... }
May, 8
Redesigned and fixed #8032
April, 23
Initial release
All comments are welcome!
Total 8 comments
Wow.... best extension! thanks :)
hi jmariani! It's usual CGridView.
Thank you!
Hi!
Thank you very much. I'll test the new version ASAP. Glad I helped to improve.
Question: Which grid are you using in your screenshot?
Regards!
@jmariani:
I've redesigned extension according to your comment. Now text and html values are populated in getText / getHtml methods.
so usage is the same but it's far more flexible as there is no dependency from afterFind / afterSave events and it does not matter was model saved or not.
Thank you!
I think I found the problem. You're populating the values with afterFind.
But if you create a new model, save, and then try to inspect the value, if will not be populated. So I fixed it by replicating your afterFind function in an afterSave function and now it works.
Pending fix is when you create a new model and try to inspect the value with the model unsaved.
I'll check that later.
Cya!
Hi:
This is my behavior code:
This is my behaviors() function:
The column voucherType in the table contains a value of 0. When I do this:
I get an empty value instead of "ingreso".
Any clues?
TIA!
I like this extension. Thank you very much!
This will save me some work as I use a few of these data structures. Thanks!
Leave a comment
Please login to leave your comment.