Использование класса CButtonColumn для изменения кнопок в виджете CGridView / Yii framework


Оригинал: Using CButtonColumn to customize buttons in CGridView

Вступление

CGridView является одним из наиболее гибких виджетов в Yii и примером такой гибкости является класс CButtonColumn. Он используется для создания кнопок для управления моделью в каждой строке таблицы. В этой инструкции мы объясним способы, которыми пользователь может настроить CButtonColumn для своих потребностей.

Базовая кастомизация

По умолчанию CButtonColumn содержит три кнопки в следующем порядке: {view}, {update} и {delete}. Их смысл и поведение должны быть очевидными.

Самый простой способ настроить внешний вид и поведение, этих трёх элементов заключается в использовании серии свойства класса CButtonColumn, таких как:
  • updateButtonImageUrl — путь к изображению кнопки для обновления.
  • updateButtonLabel — метка для обновления кнопки, спецсимволы HTML экранируются.
  • updateButtonOptions — HTML атрибут для этой кнопки.
  • updateButtonUrl — PHP выражение, которое вычисляется для кнопки (eval), результат которого используется в качестве URL.
Похожие свойства, вы найдете и для других элементов.

Несколько замечаний:
  1. Только для кнопки удаления, есть параметр deleteConfirmation (строка), которая может быть использованы для настройки сообщения, которое отображается как подтверждение операции удаления.
  2. В PHP выражение, используемое для свойства xxxButtonUrl, вы можете использовать несколько переменных:
    • $row — содержит номер строки (начиная с нуля);
    • $data — содержит объект модели (в случае CActiveDataProvider) или массив данных (в случае CSqlDataProvider или CArrayDataProvider);

    • $this — содержит объект столбца (CButtonColumn).
  3. Если вы передадите в свойство xxxButtonImageUrl пустую строку или false, то вместо изображения будет успользоваться текст из xxxButtonLabel.

Информация: Удалить подтверждение (и другие текстовые элементы CButtonColumn или CGridView) вы может создания файла zii.php в protected/messages/languageID/ (или еще лучше — копированием готового перевода, например, от yii/messages/de/). Не забудьте установить свойство
'coreMessages' => array('BasePath' => 'protected/messages')
в components вашего конфигурационного файла config.php, чтобы заставить Yii искать сообщения в директории приложения, а не брать из фреймворка.

Более гибкая настройка

Для более элегантного отображение настроек приведенных выше или если есть необходимость в более сложной настройки или внедрения новых кнопок, есть лучший, более гибкий способ — с помощью шаблонов.

Вы можете использовать свойство template для изменения порядка кнопок или удалить некоторые из них:
array
(
    'class'=>'CButtonColumn',
    'template'=>'{delete}{update}',
)
В столбце кнопок CGridView на приведенном примере не будет кнопки view, а delete и update поменяются местами (сначала будет выведена кнопка delete, затем update).

Вы можете использовать то же свойства для того, что бы ввести новые кнопки:
array
(
    'class'=>'CButtonColumn',
    'template'=>'{up}{down}{delete}',
)

Для новых кнопок Вы должны указать вид и поведение. Тут же можно переопределить встроеные кнопки. Для этого используйте свойство buttons класса CButtonColumn. Это свойство представляет собой массив, где ключи это ID кнопок (имена которых должны соответствовать тем, что Вы поставили в свойстве template), а значение является массивом данных, содержащих его специфические свойства.

Пример:
'buttonID' => array
(
    'label'=>'...',     // Текст (или title) кнопки.
    'url'=>'...',       // PHP выражение для генерации URL кнопки.
    'imageUrl'=>'...',  // URL на изображение кнопки.
    'options'=>array(), // HTML атрибуты для тега кнопки.
    'click'=>'...',     // JS функция вызываемая при клике на кнопку.
    'visible'=>'...',   // PHP выражение для определения видимости кнопки.
)


Помните: свойство label отображается только, если у вас есть текстовые ссылки! Если вы используете изображение вместо текстовых ссылок, label будет использован как атрибут alt изображения. Если Вы хотите изменить текст всплывающей подсказки, которая отображается, когда пользователь наводит на изображение кнопки, вы должны в параметр options, добавить параметр title, вот так:

'buttonID' => array
(
    'label'=>'Этот текст будет в атрибуте alt изображения...',
    'options'=>array(
		'title'=>'Этот текст будет во всплывающей подсказке при наведении на кнопку...'
	),
)


Есть аналогичные замечания по вышеуказанным свойствам, подобные описанным в первой части этой статьи:
  1. В PHP выражении для вычисления url или видимости, Вы можете использовать 2 переменные:
    • $row — содержит номер строки (начиная с нуля);
    • $data — содержит объект модели (в случае CActiveDataProvider) или массив данных (в случае CSqlDataProvider или CArrayDataProvider).


Наконец вот пример внедрения новых кнопок CButtonColumn:
array
(
    'class'=>'CButtonColumn',
    'template'=>'{email}{down}{delete}',
    'buttons'=>array
    (
        'email' => array
        (
            'label'=>'Отправить уведомление на email',
            'imageUrl'=>Yii::app()->request->baseUrl.'/images/email.png',
            'url'=>'Yii::app()->createUrl("users/email", array("id"=>$data->id))',
        ),
        'down' => array
        (
            'label'=>'[-]',
            'url'=>'"#"',
            'visible'=>'$data->score > 0',
            'click'=>'function(){alert("Going down!");}',
        ),
    ),
),


Помните, что в параметре click используется callback функция. Любое js выражение, должно быть внутри анонимной функции.

'click' => 'function(){ alert("Start"); }' // правильно
'click' => 'alert("Start");' // НЕ правильно

Подтверждение удаления

Вы могли заметить, что стандартный набор кнопок, генерируемые для операций CRUD на Gii включает в себя (в представлениях view и update) подтверждение удаления записи. Текст этого подтверждения можно легко изменить/расширить, чтобы включить некоторые данные записи (модели), такие как напрмер номер записи.

Это не так просто в CGridView (CButtonColumn), а свойство deleteConfirmation не парсится. Однако, есть хитрый способ для достижения этой цели (благодаря mdomba) с использованием jQuery. Пример:
array
(
        'class'=>'CButtonColumn',
        'deleteConfirmation'=>"js:'Запись с ID '+$(this).parent().parent().children(':first-child').text()+' будет удалена! Продолжить?'",
),


Мы также можем использовать функцию JQuery ntn-child для получения содержимого других столбцов:
array
(
        'class'=>'CButtonColumn',
        'deleteConfirmation'=>"js:'Вы точно хотите удалить запись с ID '+$(this).parent().parent().children(':nth-child(2)').text()+'?'",
),


На первый взгляд jQuery функция выглядит очень сложной и причудливой. Если вы хотите знать, почему это должно быть в том виде, пожалуйста, прочитайте это сообщение на форуме.

Заключение

Я надеюсь, что эта инструкции будет способствовать лучшему пониманию того, насколько гибок механизм кнопки в CGridView. Это особенно важно, так как на форума много вопросов задавали по этому поводу. Пожалуйста, не стесняйтесь делать какие-либо обновления или исправления в этой статье, если вы обнаружите, что чего-то не хватает или если есть ошибки в нем.

Удачного дня и приятного Yii-кодинга! :)