Механизм "Показать еще" в Битрикс

Механизм "Показать еще" в Битрикс - Дмитрий Языков Давайте посмотрим как быстро и просто реализовать эту возможность. В качестве примера я возьму статьи в своём блоге, а в итоге получится что-то такое: gif (3.17 Mb).

По шагам:
  1. Создадим шаблон компонента постраничной навигации (bitrix:system.pagenavigation);
  2. Адаптируем шаблон компонента списка новостей (bitrix:news.list);
  3. Разместим на странице и настроим компонент (bitrix:news.list).

1. Создание шаблона постраничной навигации


Я покажу как сделать это вручную, но вы можете просто скопировать один из стандартных шаблонов и заменить в нем код на мой.

Для начала создадим раздел "system.pagenavigation" в шаблоне сайта: /bitrix/templates/[ваш шаблон]/components/bitrix/ или /local/templates/[ваш шаблон]/components/bitrix/. Если раздел уже существует (как в моём случае), новый создавать не надо:) 

В нем создадим подраздел с названием нашего шаблона. Назовем его "show_more" (я буду использовать phpStorm, но те же действия можно проделать с помощью других редакторов или админки Битрикс).
Создание шаблона компонента

Каждый шаблон компонента должен содержать файл template.php, в нем будет храниться оформление. Также для реализации динамической подгрузки нам потребуются файлы script.js и style.css, где мы пропишем соответственно скрипт и стили.

Первым делом возьмемся за template:
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
$this->createFrame()->begin("Загрузка навигации");
?>

<?if($arResult["NavPageCount"] > 1):?>

    <?if ($arResult["NavPageNomer"]+1 <= $arResult["nEndPage"]):?>
        <?
            $plus = $arResult["NavPageNomer"]+1;
            $url = $arResult["sUrlPathParams"] . "PAGEN_1=" . $plus
        ?>

        <div class="load_more" data-url="<?=$url?>">
            Показать еще
        </div>

    <?else:?>

        <div class="load_more">
            Загружено все
        </div>

    <?endif?>

<?endif?>
На первые две строки не обращаем внимание, в рамках этой статьи мы их рассматривать не будем. 

Дальше два условия: кнопка загрузки будет показываться когда страниц больше 1 и когда есть следующая страница (текущая + 1). 

Кнопка будет представлять собой div с параметром data-url - адресом следующей станицы для подгрузки, классом load_more и надписью "Показать еще". 

Если страницы постраничной навигации кончились - покажем надпись "Загружено все". 

Следующий файл стилей. В нем будет оформление кнопки. Для примера я использовал простейшее оформление:
.load_more {
    margin: 10px;
    padding: 10px;
    border: 1px solid #ddd;
    cursor: pointer;
    text-align: center;
}
В сумме со стилями моего сайта, кнопка будет выглядеть как в примере. Вы же оформите её как вам нравится:)

Теперь самое главное - скрипт:
$(document).ready(function(){

    $(document).on('click', '.load_more', function(){

        var targetContainer = $('.news-list'),          //  Контейнер, в котором хранятся элементы
            url =  $('.load_more').attr('data-url');    //  URL, из которого будем брать элементы

        if (url !== undefined) {
            $.ajax({
                type: 'GET',
                url: url,
                dataType: 'html',
                success: function(data){

                    //  Удаляем старую навигацию
                    $('.load_more').remove();

                    var elements = $(data).find('.news-item'),  //  Ищем элементы
                        pagination = $(data).find('.load_more');//  Ищем навигацию

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

                }
            })
        }

    });

});
Как это работает: после нажатия на кнопку (div) срабатывает событие, отсылающее ajax запрос к указанному в кнопке адресу (атрибут data-id). Мы удаляем старую навигацию (класс .load_more), чтоб она не дублировалась. В полученных данных ищем элементы (в нашем случае класс .news-item, о нем чуть ниже) и уже известную нам навигацию (.load_more).

Последним этапом работы скрипта, в контейнер .news-list (о нем тоже ниже) добавляем полученные элементы и навигацию.

2. Шаблон компонента списка новостей

Создадим папку шаблона компонента (/local/templates/[ваш шаблон]/components/bitrix/news.list/show_more_news/, либо /bitrix/templates/[ваш шаблон]/components/bitrix/news.list/show_more_news/). 

Шаблон будет состоять всего из одного файла template.php:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
$this->setFrameMode(true);
?>
<div class="news-list">
    <?foreach($arResult["ITEMS"] as $arItem):?>
        <?
        $this->AddEditAction($arItem['ID'], $arItem['EDIT_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_EDIT"));
        $this->AddDeleteAction($arItem['ID'], $arItem['DELETE_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
        ?>
        <div id="<?=$this->GetEditAreaId($arItem['ID']);?>" class="news-item">

            <a href="<?=$arItem["DETAIL_PAGE_URL"]?>">

                <h2><?=$arItem["NAME"]?></h2>

            </a>

            <?=CFile::ShowImage($arItem['PREVIEW_PICTURE'])?>

            <?=$arItem['PREVIEW_TEXT']?>
        </div>
    <?endforeach;?>
</div>

<?=$arResult['NAV_STRING']?>
Вообще, оформление вы можете использовать какое угодно. Важная деталь: все элементы должны быть обёрнуты в блок с классом news-list, а каждый элемент иметь класс news-item (как в скрипте из второго пункта).

3. Размещение на странице и настройка компонента

На нужной странице размещаем компонент bitrix:news.list и настраиваем на необходимый инфоблок. 
В качестве шаблона компонента выбираем show_more_news (если вы все сделали правильно он должен появиться в списке), а в качестве шаблона постраничной навигации - show_moreНастройка компонента news.list
И указываем нужное количество новостей на странице. Именно столько элементов будет подгружаться после нажатия на кнопку.

Еще раз пример того, что у меня получилось: gif (3.17 Mb)

Возврат к списку