Тему этого поста подсказал мне читатель по имени 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 😉
Если есть замечания или вопросы, пишите, обсудим 😉
Интересно почитать
Дейтинг — хорошая возможность заработать на своих интернет-проектах.
Спастись от жары не сложно. Достаточно купить сплит-системы.


