AJAX-пагинация (кнопка загрузить ещё) в October CMS
Написал я компонент, и оказалось так, что вывожу сотню-другую элементов в рамках этого компонента. Естественно, что для этого добра нужна пагинация.
Не захотел делать пагинацию в виде циферок, по клику на которые меняются страницы с элементами. Решил, что сделаю кнопку «Загрузить ещё» при помощи 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()
{
$this->items = $this->loadItems():
// если в url страница больше, чем всего страниц, то редиректим на последнюю
if ($pageNumberParam = $this->paramName('pageNumber')) {
$currentPage = $this->property('pageNumber');
if ($currentPage > ($lastPage = $this->items->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?/"
, и готово 🙂
Здравствуйте!
Пытаюсь воспользоваться решением «копировал-вставил и заработало» и никак:
Call to a member function lastPage() on null
В этой строке:
if ($currentPage > ($lastPage = $this->items->lastPage()) && $currentPage > 1) {
Почему так?
P.S. В этой строке исправлено questions на items
12.08.2019 в 03:26Привет! Чтобы разобраться, нужно видеть код модели и компонента. Закинь код на https://gist.github.com и скинь сюда, либо на почту — ref@deadblog.ru
12.08.2019 в 10:47public function onRun()
{
$items = $this->loadItems():
// если в url страница больше, чем всего страниц, то редиректим на последнюю
15.01.2020 в 17:52if ($pageNumberParam = $this->paramName('pageNumber')) {
$currentPage = $this->property('pageNumber');
if ($currentPage > ($lastPage = $this->items->lastPage()) && $currentPage > 1) {
return Redirect::to($this->currentPageUrl([$pageNumberParam => $lastPage]));
}
}
}
здесь просто глобального $items надо инициализировать
$this->items = $this->loadItems(); вот так
15.01.2020 в 17:53Спасибо, поправил в статье!
15.01.2020 в 18:15$this->renderPartial(‘@_morelink.htm’, [‘pageNumber’ => $pageNumber]);
16.01.2020 в 14:10здесь на партиали что я должен делать?
я уже разобрался спасибо за статья!
16.01.2020 в 15:45Вопрос новичка. MyModel.php, ComponentClass.php где эти файлы находятся или мы создаем новый плагин с данными файлами? Как должна выглядеть иерархия файлов.
01.08.2020 в 03:15Пример в статье — как сделать пагинацию в своём плагине.
01.08.2020 в 15:45ComponentClass.php — это класс компонента, он находится в /plugins/author/pluginName/components/
MyModel.php — это класс модели, он находится в /plugins/author/pluginName/models/
Пздц чел ты рукожопый. Во первых гайд не полный, во вторых это лажа.
02.10.2020 в 23:54Лажа — это твой комментарий. Вместо балабольства мог бы предметно написать чего не хватает или кинуть ссылку на более полный гайд.
09.10.2020 в 11:34