AJAX-пагинация (кнопка загрузить ещё) в OctoberCMS

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

Не захотел делать пагинацию в виде циферок, по клику на которые меняются страницы с элементами. Решил, что сделаю кнопку «Загрузить ещё» при помощи AJAX.

Не буду подробно описывать про компонент и т.д., опишу самые главные вещи, чтобы копировал-вставил и заработало.

В первую очередь засунем всю списочную часть из default.htm в отдельный partial и добавим div#list и div#load-more-button:

# default.htm

<div id="list">
    {% partial '@_list' %}
</div>

<div id="load-more-button" class="loadmore">
    <a data-request="onLoadMore" data-request-data="page: 1" href="#">Загрузить ещё</a>
</div>

div#list нужен для вывода списка, а div#load-more-button для замены кнопки на ничего, в случае, если кончились элементы.

Добавляем в модель функцию scopeListFrontEnd, которая запрашивает содержимое из бд, попутно разбивая его на страницы:

# MyModel.php

class MyModel extends Model 
{
    public function scopeListFrontEnd($query, $options = []) 
    {
        extract(array_merge([
            'page'    => 1,
            'perPage' => 10,
        ], $options));

        return $query->paginate($perPage, $page);
    }
}

Как параметры, мы передаём текущую страницу и количество элементов на странице.

Теперь расширим класс компонента:

# ComponentClass.php

class ComponentClass extends ComponentBase
{
    public $items;

    public function defineProperties()
    {
        'pageNumber' => [
            'title'       => 'Page Number',
            'description' => 'Description',
            'type'        => 'string',
            'default'     => '{{ :page }}',
        ],
    }

    public function onRun()
    {
        $items = $this->loadItems():

        // если в url страница больше, чем всего страниц, то редиректим на последнюю
        if ($pageNumberParam = $this->paramName('pageNumber')) {
            $currentPage = $this->property('pageNumber');
            if ($currentPage > ($lastPage = $this->questions->lastPage()) && $currentPage > 1) {
                return Redirect::to($this->currentPageUrl([$pageNumberParam => $lastPage]));
            }
        }
    }

    public function loadItems()
    {
        $items = MyModel::listFrontEnd([
            'page'    => $this->property('pageNumber'),
            'perPage' => 10,
        ]);

        return $items;
    }

    /*
     * Данная функция вызывается по клику на кнопку "Загрузить ещё"
     */
    public function onLoadMore()
    {
        // получаем номер страницы
        $pageNumber = Input::get('page') + 1;

        // выставляем номер страницы и готовим данные
        $this->setProperty('pageNumber', $pageNumber);
        $this->onRun();

        if ($pageNumber < $this->items->lastPage()) {
            $more_link = $this->renderPartial('@_morelink.htm', ['pageNumber' => $pageNumber]);
        } else {
            $more_link = ''; // если мы достигли последней страницы, кнопка больше не нужна
        }

        return [
            // если перед селектором стоит @, новое содержимое будет добавляться
            // в конец, а не заменять старое
            '@#list'            => $this->renderPartial('@_list.htm'),
            '#load-more-button' => $more_link,
        ];
    }

}

Не забудь для страницы добавить в url "/page/:page?/", и готово 🙂

Комментарии (1):

  1. mfc-site.ru Ответить

    OctoberCMS включает в себя AJAX фреймворк, который позволяет выполнять AJAX запросы, находящиеся в страницах, шаблонах или компонентах, и обновлять элементы страницы при помощи фрагментов. Существует два способа его использования: JavaScript API и Data attributes API. Data attributes API не требует каких-либо знаний JavaScript.

    27.02.2019 в 21:05

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *