falbar 1С-Битрикс компонент – AJAX навигация

1С-Битрикс компонент – AJAX навигация

14 декабря 2017 3195 3

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

Реклама

Перед тем, как начать, предлагаю обратиться к маркету Битрикс и узнать какие решения этой задачи уже есть. Разнообразия тут маловато и все варианты платные:

bitriks-market

Попробовав их, я наткнулся на ситуацию, что некоторые просто не работают, а другие неудобны. Как по мне: упаковать AJAX навигацию в модуль не лучший вариант, а компонент - как раз то, что нужно.

Структура компонента

Как уже принято, разрабатываемый компонент помещаем в папку local, что позволит отделить дополнительный функционал, и уменьшить захламлённость сайта. Сама же структура будет выглядеть так:

komponent-pomeshhaem-v-papku-local
  1. falbar – область видимости нашего компонента в системе, внутри её лежит уже, непосредственно, наш компонент ajax.pagenavigation;
  2. Далее мы видим две стандартных папки с языковыми данными, шаблонами компонента;
  3. И в завершение три стандартных файла: class.php (автоматически подключаемый файл при вызове компонента),.parameters.php (параметры компонента),.description.php (описание компонента в системе).
lang-russkoyazychnyj-varianta

В папке lang будут находиться два варианта для русскоязычного и англоязычного определения. В дальнейшем в статье примеры будут только для русскоязычного варианта.

shablon-komponenta

В шаблонах у нас будет только один (по умолчанию) вариант. Для нашей задумки потребуется реализовать простенькую верстку со стилями, а также написать JavaScript код, который и будет осуществлять подгрузку контента.

Первые шаги перед написанием компонента

Перед тем, как начать писать компонент, необходимо определиться с его настройками. Для начальной реализации их будет не много. Нам понадобится:

  1. Для получения количества элементов, нам потребуется знать в котором инфоблоке будет вызван компонент;
  2. Так же нам потребуется класс или индификатор обертки, в которой будут находиться наши новости, товары или другие элементы;
  3. Ещё потребуется знать класс или индификатор для обёрток навигации и самого элемента.

По настройкам всё. Теперь можно описать саму логику решения: после того, как мы добавим наш компонент (AJAX навигация), первым делом спрячем стандартную Битрикс навигацию. Далее мы отобразим кнопку при нажатии на которую, будет подгружаться контент и добавляться к существующему. Также учтем страницы пагинации, чтобы пользователь не мог на них зайти, установим 404 ридирект. Звучит всё просто – приступим!

Работаем над файлом описания компонента

Для того, чтобы наша навигация появилась в редакторе нам нужно заполнить файл .description.php. Тут есть один момент, который я заметил: при сбросе кэша в редакторе результата мы не увидим, его нужно сбрасывать в административной части. Хотя может это только у меня так.

if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

use Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);

$arComponentDescription = array(
 "NAME"          => Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_DESC_NAME"),
  "DESCRIPTION" => Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_DESC_DESC"),
    "PATH"          => array(
      "ID" => Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_DESC_ID")
    )
);

Тут у нас стандартная структура описания - все текста вынесены в соответствующие lang-файлы:

$MESS["FALBAR_AJAX_PAGENAVIGATION_DESC_NAME"] = "AJAX навигация";
$MESS["FALBAR_AJAX_PAGENAVIGATION_DESC_DESC"] = "AJAX навигация.";
$MESS["FALBAR_AJAX_PAGENAVIGATION_DESC_ID"]   = "Фалбар";

В результате, когда вы зайдёте в редактор страницы, будет видна такая картина:

dobavlenie-komponenta-v-redaktore

Значит всё правильно и можно продолжать работать.

Файл параметров компонента

Как выше было указано нам потребуется ряд параметров. В данном разделе в самом начале нам нужно получить список всех инфоблоков:

if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Loader;

Loc::loadMessages(__FILE__);

Loader::includeModule("iblock");

$iblocks = CIBlock::GetList(
    array(
      "SORT" => "ASC"
  ),
  array(
      "ACTIVE" => "Y"
  )
);

$iblock_values = array();

