Пример работы с CListView в Yii



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 в примере выше.

dataProviderdataProvider .
itemView — представление, в котором будет рендерится каждая запись выводимая в CListView.
sortableAttributes — атрибуты, по которым происходит сортировка.

Усложним пример и изменим для своих целей виджет. Представим, что у нас есть таблица с отзывами, с такой структурой:
scheme

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



Теги: ,

Комментарии

  1. Это не пример работы, это описание примера работы, нужен пример рабочий — чтобы видно было результат этого кода — демо!

    Reply

    Max Reply:


    >описание примера работы
    Тогда, что мешает читателям самим сделать из описания примера рабочий пример? В посте подробно описано, что где нужно подключать/выводить. Как раз будет необходимая практика и опыт работы с CListView.

    Reply

    vadim_d Reply:


    Примеры из описания сделал сам сам, спасибо автору!

    Reply

  2. Спасибо за пример, правда очень намучался пока переделал…

    Reply

    Max Reply:


    С чем у вас возникли трудности?

    Reply

  3. Спасибо за статью!
    Подскажите, пожалуйста, как настроить определенные поля для вывода, например, если нужно выводить не все поля таблицы. Спасибо!

    Reply

    mistero Reply:


    Спасибо! Извините за беспокойство, разобралась

    Reply

  4. Спасибо за годный пример!
    Хорошо бы указать в коде MyClistView.php, что сперва следует импортировать исходный CListView:
    Yii::import(‘zii.widgets.CListView’);

    Reply

Оставить комментарий