CListView — это стандартный виджет для отображения записей. Поддерживает сортировку по определенным атрибутам и постраничную навигацию. Виджет расположен в /framework/zii/widgets/CListView.php. Минимальный код необходимый для вызова виджета:
$dataProvider = new CActiveDataProvider('Model');
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_testimonial',
'sortableAttributes'=>array(
'rating',
'create_time',
),
));
Рассмотрим, как можно немного изменить виджет для своих целей. Но, для начала разберем, какие параметры передаются в CListView в примере выше.
dataProvider —
dataProvider .
itemView — представление, в котором будет рендерится каждая запись выводимая в CListView.
sortableAttributes — атрибуты, по которым происходит сортировка.
Усложним пример и изменим для своих целей виджет. Представим, что у нас есть таблица с отзывами, с такой структурой:
name — имя человека оставившего отзыв.
city — город.
rating — рейтинг отзыва.
created_at — дата создания отзыва.
Нам нужно вывести отзывы из таблицы tbl_testimonials в CListView. Сортировка будет по rating и created_at. Для сортера, должен задаваться собственный стиль. Постраничная навигация в стандартном виде тоже не пойдет. Все атрибуты сортера будут выводиться в span и со стрелочками ▲▼.
Создадим контроллер TestimonialController.php
<?php
class TestimonialController extends Controller
{
public function actionIndex()
{
$model = new Testimonial();
$dataProvider = new CActiveDataProvider('Testimonial', array(
//Критерий для запроса. В этом примере, выбираются все отзывы, которые прошли модерацию.
'criteria'=>array('condition'=> 'moderation != 1'),
//Настройки для постраничной навигации
'pagination'=>array(
//Количество отзывов на страницу
'pageSize'=>5,
'pageVar'=>'page',
),
//Настройки для сортировки
'sort'=>array(
//атрибуты по которым происходит сортировка
'attributes'=>array(
'rating'=>array(
'asc'=>'rating ASC',
'desc'=>'rating DESC',
//по умолчанию, сортируем поле rating по убыванию (desc)
'default'=>'desc',
),
'created_at'=>array(
'asc'=>'created_at ASC',
'desc'=>'created_at DESC',
'default'=>'desc',
)
),
/** После того, как будет загружена страница с виджетом,
* сортировка будет происходить по этому параметру.
* Если указан defaultOrder, то задается стиль для атрибута, по которому происходит сортировка.
* В данном случае у created_at будет class="desc".
*/
'defaultOrder'=>array(
'created_at'=>CSort::SORT_DESC,
)
),
));
$this->render('index', array('dataProvider'=>$dataProvider,
'model'=>$model));
}
}
Нет смысла приводить модель Testimonial, там все стандартно. Получить ее можно, после генерации кода в gii.
Т.к. нам нужны собственные стили для для постраничной навигации и для сортируемых атрибутов, переопределим виджет, наследовав класс CListView. Для этого создадим файл MyClistView.php. У меня он находится в site/protected/widgets. В дальнейшем этот путь будет использоваться при подключении виджета.
Код MyClistView.php
<?php
class MyClistView extends CListView {
/**
* Для изменения сортера нужно изменить метод renderSorter()
* Renders the sorter.
*/
public function renderSorter()
{
//В качестве пейджера используем свой класс, со своими стилями
$this->pager = array('class'=>'MyPager');
if($this->dataProvider->getItemCount()<=0 || !$this->enableSorting || empty($this->sortableAttributes))
return;
echo CHtml::openTag('div',array('class'=>$this->sorterCssClass))."\n";
echo $this->sorterHeader===null ? Yii::t('zii','Sort by: ') : $this->sorterHeader;
echo "<ul>\n";
$sort=$this->dataProvider->getSort();
foreach($this->sortableAttributes as $name=>$label)
{
if($label == 'created_at') {
$link_name = "<span>по дате добавления</span>";
} else {
$link_name = "<span>по рейтингу</span>";
}
if(is_integer($name)){
//если производят сортировку
if(!empty($_GET['Testimonial_sort'])) {
$sorter_type = $_GET['Testimonial_sort'];
if($sorter_type == 'created_at' && $name == 1) {
echo $sort->link($label, $link_name.' ▼', $htmlOptions=array('class'=>'active'));
} elseif($sorter_type == 'created_at.desc' && $name == 1) {
echo $sort->link($label, $link_name.' ▲', $htmlOptions=array('class'=>'active'));
} elseif($sorter_type == 'rating' && $name == 0) {
echo $sort->link($label, ''.$link_name.' ▼', $htmlOptions=array('class'=>'active'));
} elseif($sorter_type == 'rating.desc' && $name == 0) {
echo $sort->link($label, $link_name.' ▲', $htmlOptions=array('class'=>'active'));
} else {
echo $sort->link($label, $link_name);
}
} else {
//sorter до сортировки
if($label == 'created_at') {
echo $sort->link($label, $link_name.' ▲', $htmlOptions=array('class'=>'active'));
} else {
echo $sort->link($label, $link_name);
}
}
} else {
echo $sort->link($name,$label);
}
}
echo "</ul>";
echo $this->sorterFooter;
echo CHtml::closeTag('div');
}
}
?>
Все запросы для сортировки в CListView передаются в виде $_GET-параметров. Поэтому, я не придумал ничего лучше использования $_GET[‘Testimonial_sort’] для определения какой атрибут сейчас сортируется. Для сортировки по убыванию в $_GET[‘Testimonial_sort’] передается attribute_name.desc, если по возрастанию, то просто attribute_name. В $name передается 0 или 1, в зависимости от атрибута. Возможно для достижения поставленной цели, есть более лучшее решение.
Для вывода всех отзывов используется index.php.
<?php
$this->widget('application.widgets.MyClistView', array(
'dataProvider'=>$dataProvider,
'ajaxUpdate'=>true,
'template'=>'{sorter}{items}{pager}',
'itemView'=>'_view',
'cssFile'=>false,
'sorterHeader'=>'Сортировка',
'sorterCssClass'=>'filter-menu sort',
'pagerCssClass'=>'YiiPager',
'pager'=>array('maxButtonCount'=>'5',),
'sortableAttributes'=>array(
'rating',
'created_at',
),
));
?>
application.widgets.MyClistView — это путь до виджета.
ajaxUpdate — использование ajax’a в работе виджета. По умолчанию true.
template — шаблон отображения записей, навигации и атрибутов, которые буду участвовать в сортировке.
itemView — представление в котором рендерится отзыв.
cssFile — включаем/выключаем стандартные css-стили.
sorterHeader — заголовок, который выводится перд ссылками сортера.
sorterCssClass — css-класс для сортера.
pagerCssClass — css-класс используемый в постраничной навигации.
afterAjaxUpdate — javascript, который срабатывает после загрузки CListView.
pager — количество данных на страницу. В нашем случае будет выводится 5 отзывов на 1-й странице.
sortableAttributes — атрибуты, которые будут сортироваться.
Код в представлении _view.php:
<div>
<strong><?php echo CHtml::encode($data->name); ?></strong><br />
г. <?php echo CHtml::encode($data->city); ?> <br />
Рейтинг: <?php echo CHtml::encode($data->rating); ?>
</div>
Итак, в этой статье мы рассмотрели несколько примеров работы с CListview в yii. Подробнее о свойствах и методах CListview можно прочитать на
http://www.yiiframework.com