templates/_pagination.html.twig line 1

Open in your IDE?
  1. {#
  2. {#/**
  3.  * @file
  4.  * Twitter Bootstrap v4-beta.2 Sliding pagination control implementation.
  5.  *
  6.  * View that can be used with the pagination module
  7.  * from the Twitter Bootstrap CSS Toolkit
  8.  * https://getbootstrap.com/docs/4.0/components/pagination/
  9.  *
  10.  */
  11. #}
  12. {%- macro _pagination_path(route, query, pageParameterName, page_number) -%}
  13.     {%- set city = app.request.attributes.get('city', default_city()) -%}
  14.     {%- if page_number == 1 -%}
  15.         {%- set _route = route -%}
  16.         {%- set _query = query|filter((v, k) => k != pageParameterName) -%}
  17.     {%- else -%}
  18.         {%- set _route = route~'._pagination' -%}
  19.         {%- set _query = query|merge({(pageParameterName): page_number}) -%}
  20.     {%- endif -%}
  21.     {%- set _query = _query|merge({'city': city.uriIdentity}) -%}
  22.     {{- path(_route, _query) -}}
  23. {%- endmacro -%}
  24. {% from _self import _pagination_path %}
  25. <div id="pagination_container">
  26.     {% if pageCount > 1 %}
  27.     <nav class="pagination">
  28.         {% set classAlign = (align is not defined) ? '' : align=='center' ? ' justify-content-center' : (align=='right' ? ' justify-content-end' : '') %}
  29.         {% set classSize = (size is not defined) ? '' : size=='large' ? ' pagination-lg' : (size=='small' ? ' pagination-sm' : '') %}
  30.         <ul class="pagination__list d-flex">
  31.             {% if previous is defined %}
  32.                 <li class="pagination__item rounding pagination__item-prev">
  33.                     <a class="pagination__link" rel="prev" href="{{ _pagination_path(route, query, pageParameterName, previous) }}" aria-label="Ссылка на предыдущую страницу" data-page="{{previous}}">{#&laquo;&nbsp;{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}#}
  34.                         <svg class="icon">
  35.                             <use xlink:href="{{ asset('assets_domain/images/icons/svg-library.svg', 'nodomainConfig') }}#icon-arrow-left"></use>
  36.                         </svg>
  37.                     </a>
  38.                 </li>
  39.             {% else %}
  40.                 <li class="pagination__item rounding pagination__item--disabled">
  41.                     <span class="pagination__link d-flex">
  42.                         {#&laquo;&nbsp;{{ 'label_previous'|trans({}, 'KnpPaginatorBundle') }}#}
  43.                         <svg class="icon">
  44.                             <use xlink:href="{{ asset('assets_domain/images/icons/svg-library.svg', 'nodomainConfig') }}#icon-arrow-left"></use>
  45.                         </svg>
  46.                     </span>
  47.                 </li>
  48.             {% endif %}
  49.             {% if startPage > 1 %}
  50.                 <li class="pagination__item rounding">
  51.                     <a class="pagination__link" href="{{ _pagination_path(route, query, pageParameterName, 1) }}" aria-label="Ссылка на первую страницу">1</a>
  52.                 </li>
  53.                 {% if startPage == 3 %}
  54.                     <li class="pagination__item rounding">
  55.                         <a class="pagination__link" href="{{ _pagination_path(route, query, pageParameterName, 2) }}" aria-label="Ссылка на вторую страницу">2</a>
  56.                     </li>
  57.                 {% elseif startPage != 2 %}
  58.                     <li class="pagination__item rounding pagination__item_spacer">
  59.                         <div class="pagination__link d-flex">...</div>
  60.                     </li>
  61.                 {% endif %}
  62.             {% endif %}
  63.             {% for page in pagesInRange %}
  64.                 {% if page != current %}
  65.                     <li class="pagination__item rounding">
  66.                         <a class="pagination__link" href="{{ _pagination_path(route, query, pageParameterName, page) }}" aria-label="Ссылка на {{ page }} страницу">{{ page }}</a>
  67.                     </li>
  68.                 {% else %}
  69.                     <li class="pagination__item rounding pagination__item_first pagination__item_active">
  70.                         <a href="#" class="pagination__link" aria-label="Неактивная ссылка">{{ page }}</a>
  71.                     </li>
  72.                 {% endif %}
  73.             {% endfor %}
  74.             {% if pageCount > endPage %}
  75.                 {% if pageCount > (endPage + 1) %}
  76.                     {% if pageCount > (endPage + 2) %}
  77.                         <li class="pagination__item rounding pagination__item_spacer">
  78.                             <div class="pagination__link">...</div>
  79.                         </li>
  80.                     {% else %}
  81.                         <li class="pagination__item rounding">
  82.                             <a class="pagination__link" href="{{ _pagination_path(route, query, pageParameterName, (pageCount - 1)) }}" aria-label="Ссылка на {{ pageCount -1 }} страницу">{{ pageCount -1 }}</a>
  83.                         </li>
  84.                     {% endif %}
  85.                 {% endif %}
  86.                 <li class="pagination__item rounding" data-show="true">
  87.                     <a class="pagination__link" href="{{ _pagination_path(route, query, pageParameterName, pageCount) }}" aria-label="Ссылка на {{ pageCount }} страницу">{{ pageCount }}</a>
  88.                 </li>
  89.             {% endif %}
  90.             {% if next is defined %}
  91.                 <li class="pagination__item rounding pagination__item-next">
  92.                     <a class="pagination__link" rel="next" href="{{ _pagination_path(route, query, pageParameterName, next) }}" aria-label="Ссылка на следующую страницу" data-page="{{next}}">
  93.                         <svg class="icon">
  94.                             <use xlink:href="{{ asset('assets_domain/images/icons/svg-library.svg', 'nodomainConfig') }}#icon-arrow-right"></use>
  95.                         </svg>
  96.                     </a>
  97.                 </li>
  98.             {% else %}
  99.                 <li class="pagination__item rounding pagination__item--disabled">
  100.                     <span class="pagination__link">
  101.                         <svg class="icon">
  102.                             <use xlink:href="{{ asset('assets_domain/images/icons/svg-library.svg', 'nodomainConfig') }}#icon-arrow-right"></use>
  103.                         </svg>
  104.                     </span>
  105.                 </li>
  106.             {% endif %}
  107.         </ul>
  108.     </nav>
  109.     <script>
  110.         function paginationChecked() {
  111.             {#
  112.                 В мобильной версии нам нужно показывать пункты +- 1 от текущей, стрелочки
  113.                 и точки если пунктов больше в текущем направлении
  114.             #}
  115.             const paginationList = document.querySelector('.pagination__list');
  116.             const activeEl = paginationList.querySelector('.pagination__item_active');
  117.             const previousActiveEl = activeEl.previousElementSibling;
  118.             const nextActiveEl = activeEl.nextElementSibling;
  119.             //const dotMarkup = `<li class="pagination__item rounding pagination__item--dot pagination__item--disabled pagination__item--mobile-active"><span class="pagination__link">…</span></li>`;
  120.             [...paginationList.children].forEach(el => {
  121.                 if (el.dataset.show) el.classList.add('pagination__item--mobile-active');
  122.                 el.addEventListener('click',() => {
  123.                     document.dispatchEvent(new CustomEvent("fetchSimilar:trigger", { detail: { type: 'recommendation' }}));
  124.                 })
  125.             })
  126.             {#// Проверяем элементы позади#}
  127.             if (elementCheck(previousActiveEl, 'pagination__item-prev')) {
  128.                 if (nextActiveEl) nextActiveEl.classList.add('pagination__item--mobile-active');
  129.                 const prePreviousActiveEl = previousActiveEl.previousElementSibling;
  130.                 if (prePreviousActiveEl && elementCheck(prePreviousActiveEl, 'pagination__item-prev') && (+activeEl.innerText > 3) && !prePreviousActiveEl.previousElementSibling.classList.contains('pagination__item--dot')) {
  131.                     {#// добавить многоточие#}
  132.                     appendDotPagination(previousActiveEl, false);
  133.                 }
  134.             }
  135.             {#// Проверяем элементы впереди#}
  136.             if (elementCheck(nextActiveEl, 'pagination__item-next')) {
  137.                 const nextNextActiveEl = nextActiveEl.nextElementSibling;
  138.                 if (elementCheck(nextNextActiveEl, 'pagination__item-next') && checkNextPlace(activeEl) && !nextNextActiveEl.nextElementSibling.classList.contains('pagination__item--dot')) {// && (+nextNextActiveEl.innerText < 3)
  139.                     {#// добавить многоточие#}
  140.                     appendDotPagination(nextNextActiveEl, true);
  141.                 }
  142.             }
  143.             {#/**
  144.             * Проверка текущего предыдущего элемента
  145.             *
  146.             * element - элемент для проверки
  147.             * return - элемент соответствует критериям?
  148.             */#}
  149.             function elementCheck(element, className) {
  150.                 if (element && !element.classList.contains(className)) {
  151.                     element.classList.add('pagination__item--mobile-active');
  152.                     return true;
  153.                 }
  154.                 return false;
  155.             }
  156.             {#/**
  157.             * Генератор многоточия
  158.             *
  159.             */#}
  160.             function appendDotPagination(element, isNext = false){
  161.                 const liTemp = document.createElement('li');
  162.                 element.parentElement.insertBefore(liTemp, isNext ? element.nextElementSibling :  element.previousElementSibling);
  163.                 //liTemp.outerHTML = dotMarkup;
  164.             }
  165.             {#/**
  166.             * Проверка на необходимости вставки многоточия впереди
  167.             * Если впереди больше 4 элементов - можно вставлять
  168.             *
  169.             */#}
  170.             function checkNextPlace(element) {
  171.                 const countToCheck = 4;
  172.                 let i = 0;
  173.                 for (; i < 4; i++){
  174.                     if (element.nextElementSibling) {
  175.                         element = element.nextElementSibling;
  176.                     } else {
  177.                         break;
  178.                     }
  179.                 }
  180.                 return i === 4
  181.             }
  182.         }
  183.         paginationChecked();
  184.         document.addEventListener('showmore:trigger', paginationChecked.bind())
  185.         document.addEventListener('ajaxLoadEnd', paginationChecked.bind())
  186.     </script>
  187. {% endif %}
  188. </div>