CGridView — один из виджетов Yii-framework. Он позволяет выводить данные объектов модели в виде удобной таблицы, с кнопками управления записями.
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'country-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'name',
'region',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
Это незаменимый виджет для любой админки. Если лень писать руками, его можно сгенерировать с помощью gii. Но то, что генерируется автоматически не всегда совпадает с потребностями разработчика. В моем примере CGridView используется для вывода и управления списком стран. Давайте рассмотрим возможности CGridView на этом примере.
Как вы наверное уже догадались, за кнопки управления отвечает кусок кода
array( 'class'=>'CButtonColumn', ),
Что будет, если разместим его не в конце списка колонок, а в начале? Правильно: кнопки управления будут до колонок с данными 🙂
По умолчанию кнопок бывает 3 (редактирование, просмотр и удаление). Ссылаются они на контроллер, совпадающий с именем модели.
array(
'class'=>'CButtonColumn',
'template'=>'{view}<div class="button">{update}</div>{delete}',
),
Из примера видно, что сами кнопки обозначаются как {view}, {update} и {delete}. Их можно обернуть в любой html-код. Таким же образом можно избавиться от «лишних» кнопок, просто не перечисляя их в данном блоке.
array(
'class'=>'CButtonColumn',
'template'=>'{delete}',
),
array(
'class'=>'CButtonColumn',
'template'=>'{update}{delete}',
'updateButtonUrl'=>'Yii::app()->getUrlManager()->createUrl("/admin/editCountry/", array("id" => $data->id))',
'deleteButtonUrl'=>'Yii::app()->getUrlManager()->createUrl("/admin/delCountry/", array("id" => $data->id))'
)
Обратите внимание: метод, возвращающий ссылку записан в одинарные кавычки! Это просто текстовая строка. Он не должен выполняться на этапе компиляции данного php-скрипта. Текущие данные строки таблицы доступны через объект $data.
'class'=>'CButtonColumn',
'template'=>'{moderation} {delete}',
'buttons'=>array
(
'moderation' => array
(
'label'=>'Одобрить',
'url'=>'Yii::app()->getUrlManager()->createUrl("admin/moderation/", array("id" => $data->id))',
'imageUrl' => '/img/moderation.png',
),
),
'deleteButtonUrl'=>'Yii::app()->getUrlManager()->createUrl("/admin/delCountry/", array("id" => $data->id))'
)
Если не задан imageUrl, ссылка будет просто текстовая.
'buttons'=>array
(
'moderation' => array
(
'label'=>'Одобрить',
'visible' => '$data->moderation == 0'
'url'=>'Yii::app()->getUrlManager()->createUrl("admin/moderation/", array("id" => $data->id))',
'imageUrl' => '/img/moderation.png',
),
),
Теперь кнопка отображается только на тех строках, где выполняется условие visible. В visible можно прописать не только выражение, но и вызов функции, возвращающий true или false. Только учтите, что этот вызов должен быть передан в виде строки.
Помимо этого, кнопке можно добавить событие по клику, прописав вызов JS-функции в виде свойства ‘click’. Событие так-же должно указываться в виде строки.
'columns'=>array(
'name',
array(
'name' => 'flag',
'value' => '"/images/".$data->flag',
'type' => 'image',
'filter' => false
),
region,
Параметр name влияет на название колонки. Это может быть как просто строка, так и атрибут модели. Во втором случаи названием колонки будет то, что прописано для атрибута в методе attributeLabels модели Country.
filter — отвечает за фильтрацию данных. О нем поговорим в другой статье.
Value — это значение колонки. Данные строки все так же доступны через объект $data. Тут может быть как просто строка, так и вызов метода. Единственное о чем нужно помнить — вызов должен быть оформлен в виде строки, которая будет скомпилирована позже.
type — тип строки. По умолчанию все строки считаются текстовыми. Типы могу быть:
array( 'name' => 'region', 'filter' => Region::getAll(), 'value' => 'Region::getNameByID($data->region)', ),
Обратите внимание, в фильтре метод вызывается сразу, а в value записан в виде строки и будет вызван только в процессе построения таблицы методами класса CGridView. В моем случаи метод getNameByID класса Region возвращает название региона по первичному ключу.
Если вы уверены, что объект, переданный в dataProvider будет иметь связанные таблицы (как это сделать смотрите во второй части, посвященной CGridView), то можно использовать такую запись
array( 'name' => 'region', 'filter' => Region::getAll(), 'value' => '$data->region->title', ),
В моем примере «region» — это имя связи модели Country, которая используется при построении CActiveDataProvider с помощью with().
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'country-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'template' => '<div>{pager}</div>{summary}{items}<div>{pager}</div>',
'columns'=>array(
'id',
'name',
'region',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
В шаблоне можно использовать любой html-код.
Для этого нужно настроить аттрибут pager
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'country-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'pager'=>array(
'header' => '',
'firstPageLabel' => '<<',
'prevPageLabel' => '<img src="images/pagination/left.png">',
'nextPageLabel' => '<img src="images/pagination/right.png">',
'lastPageLabel' => '>>',
),
'columns'=>array(
'id',
'name',
'region',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
Вот такая подробная инструкция у меня получилась. Надеюсь кому-нибудь да пригодиться. Если у вас возникли вопросы — пишите в комментариях, помогу чем смогу.
В следующей статье поговорим об источниках дынных для CGridView. Как добавить условия, настроить и сбросить фильтры.
Спасибо! Ващпе Помогло!
Спасибо, пожалуй одно из лучших описаний этого сложного виджета.
Большое спасибо, достался легаси код и там как раз этот виджет. Очень помогло