- Yii Cheat Sheet
- This part is if your models ARE related.
- Good luck and let me know if this works for you!
- BONUS:
Yii Cheat Sheet ¶
I keep a reference to some simple but painful task if you forget a common or something. I am new to Yii and this took awhile for me to figure out. Everything I read said do this or do that and not a single one worked for me. However, the following did.
Please note I'm using Yii 1.1.12.
The first part is if your models are NOT related.
Drop down with alphanumeric display for a numeric input
Say your dropdown field is binary and it inputs only numbers and you wanted to dispaly say a Yes, No, Male, Female, Active, Inactive etc. do the following.
model/_form
for example change 'gender', to:
<?php echo $form->dropDownList($form, 'gender', array('1' => 'Male', '2' => 'Female')); ?>
Same as above but adds an 'prompt' field at the top of your dropdown list if no value was selected.
<?php echo $form->dropDownList($form, 'gender', array('1' => 'Male', '2' => 'Female', 'prompt' => 'Select Gender')); ?>
The problem we have now is that it's going to disply 1 or 2 in your /view, /index and /admin tables. To change it to the alphanumeric value do the following:
Note:'gender' is my model name and you would be replacing 'gender', in the respected files listed below with the arrays that are also listed below.
model/view
array('name'=>'sex', 'type'=>'raw', 'value'=>$model->gender? "Male": "Female"),
(Note: Notice the 'type'=>'raw', this allows you to manipulate it to whatever you need. Also, it is going to assign the value in the numeric order. I.e. 1 = Male, 2 = Female, 3, 4, 5. So make sure you are consistant in your ording in your dropdown and views)
model/admin
array('name'=>'gender', 'value'=>'$data->gender? "Male": "Female"'),
you could also do something like this if you want a simple dropdown on your cgridview in your filter header:
array(
'name'=>'active_status', //
'type'=>'raw',
'value' =>'$data->active_status? "Active": "Inactive"', //converts my 1 and 0 to Active / Inactive
'filter' => array('0' => 'Inactive', '1' => 'Active'), // Adds a dropdown to the filter
'headerHtmlOptions' => array('style'=>'text-align:center; vertical-align: middle;font-size: 20px !important;'),
'htmlOptions'=>array('style'=>'text-align:center; vertical-align: middle;')
),
actual model file under protected/models
This part is if your models ARE related. ¶
NOTE: ALWAYS use the actual field name for the 'name' portions. Your filters will not recognize the filter by whatever name you want. It will only recognize the related model id numbers when filtering. Change the 'name' in your model to reflect what you want them to display as.
I.E.
The gridview filter won't work using this:
array('name'=>'Company Name', 'value'=>'$data->company->name'),
You would have to search by id number
Use this to actually search by the name
array('name'=>'company_id', 'value'=>'$data->company->name'),
in your model:
public function attributeLabels()
{
return array(
'company_id' => 'Company Name',
);
}
FOR THE FOLLOWING EXAPLES PLEASE NOTE: The easiest and fastest way to define relations is to add foreign key relationships before you create anything with gii. If you do so gii will generate the relations you.
My models are Contacts and Companies. I have relations defined between them both in their models. My Companies table (which is where the company comes from and in my database I have the name column as name. My Contacts table (which is where the firstname and lastname come from in my database my first name column is firstname and my lastname column is lastname)
Dropdown.
<?php echo $form->labelEx($model,'your_model'); ?>
<?php echo $form->dropDownList($model, 'your_model', CHtml::listData( Yourrelatingmodel::model()->findAll(), 'primary_key_of_relating_model', 'name'),array('class'=>'span5', 'prompt' => 'Select a Company')); ?>
<?php echo $form->error($model,'your_model'); ?>
So a real example would be
<?php echo $form->labelEx($model,'product_id'); ?>
<?php echo $form->dropDownList($model, 'product_id', CHtml::listData( Products::model()->findAll(), 'id', 'name'),array('class'=>'span3', 'prompt' => 'Select a Company')); ?>
<?php echo $form->error($model,'your_model'); ?>
Join two column name together in breadcrumbs/whatever using simple concatenation
I have columns firstname, lastname, and company that i want to show in my breadcrumbs so I did the following.
$model->firstname.' '.$model->lastname.' | '.$model->company,
So my complete breadcrumbs look like this
<?php
$this->breadcrumbs=array(
'Products'=>array('index'),
$model->contacts=>array('view','id'=>$model->contactid),
$model->firstname.' '.$model->lastname.' | '.$model->company,
);
?>
this outputs: Home>Contacts>John Doe | ABC Inc.
You can put whatever text between the ' ' . If you notice I chose to put 1 space between the ' ' to have a space between first and last names. Also a | between the last two models. You can also add text before/after by adding 'yourtext', before/after the line i added above.
Headings/titles:
Then as my title I put.
<h3><?php echo $model->firstname; ?> <?php echo $model->lastname; ?></h3>
or using concatenation as I like to do.
<h3><?php echo $model->firstname.' '.echo $model->lastname; ?></h3>
This outputs John Doe as the title.
Display name instead of number in potected/modelname/
NOTE IN ALL OF THE FOLLOWING EXAMPLES I REPLACED 'companyid', with the following arrays to show my name (the title of my name field) instead of the number.
/view
array('value'=>$model->company->name),
/admin
array('name'=>'company_id','value'=>'$data->company->name'),
/index
array('name'=>'company_id', 'value'=>'$data->company->name'),
Good luck and let me know if this works for you! ¶
BONUS: ¶
Add this to your grid view above columns and it will make the whole row clickable. Note: change products to your model name and use your id column name.
'htmlOptions'=>array('style'=>'cursor: pointer;'),
'selectionChanged'=>"function(id){window.location='" . Yii::app()->urlManager->createUrl('products/view', array('id'=>'productid')) . "' + $.fn.yiiGridView.getSelection(id);}",
Email link on click from grid view:
array(
'name'=>'email_address',
'type'=>'raw',
'value'=>'CHtml::link(CHtml::encode($data->email_address),"mailto:".$data->email_address)',
),
Make the field a link:
array(
'name' => 'company_id',
'type'=>'raw',
'value' =>'CHtml::link(CHtml::encode($data->company->name),
array("companies/view","id"=>$data->company_id))',
You can use the internal links with the whole link row. It will just make the text a link that is still clickable and the row will still be clickable.
Here is a working example of CGridView with the items above and some html options (I had to style one grid view seperatly from all of my others). If you want them all the same just change the css in your main css file.
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'products-grid',
'dataProvider'=>$dataProvider,
'itemsCssClass'=>'table table-striped table-bordered table-hover',
'template' => '{items}{pager}"',
'htmlOptions'=>array('style'=>'cursor: pointer; font-size: 20px !important; text-align:center; vertical-align: middle;'),
'selectionChanged'=>"function(id){window.location='" . Yii::app()->urlManager->createUrl('products/view', array('id'=>'')) . "' + $.fn.yiiGridView.getSelection(id);}",
'columns'=>array(
array(
'class'=>'EImageColumn',
'name' => 'productimg',
'headerHtmlOptions' => array('style'=>'text-align:center; vertical-align: middle; font-size: 20px !important;'),
'htmlOptions' => array('style' => 'width: 100px; height: 100px; margin-bottom: -3px; padding:2px;'),
),
array(
'name' => 'company_id',
'type'=>'raw',
'value' => 'CHtml::link(CHtml::encode($data->company->name),
array("companies/view","id"=>$data->company_id))',
......
));
?>
Search portion
there's a wiki for it: http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/
Search
EDIT: I got the search to work using the link bennouna provided in the comment below. I wasn't doing something right. I somehow googled something and a video of the link below popped up. THis is the video link. It's on youtube. also, it's not in English but you can get the idea.
Thank you bennouna! However, no dice for me. Maybe someone else can benefit from it.
Also, I read somewhere that you only put the t. before if your columns in both the tables are named the same thing. I.e. id and id. I know it's not in that example but it's in the link I posted.
Still need for unleated models :( any ideas?
Label portion
The standard way of conversion from value to text is something like this:
class Person extends CActiveRecord { const MALE = 1; const FEMALE = 2; public static $genderLabels = array( self::MALE => 'Male', self::FEMALE => 'Female', ); ...
And in the view script ...
<?php echo $form->dropDownList($form, 'gender', Person::$genderLabel); ?> ... array('name'=>'gender', 'value'=>Person::$genderLable[$model->gender]),
Or, you may want to write a method GetGenderLabel($gender) which can handle an unexpected value for $gender.
@skworden
Wiki is not a place where you write things that you are not very sure. You can do it in the forum.
Email-Links
This can be simplified:
array( 'name'=>'email_address', 'type'=>'raw', 'value'=>'CHtml::link(CHtml::encode($data->email_address),"mailto:".$data->email_address)', ),
By:
array( 'name'=>'email_address', 'type'=>'email', ),
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.