Пагинация при загрузки контента на ajax

14 января 2022 г.

На данный момент существует огромное количество статей и примеров для запроса очередной порции данных по ajax. Более того, для многих Фреймворков и CMS, в данном случае Bitrix, существуют уже реализованные механизмы и написанные классы для облегчения и ускорения работы с такими задачами.

И вроде бы все работает с определённой логикой, и как правило, скрыто «под капотом движка». Но проблемы начинают возникать, когда нужно применять не совсем обычную логику, а дополнительные фильтры для отбора данных, использование пагинации или вложенного ajax - запроса в основной запрос.

Когда я столкнулся с подобной задачей, для начала я решил перебрать различные методы из документации, но понял, что вопрос необходимо решить срочно и максимально качественно, а примеры могут вызвать ошибки, нестыковки, плюс затрата по времени на разбор этих примеров и поиск подходящего варианта реализации. И, поразмыслив, я решил использовать свой собственный костыль, который и помог решить каверзную задачу.

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

Итак, начнем. Нам понадобится компонент, и я, для удобства. взял bitrix:news.list, как самый простой компонент для вывода однотипных записей из базы. Первый вид будет выглядеть, примерно, так:

    <div class="w_list">

        //вывод цикла видюшек
        <?foreach($arResult["ITEMS"] as $arPastWebinar) {?>
            <div class="webinar_item">
                // одна видюшка
            </div>      
        <?}?> 

        // вычисляем следующую страницу и для кнопки еще прописываем **data атрибут** с этим значением
        <?if($arResult["NAV_RESULT"]->NavPageNomer + 1 <= $arResult["NAV_RESULT"]->nEndPage) {
            $plus = $arResult["NAV_RESULT"]->NavPageNomer + 1;
            $url = $arResult["NAV_RESULT"] ->sUrlPathParams . "PAGEN_1=".$plus;

            ?>
            <div class="webinar__load">
                <a id="js_more_click" href="#" data-url="<?=$url?>">Показать ещё</a>
            </div>
        <?}?>   

    </div>

на индексной странице index.php, где расположен сам компонент, можно указать фильтр для элементов в поле "FILTER_NAME"

$arPastWebinarsFilter = [       
    "<=DATE_ACTIVE_TO" => date($DB->DateFormatToPHP(CLang::GetDateFormat("FULL")), mktime()),
    "ACTIVE"=>"Y",      
];

При клике по кнопке «показать» еще перехватываем событие и отправляем ajax - запрос на другую страницу, где расположен тот же компонент. Ajax - запрос выглядит примерно так:

$("body").on('click', "#js_more_click", function(e){    

    var self = $(this);
    var container = $(".w_list");
    var url = self.data("url");

    if(url !== undefined) {
        $.ajax({
            type: 'GET',
            url: "/ajax/past_webinar_ajax_request.php?AJAX_CALL=Y&" + url,
            dataType: 'html',
            success: function(data){                    
                //  Удаляем старую навигацию
                $(".webinar__load").remove();

                var elements = $(data).find('.webinar_item');  //  Ищем элементы:
                var pagination = $(data).find('.webinar__load');//  Ищем навигацию в новых элементах:

                container.append(elements);   //  Добавляем посты в конец контейнера:
                container.append(pagination); //  добавляем навигацию следом

            }
        })
    }

    e.preventDefault()
});

На странице past_webinar_ajax_request.php не забываем очистить буфер. Для этого передаем в запросе get параметром "AJAX_CALL"

<? require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");
      if($_REQUEST["AJAX_CALL"] == "Y") {
      global $APPLICATION;
      $APPLICATION->RestartBuffer();
}?>

Тут тоже можно применять, необходимые для выборки данных, фильтры поля "FILTER_NAME"

Компонент сам подцепляет текущую страницу пагинации благодаря второму get параметру PAGEN_1=N. Так же не забываем указывать кол-во выводимых записей "NEWS_COUNT" в компоненте, иначе будет подгружаться другое кол-во элементов.

Хотя все страницы и выборка работает на автомате, ничего критичного не произойдет. Надеюсь статья была полезна)).

Комментарии(0)