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. Как добавить условия, настроить и сбросить фильтры.
Спасибо! Ващпе Помогло!
Спасибо, пожалуй одно из лучших описаний этого сложного виджета.
Большое спасибо, достался легаси код и там как раз этот виджет. Очень помогло