Пятая подборка советов по фреймворку Yii.
-
Зависимый select от другого select'а.
Задача: необходимо выводить дополнительный select при выборе определённых значений в другом.
На примере: город и станции метро города.
В одном городе существует метро, в другом нет. Соответственно если выбран город, в котором есть станции метро, то отображаем второй select для выбора станций, если нет станций метро - скрываем.
В представлении пишем:
- <div class="row">
- <?php echo $form->labelEx($model,'city_id'); ?>
- <?php echo $form->dropDownList($model,'city_id', City::getCityArray(),
- array(
- 'class' => 'width150', 'ajax' => array(
- 'type'=>'POST',
- 'dataType'=>'json',
- 'url'=>Yii::app()->createAbsoluteUrl('controller/someaction'),
- 'success'=>'function(data) {
- if (data.dropdownMetro) {
- $("#metro-block").show();
- $("#City_metro_id").html(data.dropdownMetro);
- }
- else {
- $("#metro-block").hide();
- }
- }',
- ))); ?>
- <?php echo $form->error($model,'city_id'); ?>
- </div>
-
- <div class="row" id="metro-block" style="display: none;">
- <?php echo $form->labelEx($model,'metro_id'); ?>
- <?php echo $form->dropDownList($model,'metro_id', array(), array('class' => 'width150')); ?>
- <?php echo $form->error($model,'metro_id'); ?>
- </div>
Добавляем метод в контроллер:
- public function actionSomeAction() {
- $cityId = (int) $_POST['City']['city_id'];
-
- if (!$cityId) {
- echo CJSON::encode(array(
- 'no'=>true
- ));
- Yii::app()->end();
- }
-
- $data = self::model()->findAll('city_id=:city_id',
- array(':city_id'=>$cityId));
-
- $data = CHtml::listData($data, 'id', 'name');
-
- $dropdownMetro = '';
-
- foreach($data as $value => $name)
- {
- $dropdownMetro .= CHtml::tag('option', array('value' => $value), CHtml::encode($name), true);
- }
-
- echo CJSON::encode(array(
- 'dropdownMetro'=>$dropdownMetro
- ));
- }
В методе actionSomeAction $cityId присваивается значение из массива $_POST.
Обычно, "Выбрать значение" в выпадающем списке имеет значение 0, соответственно ответ придёт '{"no":true}' и селектор "Метро" будет скрыт ($("#metro-block").hide();)
-
Сценарии в Yii.
Разберём подробно сценарии для понимания их работы.
Сценарий можно задать:
- $model = new firstModel('frontend');
или:
- $model = new firstModel();
- $model->scenario = 'frontend';
а ещё:
- $model = firstModel::model()->findByPk(1);
- $model->scenario = 'frontend';
также:
- $model = firstModel::model()->find('id = :id', array(':id' => 1);
- $model->scenario = 'frontend';
Но все они значат одно - при валидации будет учитываться 'on' => 'frontend'
- public function rules() {
- return array(
- array('email', 'required'),
- array('email', 'email', 'on' => 'frontend'),
- );
- }
- $model = new firstModel('frontend');
- $model->email = 'email@email.com';
- if ($model->validate()) {
- прошло валидацию
- }
- $model = new firstModel('frontend');
- $model->email = 'email@email';
- if ($model->validate()) {
- не прошло валидацию
- }
- $model = new firstModel();
- $model->email = 'email@email';
- if ($model->validate()) {
- прошло валидацию
- }
- $model = new firstModel();
- $model->scenario = 'frontend';
- $model->email = 'email@email';
- if ($model->validate()) {
- не прошло валидацию
- }
-
Сгруппированный раскрывающийся список.
Первый вариант:
- echo CHtml::dropDownList('Cars', 'car_id', array(
- 'Toyota'=>array(
- 1=>'Avensis',
- 2=>'Camry',
- ),
- 'Volvo'=>array(
- 3=>'S60',
- 4=>'XC70',
- ),
- ));
Второй вариант:
- $records = array(
- array('id' => 1, 'name' => 'Yii', 'group' => 'Фреймворк'),
- array('id' => 2, 'name' => 'Drupal', 'group' => 'Фреймворк'),
- array('id' => 3, 'name' => 'Joomla', 'group' => 'Фреймворк'),
- array('id' => 4, 'name' => 'Сodeigniter', 'group' => 'Фреймворк'),
- array('id' => 5, 'name' => 'Mercurial', 'group' => 'Система контроля версий'),
- array('id' => 6, 'name' => 'Git', 'group' => 'Система контроля версий'),
- array('id' => 7, 'name' => 'SVN', 'group' => 'Система контроля версий'),
- );
-
- $dropDownList = CHtml::listData($records, 'id', 'name', 'group');
- echo CHtml::dropDownList('dropDownList', '', $dropDownList);
Обсудить статью на форуме