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

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

3 минуты
🙈 ∞
механизм показать еще в битрикс
Давайте посмотрим как быстро и просто реализовать эту возможность. В качестве примера я возьму статьи в своём блоге, а в итоге получится что-то такое: 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_".$arResult["NavNum"]."=".$plus;

        ?>

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

    <?else:?>

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

    <?endif?>

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

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

Кнопка будет представлять собой div с параметром data-url - адресом следующей станицы для подгрузки, классом load_more и надписью "Показать еще".
Читайте также: 7 смертных грехов разработки на 1С-Битрикс.
Если страницы постраничной навигации кончились - покажем надпись "Загружено все".

Следующий файл стилей. В нем будет оформление кнопки. Для примера я использовал простейшее оформление:
.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).
Статья из подборки 1С-Битрикс Разработка сайтов
Обсудим проект? Напиши в Телеграм, Whatsapp или ВК

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

Чтобы оставить комментарий, авторизуйтесь. Войти или зарегистрироваться
Александр Ермакович 23:12 11.07.2019

Дмитрий, спасибо! Работает ваше решение.
А как вывести элементы только из подраздела?
т.е. есть список разделов, из которых я вывожу 5 новостей. После каждого раздела идет кнопка " показать далее", при нажатии на которую подгружаются данные, но для всех разделов, а как ограничить их текущим разделом? т.е. что бы при нажатии далее у раздела 2, подгрузились новости только в этот раздел?

0 #

$(document).ready(function(){

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

var targetContainer = $('.bx_catalog_list_home'), // Контейнер, в котором хранятся элементы
url = $('.load_more').attr('data-url'); // URL, из которого будем брать элементы
$('.load_more').remove();
if (url !== undefined) {
$.ajax({
type: 'GET',
url: url,
dataType: 'html',
success: function(data){
// Удаляем старую навигацию

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


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

}
})
}
});
});

0 #
Yazykov Dmitry 08:51 30.04.2019

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

0 #

Хотелось бы ещё добавить, чтобы не было дублей нужно сделать так

pagination = $(data).find('.load_more').filter(':last');// Ищем навигацию

В конечном итоге у меня получилось

$(document).ready(function(){

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

var targetContainer = $('.bx_catalog_list_home'), // Контейнер, в котором хранятся элементы
url = $('.load_more').attr('data-url'); // URL, из которого будем брать элементы
$('.load_more').remove();
if (url !== undefined) {
$.ajax({
type: 'GET',
url: url,
dataType: 'html',
success: function(data){
// Удаляем старую навигацию

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


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

}
})
}
});
});

php и css без изменений

0 #

Здравствуйте. Сделал всё по инструкции, но что-то пошло не так... Сделал 4 новости. В "NEWS_COUNT" указал 3. При нажатии на кнопку просто дублируется ещё раз список из тех же 3 новостей, которые сразу видны и без нажатия (((

0 #
Yazykov Dmitry 09:11 13.03.2019

Выложите код на codepen, вслепую сложно что-то сказать)

0 #

Вывожу список новостей на главной странице, шаблон списка лежит в /bitrix/components/md/news.list/templates, шаблон навигации добавил в /bitrix/components/bitrix/system.pagenavigation/templates/

0 #
Матвей Бойко 11:47 31.10.2018

Подскажи, а как сделать кнопку "Посмотреть все"?

0 #
Yazykov Dmitry 14:31 10.01.2019

Алгоритм будет таким:
1. В настройках компонента проставляется галочка "Показывать ссылку "Все"
2. Для отображения всех элементов надо передать get-запрос с параметром SHOWALL_1=1. Делаем AJAX запрос с этим параметром, к файлу компонента. Компонент должен вернуть все записи.
3. Вставка блока и отображение на странице без существенных изменений.

0 #
Александр 20:43 06.10.2018

у меня заработало после небольшой правки:

0 #
Олександр Пасічняк 16:43 28.08.2018

Дмитрий, спасибо! Много вариантов решения перепробовал, только Ваше заработало

0 #
Yazykov Dmitry 16:25 25.09.2018

Спасибо за отзыв)

0 #
Alexandr Neudahin 08:25 01.06.2018

Классное решение - все просто и функционально!

0 #
Yazykov Dmitry 08:34 01.06.2018

Спасибо)

0 #
Инконгито 18:23 29.05.2018

А что, если у нас будет 60 новостей, на одной странице мы хотим выводить 16 новостей, если использовать ваш пример, то при нажатие "показать еще" выводит след. 16 новостей и при дальнейшей попытке нажать "посмотреть еще", он повторяет вывод новостей, которые были выгружены во второй раз

0 #
Yazykov Dmitry 08:33 01.06.2018

Добрый день) Такие частные случаи я не рассматривал, но, думаю не проблема в качестве "первой подгрузки" получать не вторую, а, например, четвертую страницу. Единственное ограничение - первоначальниый вывод (60 элементов) должны делиться на количество подгружаемых (у вас 16, возьмите 20 для удобства) без остатка, иначе будут пропадать элементы.

0 #
Kirill Seleznev 14:23 08.05.2018

Здравствуйте
Подскажите пожалуйста, есть ли возможность прикрутить два таких списка новостей с ajax подгрузкой на одной странице?
Попробовал, первый отрабатывает как положено, а вот второй начинает при клике на "Показать еще" дублировать новости из своего списка.

0 #
Kirill Seleznev 15:55 08.05.2018

Хотя нашел ответ на свой вопрос.
Путем включения у компонентов AJAX_MODE => Y
и в компоненте подставить параметр AJAX_OPTION_ADDITIONAL присвоив ему уникальное значение.

0 #
Евгений (Яндекс) 22:00 28.09.2018

Решил!
Проблема была в том, что в шаблоне постраничной навигации я прописал параметр
$paramName = "PAGEN_1";
а надо было:
$paramName = "PAGEN_" . $arResult["NavNum"];

0 #
Yazykov Dmitry 07:11 20.04.2019

Да, ваш подход более верный. Внес изменения в статью)

0 #
Sundari Tokarenko 16:01 19.04.2019

Огромное спасибо!
В примере автора нужно заменить:
$url = $arResult["sUrlPathParams"] . "PAGEN_1=" . $plus;
НА:
$url = $arResult["sUrlPathParams"] . "PAGEN_".$arResult["NavNum"]."=".$plus;

0 #
Евгений (Яндекс) 21:28 28.09.2018

Задал уникальные классы: load_more1, news-list1 и т. д.. Кэширование отключил.

Установил AJAX_MODE => Y и прописал уникальные AJAX_OPTION_ADDITIONAL в компонентах, но всё равно 2-й по списку компонент дублирует свои элементы.
Куда копать, уже не знаю.

0 #
Yazykov Dmitry 14:33 08.05.2018

Добрый день!)

Вообще, должно решаться очень просто: необходимо в скрипте и шаблоне компонента задать уникальные классы. Например: load_more1, news-list1 и тд. Надо проверить, не экспериментировал:)

0 #
Anton Vc 14:10 16.03.2018

Не хватает обработки истории браузера, при клике "Назад" - "Вперед" мы должны попадать в то же место, должны загружаться ранее загруженные страницы

0 #
Yazykov Dmitry 14:43 08.05.2018

Отличное предложение)

0 #
Виктор 17:03 20.06.2022

как реализовать?

0 #
Andrew Ryasantsev 11:36 26.01.2018

А как сделать так, чтобы фокус не перемещался наверх страницы?

0 #
Telegram
+
tg
Мы в Telegram Читай первым уникальный контент
+
Подпишись на наш Телеграм канал