Yii фреймворк: создание кнопок с помощью CButtonColumn

Владимир | | Ajax, JavaScript, PHP, Web разработка, Yii.

yii php CButtonColumn

Тему этого поста подсказал мне читатель по имени 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». Я сделал скриншот (несколько колонок убрал, чтобы уменьшить ширину таблицы).

initial grid

Взгляните на код, который создаёт стандартную таблицу с тремя кнопками.

<?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 😉

Если есть замечания или вопросы, пишите, обсудим 😉

Интересно почитать

Дейтинг — хорошая возможность заработать на своих интернет-проектах.

Спастись от жары не сложно. Достаточно купить сплит-системы.