Тему этого поста подсказал мне читатель по имени Alex, за что ему большое спасибо.
Речь о компонентах zii, которые, начиная с версии 1.1, входят в состав фреймворка, и активно используются утилитой yiic при генерации кода.
К сожалению, документация по этим компонентам есть только в виде API (комментарии к исходникам) и её явно недостаточно.
Ситуация следующая. Если вас полностью устраивает код, который генерирует yiic — никаких проблем. Но вот что-то изменить или добавить какие-нибудь возможности уже сложнее.
Рассмотрим такую ситуацию. Для одной из таблиц в БД вы создали стандартный набор CRUD операций. И вам нужно в таблицу с перечнем записей добавить дополнительную кнопку. На первый взгляд, задача довольно простая, т.к. таблица генерируется с помощью виджета 'zii.widgets.grid.CGridView
' и среди компонентов zii есть CButtonColumn, который специально предназначен для создания колонок с кнопками. Т.е. задача заключается в настройке этого компонента.
Чтобы было понятнее, рассмотрим небольшой пример.
Создаём новое приложение
yiic webapp .
По-умолчанию в нём есть sqlite база с одной таблицей (данными пользователей)
Создаём модель
yiic shell
model User tbl_user
и CRUD интерфейс
crud User
В результате будет сгенерировано несколько скриптов, которые позволят управлять записями в таблице.
При этом страница управления записями (index.php?r=user/admin
) содержит таблицу с перечнем записей и столбцов с кнопками «View», «Update», «Delete». Я сделал скриншот (несколько колонок убрал, чтобы уменьшить ширину таблицы).
Взгляните на код, который создаёт стандартную таблицу с тремя кнопками.
<?php $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider'=>$dataProvider, 'columns'=>array( 'id', 'username', 'password', 'email', array( 'class'=>'CButtonColumn', ), ), )); ?>
В массиве columns
перечисляем названия столбцов таблицы. Если имя столбца совпадает с полем таблице, то оно будет заполнено соответствующими данными. В последнем элементе указан массив с одним элементом 'class'=>'CButtonColumn'
. Этого достаточно для создания трёх стандартных кнопок.
Попробуем добавить ещё один столбец с кнопкой «AJAX запрос». Для этого добавим ещё один элемент в массив 'columns'
array( 'class'=>'CButtonColumn', 'buttons'=>array( 'preview'=>array( 'label'=>'AJAX запрос', 'url'=>'…', 'click'=>'…', ), ), 'template'=>'{preview}', ),
Принцип следующий. В элементе 'buttons'
нужно указать массив с новыми кнопками. При этом ключ каждого элемента этого массива является названием кнопки. Его мы должны использовать в элементе 'template'
для того, чтобы показать кнопку в таблице. Название необходимо заключит в фигурные скобки. При этом можно добавить в одну ячейку сразу несколько кнопок, например, так:
'{view} {update} {delete}'
.
Для каждой кнопки необходимо указать массив с параметрами.
'label'
– содержит текст, который будет отображаться на кнопке.
'url'
– PHP выражение, которое сформирует ссылку для данной кнопки.
'click'
– JS функция, которая будет назначена в качестве обработчика клика по кнопке.
Кроме того, можно указать картинку и массив с html атрибутами с помощью параметров 'imageUrl'
и 'options'
. Но сейчас речь не о них. У меня больше всего вопросов вызвали 'url'
и 'click'
.
Расписывать свои ковыряния в исходниках я не буду. Лучше сразу покажу решение.
В параметре 'url'
нужно записать PHP выражение, которое сформирует URL, в виде строки, т.е. в кавычках. Например,
'url'=>'Yii::app()->createUrl("user/getuser")'
При этом будут доступны две переменные: $row
и $data
. Первая содержит номер строки, вторая — объект с данными текущей записи. Т.е. добавить в запрос GET параметр с email’ом пользователя можно так:
'url'=>'Yii::app()->createUrl("user/getuser", array("email"=>$data->email))'
Для того, чтобы проверить отправку AJAX запросов я добавил в контроллер метод actionGetuser. Он ищет пользователя по его email'у.
public function actionGetuser() { if (isset($_GET['email'])) { $user = User::model()->find('email=:email', array(':email'=>$_GET['email'])); if (null !== $user) { echo $user->username; } else { echo 'unknown'; } } else { echo 'unknown'; } }
Напишем функцию, которая будет выполнять отправку запроса. Я добавил её прямо в представление.
<?php $js_preview =<<< EOD function() { var url = $(this).attr('href'); $.get(url, function(response) { alert(response); }); return false; } EOD; ?> <?php $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider'=>$dataProvider, 'columns'=>array( 'id', 'username', 'password', 'email', array( 'class'=>'CButtonColumn', ), array( 'class'=>'CButtonColumn', 'buttons'=>array( 'preview'=>array( 'label'=>'AJAX запрос', 'url'=>'Yii::app()->createUrl("user/getuser", array("email"=>$data->email))', 'click'=>$js_preview, ), ), 'template'=>'{preview}', ), ), )); ?>
Как видите, текст JS функции присвоен переменной $js_preview
. Эту переменную мы и указываем в параметре 'click'
.
Принцип работы следующий.
1) Получаем URL данной кнопки (с помощью $(this).attr('href')
). Он уже содержит email в качестве GET параметра.
2) Отправляем AJAX запрос (с помощью $.get
).
3) Показываем результат (alert(response)
).
Как видите, кода нужно написать минимум, но, повторюсь, очень хотелось бы почитать подробное руководство от разработчиков о компонентах zii 😉
Если есть замечания или вопросы, пишите, обсудим 😉
Интересно почитать
Дейтинг — хорошая возможность заработать на своих интернет-проектах.
Спастись от жары не сложно. Достаточно купить сплит-системы.