Site building and maintenance

Blog. Yii. Tips for Yii. Сhapter 6

Search

Tips for Yii. Сhapter 6.

  1. datePicker в CGridView.

    What have we got?

    A table in the database with one of the fields 'date_created' with date/datetime type and displaying of the data in CGridView.

    What is our task?

    It is to create a filter in CGridView for this field with the help of datePicker.

    What is a solution?

    It is Yii CJuiDatePicker that will help us. (for example our Open Real Estate CMS 1.3.3)

    Add it to 'date_created' in the viewing:

    1. 'filter'=>$this->widget('zii.widgets.jui.CJuiDatePicker'array(    
    2.     'model'=>$model,     
    3.     'attribute'=>'date_created',    
    4.     'language'=>'en',  /* Yii::app()->language */  
    5.     'options'=>array(    
    6.             'showAnim'=>'fold',    
    7.             'dateFormat'=>'yy-mm-dd',    
    8.             'changeMonth' => 'true',    
    9.             'changeYear'=>'true',    
    10.             'showButtonPanel' => 'true',    
    11.     ),    
    12. ),true),   

    And to make datePicker available after an ajax update of the table, write its initialization in afterAjaxUpdate (we add datePicker to id of the element; in our case, it is 'News_date_created').

    An ajax update of the table can happen by deleting of the record, by searching in the table.

    1. 'afterAjaxUpdate' => 'function(){jQuery("#News_date_created").datepicker(jQuery.extend(jQuery.datepicker.regional["en"],{"showAnim":"fold","dateFormat":"yy-mm-dd","changeMonth":"true","showButtonPanel":"true","changeYear":"true"})); $("a[rel=\'tooltip\']").tooltip(); $("div.tooltip-arrow").remove(); $("div.tooltip-inner").remove();}',  

    Having made all additions to the code, we will get the following:

    1. <?php $this->widget('CustomGridView'array(  
    2.     'id'=>'news-grid',  
    3.     'dataProvider'=>$model->search(),  
    4.     'filter'=>$model,  
    5.     'afterAjaxUpdate' => 'function(){jQuery("#News_date_created").datepicker(jQuery.extend(jQuery.datepicker.regional["en"],{"showAnim":"fold","dateFormat":"yy-mm-dd","changeMonth":"true","showButtonPanel":"true","changeYear":"true"})); $("a[rel=\'tooltip\']").tooltip(); $("div.tooltip-arrow").remove(); $("div.tooltip-inner").remove();}',  
    6.     'columns'=>array(  
    7.         array(  
    8.             'class'=>'CCheckBoxColumn',  
    9.             'id'=>'itemsSelected',  
    10.             'selectableRows' => '2',  
    11.             'htmlOptions' => array(  
    12.                 'class'=>'center',  
    13.             ),  
    14.         ),  
    15.         array(  
    16.             'header' => tc('Title'),  
    17.             'name'=>'title_'.Yii::app()->language,  
    18.             'type'=>'raw',  
    19.             'value'=>'CHtml::link(CHtml::encode($data->getStrByLang("title")), $data->url)'  
    20.         ),  
    21.         array(  
    22.             'name'=>'dateCreated',  
    23.             'type'=>'raw',  
    24.             'filter'=>$this->widget('zii.widgets.jui.CJuiDatePicker'array(    
    25.                 'model'=>$model,     
    26.                 'attribute'=>'date_created',    
    27.                 'language'=>'en',  /* Yii::app()->language */  
    28.                 'options'=>array(    
    29.                         'showAnim'=>'fold',    
    30.                         'dateFormat'=>'yy-mm-dd',    
    31.                         'changeMonth' => 'true',    
    32.                         'changeYear'=>'true',    
    33.                         'showButtonPanel' => 'true',    
    34.                 ),    
    35.             ),true),    
    36.             'htmlOptions' => array('style' => 'width:130px;'),  
    37.         ),  
    38.         array(  
    39.             //'class'=>'CButtonColumn',  
    40.             'class'=>'bootstrap.widgets.BootButtonColumn',  
    41.             'deleteConfirmation' => tt('Are you sure you want to delete this news?''news'),  
    42.             'viewButtonUrl' => '$data->url',  
    43.         ),  
    44.     ),  
    45. ));   

    To make the filter work for this field, we shall open the model and add to the ‘search’ method the following:

    1. if ($this->date_created)    
    2.     $criteria->compare('date_created'$this->date_created, true);  

    So we will get:

    1. public function search() {    
    2.     $criteria = new CDbCriteria;    
    3.     ...    
    4.     if ($this->date_created)    
    5.         $criteria->compare('date_created'$this->date_created, true);    
    6.     ...    
    7. }  

    and:

    1. public function rules() {  
    2.     return array(  
    3.         ...  
    4.         array($this->getI18nFieldSafe().', date_created''safe'),  
    5.         ...  
    6.     );  
    7. }  

    Here is the screenshot of what we have, as a result.We click the "Creation date" field:

    yii-tips-6-01

     

  2. Actions before validation and after it.

    Sometimes it is necessary to do actions before validation.

    For example, to set a scenario name for validation depending on the value of a variable.

    1. public function onBeforeValidate($event) {    
    2.    $scenarioArray = array(    
    3.                    1 => 'scanario1',    
    4.                    2 => 'scanario2',    
    5.                    3 => 'scanario3',    
    6.                    4 => 'scanario4',    
    7.                    5 => 'scanario5',    
    8.    );    
    9.    $this->scenario = $scenarioArray[$this->fieldFromDB1];    
    10.    
    11.    if (!$this->field2 || !$this->field3)    
    12.        $this->addError('field2''Fill in field2 and field3');    
    13.    else     
    14.        $this->fieldFromDB2 = $this->field2.$this->field3;    
    15. }    

    , here field2 and field3 are, the fields which the database does not have, but they are announced in the model.

    And after validation we can code:

    1. public function onAfterValidate($event) {    
    2.    // some code here  
    3. }   

    The model has also beforeValidate().

    But we have examined onBeforeValidate() that considers an event as an argument.

     

  3. How to add a progress indicator for ajax requests.

    While performing an ajax request, it is useful to show to the user "that something is happening" and his/her click on the link/button has not been ineffective.

    We add div onto the page:

    1. <div id="loading" style="display:none;">Loading...</div>  

    Styles:

    1. #loading{     
    2.     positionfixed;     
    3.     top40px;     
    4.     leftleft: 0;     
    5.     z-index: 5000;     
    6.     background-color#3C69AC;     
    7.     font-size: 100%;    
    8.     color#FFFFFF;     
    9.     padding5px;    
    10. }   

    Showing and hiding of the div:

    1. Yii::app()->clientScript->registerScript('loading' 
    2.     $("#loading").bind("ajaxSend", function(){  
    3.         $(this).show();  
    4.     }).bind("ajaxComplete", function(){  
    5.         $(this).hide();  
    6.     });  
    7. ', CClientScript::POS_READY);    

     

  4. Paths to folders..

    I guess that many developers have to work with downloaded photos and to specify an absolute path to a folder that will contain all the downloaded files.

    Dirname(__FILE__);/dirname(__FILE__) . '/../'; etc. can help us.

    But Yii has a getPathOfAlias method, using of it is a right and beautiful solution.

    For example, for loading in the upload folder:

    yii-tips-6-02

    we use:

    1. Yii::getPathOfAlias('webroot.uploads');    

    For loading in the uploads/qrcodes folder:

    yii-tips-6-03

    we use:

    1. Yii::getPathOfAlias('webroot.uploads.qrcodes');  

    For loading in the protected/modules/cropimage folder we use:

    1. Yii::getPathOfAlias('application.modules.cropimage');   

    It is not possible to use

    1. Yii::getPathOfAlias('webroot.protected.modules.cropimage');   

    , because a ‘protected’ folder is closed for access via htaccess.

     

Discuss the article in the forum