Создание кнопок с помощью 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».

Взгляните на код, который создаёт стандартную таблицу с тремя кнопками.
<?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 ;)
Теги:
Создание кнопок, CButtonColumn
Добавлено: 22 Апреля 2018 11:15:45 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...