while($iblock = $iblocks->Fetch()){

  $iblock_values[$iblock["ID"]] = "[".$iblock["ID"]."] ".$iblock["NAME"];
}

Это легко реализуется стандартными методами API Битрикс, что видно выше в коде. Далее сформируем массив с параметрами нашего компонента:

$arComponentParameters = array(
 "PARAMETERS" => array(
     "IBLOCK"                    => array(
          "NAME"     => Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_PARAM_IBLOCK"),
            "TYPE"     => "LIST",
            "VALUES" => $iblock_values
     ),
      "SELECTOR_WRAPPER_NAVIGATION" => array(
            "NAME" => Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_PARAM_NAVIGATION"),
            "TYPE" => "STRING"
       ),
      "SELECTOR_WRAPPER_CONTENT"      => array(
          "NAME" => Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_PARAM_CONTENT"),
           "TYPE" => "STRING"
       ),
      "SELECTOR_ELEMENT"              => array(
          "NAME" => Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_PARAM_ELEMENT"),
           "TYPE" => "STRING"
       )
   )
);

Как видно вся структура этого массива однотипна, а о том, что она может содержать – хорошо описано в официальной документации Битрикс. Хотя лучший пример для изучения - это уже написанные компоненты. Добавим в соответствующие языковые файлы наши названия:

$MESS["FALBAR_AJAX_PAGENAVIGATION_PARAM_IBLOCK"]    = "Инфоблок";
$MESS["FALBAR_AJAX_PAGENAVIGATION_PARAM_NAVIGATION"] = "Селектор обертки навигации";
$MESS["FALBAR_AJAX_PAGENAVIGATION_PARAM_CONTENT"]      = "Селектор обертки контента";
$MESS["FALBAR_AJAX_PAGENAVIGATION_PARAM_ELEMENT"]     = "Селектор элемента";

Осталось увидеть результат:

parametry-komponenta

Перед тем, как переходить к следующей части статьи, нам нужно заполнить параметры и разместить компонент на странице. Для примера добавим его на страницу продукции стандартного Битрикс шаблона:

stranitsa-shablona-bitriks-produktsiya

И настроим следующим образам:

nastroennyj-komponent-ajax-navigatsii

Пишем логику компонента

В новом ядре Битрикс D7 логика компонента располагается в файле class.php. Что нам нужно? Первое - подключить шаблон. Далее получить параметры и их обработать, а в конце сформировать массив $arParams. Так же в своей работе мы будем использовать библиотеку jQuery, следовательно мы его подключим. Приступим!

if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

use Bitrix\Main\EventManager;
use Bitrix\Main\Loader;
use Bitrix\Main\Context;

Loader::includeModule("iblock");

class AjaxPagenavigation extends CBitrixComponent{

 // Остальной код пишем тут
}

В начале файла подключим нужные нам классы API, и создадим класс наследник AjaxPagenavigation от CBitrixComponent. Двигаемся дальше и переопределим в нем метод executeComponent(). В нем мы проверим на наличие в адресной строке параметра PAGEN и, если он есть, перенаправим пользователя на 404 страницу. Также обратимся к приватному методу initEvents(), где создадим событие перед загрузкой страницы (в нем подключим jQuery библиотеку). В конце подключим шаблон компонента:

public function executeComponent(){

    $request = Context::getCurrent()->getRequest();

  if(!$request->isAjaxRequest()){

      $server = Context::getCurrent()->getServer();

        if(strpos($server->getRequestUri(), "PAGEN_") !== false){

          LocalRedirect("/404.php", "404 Not Found");
     }
   }

   $this->initEvents();

 $this->includeComponentTemplate();

   return false;
}
private function initEvents(){

  EventManager::getInstance()->addEventHandler(
        "main",
       "OnBeforeEndBufferContent",
       function(){

         CJSCore::Init(
              array(
                  "jquery"
              )
           );
      }
   );

  return false;
}

Осталось разобраться с параметрами:

public function onPrepareComponentParams($params = array()){

 if($params){

        $params["COUNT"] = CIBlock::GetElementCount($params["IBLOCK"]);

     unset($params["IBLOCK"]);
     unset($params["CACHE_TYPE"]);

     $params["PARAMS"] = json_encode($params);

     unset($params["SELECTOR_ELEMENT"]);
       unset($params["SELECTOR_WRAPPER_CONTENT"]);
       unset($params["SELECTOR_WRAPPER_NAVIGATION"]);
        unset($params["COUNT"]);

      return $params;
 }

   return false;
}

