Site building and maintenance

Blog. Yii. Tips for Yii. Chapter 10

Search

Tips for Yii. Chapter 10.

  1. Let’s output CStarRating in GridView.

    Instead of introduction: The site has a comments system with rating (giving grades with the help of the CStarRating widget). Our task is to display the rating like ‘stars’ in the GridView.

    yii-tips-10-01

    So we have to copy the key of the ‘value’ array into the view file:

    1. $this->grid->controller->widget("CStarRating"array("name" => $data->id, "id" => $data->id, "value" => $data->rating, "readOnly" => true,),true)   

    The full view of the result will be like the following:

    1. array(    
    2.     'name' => 'rating',    
    3.     'type' => 'raw',    
    4.     'value'=>'$this->grid->controller->widget("CStarRating", array("name" => $data->id, "id" => $data->id, "value" => $data->rating, "readOnly" => true,),true)',    
    5.     'headerHtmlOptions' => array('style' => 'width:85px;'),    
    6.     'htmlOptions' => array('class' => 'rating-block'),    
    7.     'filter' => false,    
    8.     'sortable' => false,    
    9. ),   

    And we have to add the following code for view to work correctly (the stars not to be displayed like radio buttons' list) after searching/sorting/filtering;

    1. 'afterAjaxUpdate'=>"function() {  
    2.     jQuery('.rating-block input').rating({'readOnly':true});  
    3. }",   

    So as a result we will get the following code:

    1. $this->widget('bootstrap.widgets.TbGridView'array(    
    2.     'id'=>'users-comments-grid',    
    3.     'dataProvider'=>$model->search(),    
    4.     'filter'=>$model,    
    5.     'afterAjaxUpdate'=>"function() {  
    6.         jQuery('.rating-block input').rating({'readOnly':true});  
    7.     }",    
    8.     'columns'=>array(    
    9.         array(    
    10.             'name' => 'message',    
    11.             'sortable' => false,    
    12.         ),    
    13.         array(    
    14.             'name' => 'rating',    
    15.             'type' => 'raw',    
    16.             'value'=>'$this->grid->controller->widget("CStarRating", array("name" => $data->id, "id" => $data->id, "value" => $data->rating, "readOnly" => true,),true)',    
    17.             'headerHtmlOptions' => array('style' => 'width:85px;'),    
    18.             'htmlOptions' => array('class' => 'rating-block'),    
    19.             'filter' => false,    
    20.             'sortable' => false,    
    21.         ),    
    22.     ),    
    23. ));   

     

  2. Let's extend CFormatter.

    In the same GridView or DetailView we more than often set the field type, for instance: 'type' => 'raw', 'type' => 'text' etc.

    For GridView it may have the following view:

    1. array(    
    2.     'name' => 'text',    
    3.     'type' => 'raw',    
    4. )   

    For DetailView it may look like this:

    1. array(    
    2.     'label' => 'Email',    
    3.     'value' => ' email@email.com',    
    4.     'type' => 'email',    
    5.     'template' => "<tr class=\"{class}\"><th>{label}</th><td>{value}</td></tr>\n"    
    6. ),   

    But we often use only such types as 'raw', 'email', 'image' and 'url'.

    You can read more about CFormatter and all its types on the Documentation page - http://www.yiiframework.com/doc/api/1.1/CFormatter

    Let's extend this class in such a way that our filter will cut the text and will output 5 words with three dots when outputting long sentences.

    In the protected/components folder let’s create a new CCFormatter.php file with the following content:

    1. <?php    
    2. class CCFormatter extends CFormatter {    
    3.     public $numOfWords = 5;    
    4.     
    5.     public function formatTtext($value) {    
    6.         $value = CHtml::encode($value);    
    7.     
    8.         $lenBefore = strlen($value);    
    9.     
    10.         if($this->numOfWords){    
    11.             if(preg_match("/\s*(\S+\s*){0,$this->numOfWords}/"$value$match)){    
    12.                 $value = trim($match[0]);    
    13.             }    
    14.             if(strlen($value) != $lenBefore){    
    15.                 $value .= ' ...';    
    16.             }    
    17.         }    
    18.     
    19.         return $value;    
    20.     }    
    21. }   

    Add some lines in the 'components' section in the config/main.php file:

    1. 'format' => array(    
    2.     'class' => 'application.components.CCFormatter'    
    3. ),   

    Check its work when being displayed in DetailView:

    1. array(    
    2.     'label' => 'Text',    
    3.     'value' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.',    
    4.     'type' => 'ttext',    
    5.     'template' => "<tr class=\"{class}\"><th>{label}</th><td>{value}</td></tr>\n"    
    6. ),  

    And in the output we will see this:

    yii-tips-10-02

     

Discuss the article in the forum