Записки по Yii 1
Эту статью буду пополнять зарубками на память. Часто бывает так что на какие-то мелочи уходит много времени. Не всегда удаётся нужное отыскать в интернете. Это такой мини-сборник мини-рецептов по Yii.
Текстовое поле с маской и текстом по-умолчанию
Если в форме требуется вывести подпись (label) и текстовое поле с маской ввода и предустановленной строкой, то тут поможет стандартный виджет Yii CMaskedTextField, определённый в framework/web/widgets/CMaskedTextField.php. Мне понадобилось в предустановленный текст написать цифры, включая "9". А эта цифра предопределена как маска на все числа. Поэтому нужно переодределить числа и "высвободить" для себя девятку. Полный код, готовый для вставки в view-файл выглядит так:
<?php
echo $form->labelEx($model,'isbn');
$this->widget('CMaskedTextField', array(
'model' => $model,
'attribute' => 'isbn',
'mask' => '978-5-4353-01ii-i',
'charMap' => array('i' => '[0-9]')
));
?>
Здесь предопределена маска для ввода ISBN, где начало кода ISBN уже по-умолчанию указано (пользователю остаётся только дописать последние три цифры). По каким правилам составлять свои маски написано тут: http://digitalbush.com/projects/masked-input-plugin
В результате на странице до получения фокуса поле не заполнено и выглядит так:
После получения фокуса, отображается преднастроенный текст:
Если в Yii используется расширение YiiBooster (4.*), то код будет выглядеть так:
<?php echo $form->maskedTextFieldGroup($model, 'isbn', array(
'widgetOptions'=>array(
'mask' => '978-5-4353-01ii-i',
'charMap' => array('i' => '[0-9]'),
'htmlOptions'=>array('class'=>'span5','maxlength'=>17)
)));
?>
maskedTextFieldGroup определён в /protected/extensions/bootstrap/widgets/TbActiveForm.phpА результат выглядит более привлекательно за счёт применения стилей библиотеки Bootstrap 3:
и в фокусе:
Добавляем перевод
Для отображения всех элементов интерфейса, а так же данных в Yii на русском языке удобнее всего добавить специальный файл с переводами и определить язык в настройках.В файле настроек (/protected/config/main.php) в return array() добавляем
'sourceLanguage' => 'en',
'language' => 'ru',
После этого создаём файл с переводом /protected/messages/ru/main.php. В файле переводим всё, что нужно в следующем виде:
<?php
return array(
'Create' => 'Добавить',
'Save' => 'Сохранить',
'Reset' => 'Сбросить'
);
После этого можно пользоваться переводом с помощью встроенного в Yii средства Yii::t(). Например для кнопок под формой во view-файле можно написать (в этом примере Yii с расширением YiiBooster 4.*):
<div class="form-actions">
<?php $this->widget('booster.widgets.TbButton', array(
'buttonType'=>'submit',
'context'=>'primary',
'icon'=>'ok white',
'label'=>$model->isNewRecord ? Yii::t("main", "Create") : Yii::t("main", "Save"),
)); ?>
<?php $this->widget('booster.widgets.TbButton', array(
'buttonType'=>'reset',
'icon'=>'remove',
'label'=>Yii::t("main", "Reset"),
)); ?>
</div>
Выпадающий список с данными из другой таблицы
В YiiBooster 4 (по отношению к версии 2 и 3) изменили синтаксис для выпадающего списка. В этой версии YiiBooster в форме добавления книги я реализовал выпадающий список с данными из базы по доступным жанрам книг (первым значением я поставил заглушку):
<?php echo $form->dropDownListGroup($model, 'genre_id', array('widgetOptions'=>array(
'data' => CHtml::listData(Genre::model()->findAll(), 'id', 'name'),
'htmlOptions' => array(
'empty' => Yii::t("main", "Select genre")
)
)));
?>
Этот код во view-файле позволяет подгрузить данные из модели Genre (создаётся массив из id и наименований). Чтобы эта схема заработала в модели Book, в ней определена связь по отношению к модели Genre под названием genre типа BELONGS_TO для поля genre_id из модели Book.
public function relations()
{
return array(
'authorBooks' => array(self::HAS_MANY, 'AuthorBook', 'book_id'),
'genre' => array(self::BELONGS_TO, 'Genre', 'genre_id'),
);
}
В свою очередь в модели Genre определена связь с моделью Book под названием books:
public function relations()
{
return array(
'books' => array(self::HAS_MANY, 'Book', 'genre_id'),
);
}
Все эти связи сформировались автоматически средствами Gii при генерации соответствующих моделей. Предварительно в базе данных были настроены нужные индексы и связи таблиц.Картинки в таблице
Иногда требуется вместо текста в таблице показывать картинки. С установленным дополнением YiiBooster 4 это делается с помощью виджета таблицы TbExtendedGridView с ячейкой виджетом TbImageColumn. Ниже приведён сокращённый пример, где данные с названием картинки подгружаются из таблицы, а сама картинка берётся из директории img на два уровня выше текущего положения. Если названия картинки нет, то выводится заглушка-каринка с заданным размером.
$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'id'=>'book-grid',
'dataProvider'=>$model->search(),
'type'=>'striped bordered condensed',
'template'=>'{summary}{pager}{items}{pager}',
'columns'=>array(
array(
'class'=>'bootstrap.widgets.TbImageColumn',
'imagePathExpression' => function($data, $row) {
if($row->photo)
return "/../../img/" . $row->photo;
else
return '';
},
'emptyText' => 'Фотографии нет',
'usePlaceHoldIt' => TRUE,
'placeHoldItSize' => '130x200'
),
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
'template' => '{view} {update} {delete}',
'buttons' => array(
'view',
'update',
'delete'
),
'htmlOptions'=>array('style'=>'width: 60px'),
)
)
));
С картинкой и без картинки таблица выглядит примерно так:
Если в базе поле с названием картинки обязательное, то путь к картинке можно указать так:
'imagePathExpression'=>'"/../../img/".$data->photo'
Переключатель (checkbox) в таблице
Виджет таблица TbExtendedGridView из набора расширенияYiiBooster 4 может содержать виджет TbButtonColumn, который позволяет настроить активный булевый переключатель. Ниже приведён сокращённый вариант таблицы, где одно из полей в исходной таблице базы данных имеет значения 0 и 1, в результирующей таблице будет показан ярлычёк с крестиком или галочкой соответственно.
$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'id'=>'book-grid',
'dataProvider'=>$model->search(),
'type'=>'striped bordered condensed',
'template'=>'{summary}{pager}{items}{pager}',
'columns'=>array(
array(
'class' => 'bootstrap.widgets.TbToggleColumn',
'toggleAction' => 'book/toggleAccounting',
'name' => 'enable',
'header' => Yii::t("main", "Enable on site"),
'checkedButtonLabel' => Yii::t("main", "Check"),
'uncheckedButtonLabel' => Yii::t("main", "Uncheck")
),
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
'template' => '{view} {update} {delete}',
'buttons' => array(
'view',
'update',
'delete'
),
'htmlOptions'=>array('style'=>'width: 60px'),
)
)
));
Но, чтобы этот виджет заработал, в контроллер нужно добавть обработчик:
public function actions() {
return array(
'toggleBook' => array(
'class'=>'bootstrap.actions.TbToggleAction',
'modelName' => 'Book'
)
);
}
Ajax кнопка
Задача: без перезагрузки страницы скопировать значение одного инпута, обработать в контроллере и записать значение в другой инпут. Во view файле пишем:
$this->widget('booster.widgets.TbButton', array(
'buttonType'=>'ajaxButton',
'context'=>'primary',
'label'=>Yii::t("main", "Make book authors page"),
'url' => CController::createUrl('author/makePage'),
'ajaxOptions' => array(
'type' => 'POST',
'data' => array(
'authorName' => 'js:$("input#Author_name").val()',
'YII_CSRF_TOKEN' => Yii::app()->request->csrfToken),
'success' => 'function(msg){
$("input#Author_link").val(msg);
}'
)
));
В данном случае в контроллере AuthorController.php есть функция вида:
public function actionMakePage() {
$link='111';
echo $link;
}
Комментарии
Отправить комментарий