Создание и сопровождение сайтов

Блог. Yii. Подсказки по yii. Глава пятая.

Поиск

Пятая подборка советов по фреймворку Yii.

  1. Зависимый select от другого select'а.

    Задача: необходимо выводить дополнительный select при выборе определённых значений в другом.

    На примере: город и станции метро города.

    В одном городе существует метро, в другом нет. Соответственно если выбран город, в котором есть станции метро, то отображаем второй select для выбора станций, если нет станций метро - скрываем.

    В представлении пишем:

     

    1. <div class="row">  
    2.     <?php echo $form->labelEx($model,'city_id'); ?>  
    3.     <?php echo $form->dropDownList($model,'city_id', City::getCityArray(),   
    4.             array(  
    5.                 'class' => 'width150''ajax' => array(  
    6.                 'type'=>'POST',   
    7.                 'dataType'=>'json',  
    8.                 'url'=>Yii::app()->createAbsoluteUrl('controller/someaction'),  
    9.                 'success'=>'function(data) { 
    10.                     if (data.dropdownMetro) { 
    11.                         $("#metro-block").show(); 
    12.                         $("#City_metro_id").html(data.dropdownMetro); 
    13.                     } 
    14.                     else { 
    15.                         $("#metro-block").hide(); 
    16.                     } 
    17.                 }',  
    18.             ))); ?>  
    19.     <?php echo $form->error($model,'city_id'); ?>  
    20. </div>  
    21.   
    22. <div class="row" id="metro-block" style="display: none;">  
    23.     <?php echo $form->labelEx($model,'metro_id'); ?>  
    24.     <?php echo $form->dropDownList($model,'metro_id'array(), array('class' => 'width150')); ?>  
    25.     <?php echo $form->error($model,'metro_id'); ?>  
    26. </div>  

    Добавляем метод в контроллер:

     

    1. public function actionSomeAction() {  
    2.     $cityId = (int) $_POST['City']['city_id'];  
    3.       
    4.     if (!$cityId) {  
    5.         echo CJSON::encode(array(  
    6.             'no'=>true  
    7.         ));  
    8.         Yii::app()->end();  
    9.     }  
    10.       
    11.     $data = self::model()->findAll('city_id=:city_id',   
    12.                 array(':city_id'=>$cityId));  
    13.   
    14.     $data = CHtml::listData($data'id''name');  
    15.       
    16.     $dropdownMetro = '';  
    17.       
    18.     foreach($data as $value => $name)  
    19.     {  
    20.         $dropdownMetro .= CHtml::tag('option'array('value' => $value), CHtml::encode($name), true);  
    21.     }  
    22.       
    23.     echo CJSON::encode(array(  
    24.         'dropdownMetro'=>$dropdownMetro  
    25.     ));  
    26. }  

    В методе actionSomeAction $cityId присваивается значение из массива $_POST.

    Обычно, "Выбрать значение" в выпадающем списке имеет значение 0, соответственно ответ придёт '{"no":true}' и селектор "Метро" будет скрыт ($("#metro-block").hide();)

  2. Сценарии в Yii.

    Разберём подробно сценарии для понимания их работы.

    Сценарий можно задать:

     

    1. $model = new firstModel('frontend');  

    или:

     

    1. $model = new firstModel();  
    2. $model->scenario = 'frontend';  

    а ещё:

     

    1. $model = firstModel::model()->findByPk(1);  
    2. $model->scenario = 'frontend';  

    также:

     

    1. $model = firstModel::model()->find('id = :id'array(':id' => 1);  
    2. $model->scenario = 'frontend';  

    Но все они значат одно - при валидации будет учитываться 'on' => 'frontend'

     

    1. public function rules() {  
    2.   return array(  
    3.     array('email''required'),  
    4.     array('email''email''on' => 'frontend'),  
    5.   );  
    6. }  

     

    1. $model = new firstModel('frontend');  
    2. $model->email = 'email@email.com';  
    3. if ($model->validate()) {  
    4.     прошло валидацию  
    5. }  

     

    1. $model = new firstModel('frontend');  
    2. $model->email = 'email@email';  
    3. if ($model->validate()) {  
    4.     не прошло валидацию  
    5. }  

     

    1. $model = new firstModel();  
    2. $model->email = 'email@email';  
    3. if ($model->validate()) {  
    4.     прошло валидацию  
    5. }  

     

    1. $model = new firstModel();  
    2. $model->scenario = 'frontend';  
    3. $model->email = 'email@email';  
    4. if ($model->validate()) {  
    5.     не прошло валидацию  
    6. }  
  3. Сгруппированный раскрывающийся список.

    Первый вариант:

     

    1. echo CHtml::dropDownList('Cars''car_id'array(  
    2.     'Toyota'=>array(  
    3.         1=>'Avensis',  
    4.         2=>'Camry',  
    5.     ),  
    6.     'Volvo'=>array(  
    7.         3=>'S60',  
    8.         4=>'XC70',  
    9.     ),  
    10. ));  

    Второй вариант:

     

    1. $records = array(  
    2.     array('id' => 1, 'name' => 'Yii''group' => 'Фреймворк'),  
    3.     array('id' => 2, 'name' => 'Drupal''group' => 'Фреймворк'),  
    4.     array('id' => 3, 'name' => 'Joomla''group' => 'Фреймворк'),  
    5.     array('id' => 4, 'name' => 'Сodeigniter''group' => 'Фреймворк'),  
    6.     array('id' => 5, 'name' => 'Mercurial''group' => 'Система контроля версий'),  
    7.     array('id' => 6, 'name' => 'Git''group' => 'Система контроля версий'),  
    8.     array('id' => 7, 'name' => 'SVN''group' => 'Система контроля версий'),  
    9. );  
    10.   
    11. $dropDownList = CHtml::listData($records'id''name''group');   
    12. echo CHtml::dropDownList('dropDownList'''$dropDownList);  

Обсудить статью на форуме