templates/ContentBlock/headerJS.html.twig line 1

Open in your IDE?
  1. <style>
  2.     ._resultsContainerBlink {
  3.         animation: resultsContainerBlinker 1s linear infinite;
  4.     }
  5.     @keyframes resultsContainerBlinker {
  6.         50% {
  7.             opacity: 0.3;
  8.         }
  9.     }
  10. </style>
  11. <script>
  12.     /****************************************************************************************/
  13.     /*                         Content block common JS                                      */
  14.     /****************************************************************************************/
  15.     (function(window, $){
  16.         const resultsContainer = function(elem, options){
  17.             this.elem = elem;
  18.             this.$elem = $(elem);
  19.             this.$elem.data('plugin.resultsContainer', this);
  20.             this.options = options;
  21.             this.cachedPages = {}; // Cache object to store preloaded pages
  22.             this.init();
  23.         };
  24.         resultsContainer.prototype = {
  25.             defaults: {
  26.                 debug: false, // when true, it will set a border to every results container, and highlight it everytime an update/reload action takes place
  27.                 infinite_scroll: false,
  28.                 isSentinel: null, // infinite scroll sentinel
  29.                 observer: null, // infinite scroll observer for sentinel
  30.                 var1: false,
  31.                 var2: []
  32.             },
  33.             init: function(){
  34.                 let _this = this;
  35.                 _this.config = $.extend({}, _this.defaults, _this.options);
  36.                 if(_this.$elem.hasClass('_iscroll'))
  37.                 {
  38.                     _this.config.infinite_scroll = true;
  39.                     if(window.history.state && window.history.state.htmlContent)
  40.                     {
  41.                         _this.$elem.html(window.history.state.htmlContent);
  42.                     }
  43.                     _this.config.$sentinel = $('<div/>').addClass('_scroll_sentinel');
  44.                     let $_sentinel = _this.$elem.find('._scroll_sentinel');
  45.                     if($_sentinel.length)
  46.                     {
  47.                         _this.config.$sentinel = $_sentinel;
  48.                     } else {
  49.                         _this.$elem.append(_this.config.$sentinel);
  50.                     }
  51.                     _this.config.$sentinel.data('isLoading', false);
  52.                     _this.initSentinel();
  53.                     _this.$elem.find('._goTop').on('click', function(e){
  54.                         e.preventDefault();
  55.                         $('html, body').animate({scrollTop: _this.$elem.find('._xlabs_results').offset().top - parseInt(_this.config.pagination.auto_scroll_top)}, 100);
  56.                     });
  57.                 }
  58.                 // Preload first page
  59.                 if(_this.$elem.hasClass('_iload'))
  60.                 {
  61.                     _this.cachedPages[1] = _this.$elem.find('._xlabs_results').html();
  62.                 }
  63.                 // Pagination
  64.                 _this.config.pagination = JSON.parse(_this.$elem.attr('data-pagination'));
  65.                 if(_this.config.pagination.ajax_pagination)
  66.                 {
  67.                     $(document).on('click', '[data-container-id="' + _this.$elem.attr('data-container-id') + '"] ._xlabs_results .pageBtn', function(e){
  68.                         e.preventDefault();
  69.                         let btn = $(this);
  70.                         let results = _this.$elem.resultsContainer();
  71.                         results.setParam('page', btn.attr('data-page'));
  72.                         results.reload(false, function(){
  73.                             if(_this.config.pagination.auto_scroll_top)
  74.                             {
  75.                                 $('html, body').animate({scrollTop: _this.$elem.find('._xlabs_results').offset().top - parseInt(_this.config.pagination.auto_scroll_top)}, 100);
  76.                             }
  77.                             if(_this.config.pagination.ajax_pagination_callback)
  78.                             {
  79.                                 if(typeof _this.config.pagination.ajax_pagination_callback === 'function')
  80.                                 {
  81.                                     _this.config.pagination.ajax_pagination_callback();
  82.                                 }
  83.                             }
  84.                             //_this.preloadNextPage(); // Preload the next page after reloading
  85.                         });
  86.                     });
  87.                     _this.preloadNextPage(); // Preload the next page on initialization
  88.                 }
  89.                 if(this.config.debug)
  90.                 {
  91.                     this.enterDebug();
  92.                 }
  93.                 return this;
  94.             },
  95.             update: function(aParams, _fnCallback = false){ // reload with updated params
  96.                 let _this = this;
  97.                 let container = this.$elem;
  98.                 let config = this.config;
  99.                 this.setParams(aParams);
  100.                 container.css('opacity', '.6');
  101.                 _this.stopSentinel();
  102.                 $.ajax({
  103.                     url: container.attr('data-ajax-path'),
  104.                     data: {
  105.                         aParams: aParams
  106.                     },
  107.                     type: 'post',
  108.                     dataType: 'html',
  109.                     success: function(data){
  110.                         if(_this.config.infinite_scroll)
  111.                         {
  112.                             container.find('._pagination').remove();
  113.                             container.find('._search_totals').remove();
  114.                             container.find('._xlabs_results').append(data);
  115.                             _this.initSentinel();
  116.                             _this.config.$sentinel.data('isLoading', false);
  117.                             //_this.$elem.find('.preloader').remove();
  118.                             _this.$elem.find('.preloader').addClass('d-none');
  119.                             window.history.replaceState({
  120.                                 htmlContent: _this.$elem.html()
  121.                             }, document.title, window.location.href);
  122.                         } else {
  123.                             container.find('._xlabs_results').html(data);
  124.                         }
  125.                         container.css('opacity', '1');
  126.                         if(config.debug)
  127.                         {
  128.                             _this.blink();
  129.                             console.log('Updated ' + aParams['container_id']);
  130.                         }
  131.                         if(typeof _fnCallback == 'function')
  132.                         {
  133.                             _fnCallback();
  134.                         }
  135.                         _this.preloadNextPage(); // Preload the next page after updating
  136.                     },
  137.                     error: function(){
  138.                         container.css('opacity', '1');
  139.                     }
  140.                 });
  141.             },
  142.             reload: function(reset = false, _fnCallback = false){ // keeping current params; when reset true, will use original request params
  143.                 let _this = this;
  144.                 let container = this.$elem;
  145.                 let config = this.config;
  146.                 let aParams = reset ? this.getInitialParams() : this.getParams();
  147.                 container.css('opacity', '.6');
  148.                 _this.stopSentinel();
  149.                 if(_this.cachedPages[aParams.page])
  150.                 {
  151.                     if(_this.config.infinite_scroll)
  152.                     {
  153.                         container.find('._pagination').remove();
  154.                         container.find('._search_totals').remove();
  155.                         container.find('._xlabs_results').append(_this.cachedPages[aParams.page]);
  156.                         _this.initSentinel();
  157.                         _this.config.$sentinel.data('isLoading', false);
  158.                         _this.$elem.find('.preloader').addClass('d-none');
  159.                         _this.$elem.find('._goTop').removeClass('d-none');
  160.                         window.history.replaceState({
  161.                             htmlContent: _this.$elem.html()
  162.                         }, document.title, window.location.href);
  163.                     } else {
  164.                         container.find('._xlabs_results').html(_this.cachedPages[aParams.page]);
  165.                     }
  166.                     container.css('opacity', '1');
  167.                     if(config.debug)
  168.                     {
  169.                         _this.blink();
  170.                         console.log('Reloaded ' + aParams['container_id']);
  171.                     }
  172.                     if(typeof _fnCallback == 'function')
  173.                     {
  174.                         _fnCallback();
  175.                     }
  176.                     //if($(_this.cachedPages[aParams.page]).find('._results_item').length)
  177.                     //{
  178.                         _this.preloadNextPage();
  179.                     //}
  180.                 } else {
  181.                     $.ajax({
  182.                         url: container.attr('data-ajax-path'),
  183.                         data: {
  184.                             aParams: aParams
  185.                         },
  186.                         type: 'post',
  187.                         dataType: 'html',
  188.                         success: function(data){
  189.                             if(_this.config.infinite_scroll)
  190.                             {
  191.                                 container.find('._pagination').remove();
  192.                                 container.find('._search_totals').remove();
  193.                                 container.find('._xlabs_results').append(data);
  194.                                 _this.initSentinel();
  195.                                 _this.config.$sentinel.data('isLoading', false);
  196.                                 _this.$elem.find('.preloader').addClass('d-none');
  197.                                 window.history.replaceState({
  198.                                     htmlContent: _this.$elem.html()
  199.                                 }, document.title, window.location.href);
  200.                             } else {
  201.                                 _this.cachedPages[aParams.page] = data;
  202.                                 container.find('._xlabs_results').html(data);
  203.                             }
  204.                             container.css('opacity', '1');
  205.                             if(config.debug)
  206.                             {
  207.                                 _this.blink();
  208.                                 console.log('Reloaded ' + aParams['container_id']);
  209.                             }
  210.                             if(typeof _fnCallback == 'function')
  211.                             {
  212.                                 _fnCallback();
  213.                             }
  214.                             //if($(data).find('._results_item').length)
  215.                             //{
  216.                                 _this.preloadNextPage();
  217.                             //}
  218.                         },
  219.                         error: function(){
  220.                             container.css('opacity', '1');
  221.                         }
  222.                     });
  223.                 }
  224.             },
  225.             preloadNextPage: function(){
  226.                 let _this = this;
  227.                 let currentParams = _this.getParams();
  228.                 let nextPageParams = $.extend({}, currentParams, {page: parseInt(currentParams.page) + 1});
  229.                 if(_this.cachedPages[nextPageParams.page])
  230.                 {
  231.                     return; // Page is already cached
  232.                 }
  233.                 let nextPageCmd = _this.getNextPageCmd();
  234.                 if(!nextPageCmd.length)
  235.                 {
  236.                     return;
  237.                 }
  238.                 $.ajax({
  239.                     url: _this.$elem.attr('data-ajax-path'),
  240.                     data: {
  241.                         aParams: nextPageParams
  242.                     },
  243.                     type: 'post',
  244.                     dataType: 'html',
  245.                     success: function(data){
  246.                         _this.cachedPages[nextPageParams.page] = data; // Cache the next page content
  247.                     }
  248.                 });
  249.             },
  250.             getInitialParams: function(){
  251.                 return JSON.parse(this.$elem.attr('data-original-params'));
  252.             },
  253.             getParams: function(){
  254.                 return JSON.parse(this.$elem.attr('data-ajax-params'));
  255.             },
  256.             setParams: function(aParams){
  257.                 this.$elem.attr('data-ajax-params', JSON.stringify(aParams));
  258.                 return this;
  259.             },
  260.             getParam: function(param){
  261.                 let params = this.getParams();
  262.                 return params[param];
  263.             },
  264.             setParam: function(param, value){
  265.                 let params = this.getParams();
  266.                 params[param] = value;
  267.                 this.setParams(params);
  268.                 return this;
  269.             },
  270.             removeParam: function(param){
  271.                 let params = this.getParams();
  272.                 delete(params[param]);
  273.                 this.setParams(params);
  274.                 return this;
  275.             },
  276.             clear: function(){
  277.                 let _this = this;
  278.                 _this.$elem.find('._xlabs_results ._results_item').remove();
  279.                 _this.$elem.find('._xlabs_results ._no_results').remove();
  280.             },
  281.             clearCachedPages: function(){
  282.                 let _this = this;
  283.                 _this.cachedPages = {};
  284.             },
  285.             initSentinel: function(){ // for infinite scroll
  286.                 let _this = this;
  287.                 if(_this.config.observer)
  288.                 {
  289.                     _this.config.observer.disconnect();
  290.                 }
  291.                 _this.config.observer = new IntersectionObserver(function(entries) {
  292.                     if(entries[0].isIntersecting)
  293.                     {
  294.                         if(_this.config.$sentinel.data('isLoading')) return;
  295.                         _this.config.$sentinel.data('isLoading', true);
  296.                         let nextPageCmd = _this.getNextPageCmd();
  297.                         let isLastPage = !nextPageCmd.length;
  298.                         if(isLastPage)
  299.                         {
  300.                             _this.config.observer.disconnect();
  301.                             return;
  302.                         }
  303.                         _this.$elem.find('.preloader').removeClass('d-none');
  304.                         setTimeout(function(){
  305.                             nextPageCmd.find('a').click();
  306.                         }, 0);
  307.                     }
  308.                 });
  309.                 // Start observing the sentinel element
  310.                 _this.config.observer.observe(_this.config.$sentinel[0]);
  311.             },
  312.             stopSentinel: function(){
  313.                 let _this = this;
  314.                 if(_this.config.observer)
  315.                 {
  316.                     _this.config.observer.disconnect();
  317.                 }
  318.             },
  319.             resetInfiniteScroll: function(){ // required when infinite scroll results have to be reset
  320.                 let _this = this;
  321.                 let container = this.$elem;
  322.                 _this.clear();
  323.                 _this.clearCachedPages();
  324.                 container.find('._results').remove();
  325.             },
  326.             getNextPageCmd: function(){
  327.                 let _this = this;
  328.                 let paginationCmds = _this.$elem.find('.page-item');
  329.                 let currentPageCmd = _this.$elem.find('.page-item.active');
  330.                 let currentPageIndex = paginationCmds.index(currentPageCmd);
  331.                 return paginationCmds.eq(currentPageIndex + 1);
  332.             },
  333.             enterDebug: function(){ // this function can be removed; it´s just to visually check that the plugin is being executed for a container
  334.                 console.log('resultsContainer initialized for container ' + this.$elem.attr('data-container-id'));
  335.                 this.$elem.css({
  336.                     'border': '1px solid #2196F3'
  337.                 });
  338.             },
  339.             blink: function(){ // debug purposes
  340.                 let container = this.$elem;
  341.                 //container.fadeOut(250).fadeIn(250).fadeOut(250).fadeIn(250);
  342.                 container.addClass('_resultsContainerBlink');
  343.                 setTimeout(function()
  344.                 {
  345.                     container.removeClass('_resultsContainerBlink');
  346.                 }, 1000);
  347.             }
  348.         };
  349.         resultsContainer.defaults = resultsContainer.prototype.defaults;
  350.         $.fn.resultsContainer = function(options = {}) {
  351.             //return $(this).data('plugin.resultsContainer') ? $(this).data('plugin.resultsContainer') : new resultsContainer(this, options);
  352.             return $(this).data('plugin.resultsContainer') ? $(this).data('plugin.resultsContainer') : this.each(function(){
  353.                 $(this).data('plugin.resultsContainer') ? $(this).data('plugin.resultsContainer') : new resultsContainer(this, options);
  354.             });
  355.         };
  356.         window.resultsContainer = resultsContainer;
  357.     })(window, jQuery);
  358.     $(document).ready(function(){
  359.         $('._xlabs_results_wrapper').resultsContainer();
  360.     });
  361.     function updateContentBlockResults(aParams_container, updated_aParams)
  362.     {
  363.         aParams_container.resultsContainer().update(updated_aParams);
  364.     }
  365. </script>