В методе onPrepareComponentParams() наша задача сформировать элемент PARAMS массива $arParams. В себе он сдержит заполненные пользователем настройки, а также полученное число записей в инфоблоке. Хорошим тоном будет удалить из массива параметры, которые мы не используем.

Шаблон компонента по умолчанию

Закончив с основной частью, нам нужно сформировать шаблон. Он будет максимально простым:

<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

use Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);
?>

<div id="falbar-ajax-pagenavigation-wrapper" data-params="<? echo($arParams["PARAMS"]); ?>">
   <span id="falbar-ajax-pagenavigation-button">
       <? echo(Loc::getMessage("FALBAR_AJAX_PAGENAVIGATION_TEMP_BUTTON")); ?>
  </span>
</div>

Сразу же заполним lang-файлы:

$MESS["FALBAR_AJAX_PAGENAVIGATION_TEMP_BUTTON"] = "Ещё";

И укажем в завершении CSS стили:

div#falbar-ajax-pagenavigation-wrapper{
   text-align: center;
 padding: 20px;
}
span#falbar-ajax-pagenavigation-button{
  cursor: pointer;
    font-weight: bold;
  opacity: 0.9;
}
span#falbar-ajax-pagenavigation-button:hover{
 opacity: 1;
}

В результате всей этой магии мы получаем кнопку на странице, с которой уже и будем работать в JS файле:

poluchaem-ajax-knopku-na-stranitse

Последний этап разработки компонента JavaScript

Вот мы и подобрались к финальной части нашей сегодняшней темы – AJAX навигация. Весь код будет исполняться после загрузки страницы:

$(function(){

 // Наша подгрузка
});

Найдем кнопку на странице и наши параметры:

var wrapper = $("#falbar-ajax-pagenavigation-wrapper"),
   button  = $("#falbar-ajax-pagenavigation-button");

if(wrapper.length){

 var params = wrapper.data("params");

  if(params){

     // Ещё глубже
   };
};

Далее получим все необходимые настройки:

var  navigation = $(params.SELECTOR_WRAPPER_NAVIGATION),
 pagenStr = navigation.find("a").attr("href"),
   pagenIndex = pagenStr.indexOf("PAGEN_") + 1,
  element = params.SELECTOR_ELEMENT,
  content = $(params.SELECTOR_WRAPPER_CONTENT),
   elementCount = params.COUNT;

После чего спрячем стандартную навигацию Битрикс:

navigation.hide();

И в зависимости от числа записей, опишем действия после нажатия на кнопку «Ещё»:

if(pagenIndex){

    pagenStr = pagenStr.substring(pagenIndex - 1, pagenIndex + 7);

  wrapper.attr("data-page", 1);

 button.on("click", function(){

        var pageCurrent = parseInt(wrapper.attr("data-page")),
            elementCountCurrent = $(element).length;

        if(elementCount != elementCountCurrent){

            ++pageCurrent;

          BX.showWait();
          $(this).hide();

         $.ajax({
                url: location.origin + location.pathname + "index.php?" + pagenStr + pageCurrent,
             success: function(data){

                    content.append(
                     $(data).find(element)
                   );

                  wrapper.attr("data-page", pageCurrent);

                   BX.closeWait();

                 if(elementCount != $(element).length){

                      button.show();
                  };
              }
           });
     };

      return false;
   });
};

В выше указанном коде, важно пояснить: сформировав путь следующей страницы мы получаем её целиком и уже средствами jQuery достаем необходимые записи.

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

Реклама
Егор Смирнов
21 октября 2019
Скиньте пожалуйста готовый архив с файлами
Антон Кулешов
21 октября 2019
Егор Смирнов, В конце статьи есть кнопка скачать.
Егор Смирнов
6 ноября 2019
После нажатия на "Еще" бесконечно подгружатюся товары дубликаты по 27 штук, в отображении стоит 7шт на страницу, в чем проблема?
no_avatar