<style>
._resultsContainerBlink {
animation: resultsContainerBlinker 1s linear infinite;
}
@keyframes resultsContainerBlinker {
50% {
opacity: 0.3;
}
}
</style>
<script>
/****************************************************************************************/
/* Content block common JS */
/****************************************************************************************/
(function(window, $){
const resultsContainer = function(elem, options){
this.elem = elem;
this.$elem = $(elem);
this.$elem.data('plugin.resultsContainer', this);
this.options = options;
this.cachedPages = {}; // Cache object to store preloaded pages
this.init();
};
resultsContainer.prototype = {
defaults: {
debug: false, // when true, it will set a border to every results container, and highlight it everytime an update/reload action takes place
infinite_scroll: false,
isSentinel: null, // infinite scroll sentinel
observer: null, // infinite scroll observer for sentinel
var1: false,
var2: []
},
init: function(){
let _this = this;
_this.config = $.extend({}, _this.defaults, _this.options);
if(_this.$elem.hasClass('_iscroll'))
{
_this.config.infinite_scroll = true;
if(window.history.state && window.history.state.htmlContent)
{
_this.$elem.html(window.history.state.htmlContent);
}
_this.config.$sentinel = $('<div/>').addClass('_scroll_sentinel');
let $_sentinel = _this.$elem.find('._scroll_sentinel');
if($_sentinel.length)
{
_this.config.$sentinel = $_sentinel;
} else {
_this.$elem.append(_this.config.$sentinel);
}
_this.config.$sentinel.data('isLoading', false);
_this.initSentinel();
_this.$elem.find('._goTop').on('click', function(e){
e.preventDefault();
$('html, body').animate({scrollTop: _this.$elem.find('._xlabs_results').offset().top - parseInt(_this.config.pagination.auto_scroll_top)}, 100);
});
}
// Preload first page
if(_this.$elem.hasClass('_iload'))
{
_this.cachedPages[1] = _this.$elem.find('._xlabs_results').html();
}
// Pagination
_this.config.pagination = JSON.parse(_this.$elem.attr('data-pagination'));
if(_this.config.pagination.ajax_pagination)
{
$(document).on('click', '[data-container-id="' + _this.$elem.attr('data-container-id') + '"] ._xlabs_results .pageBtn', function(e){
e.preventDefault();
let btn = $(this);
let results = _this.$elem.resultsContainer();
results.setParam('page', btn.attr('data-page'));
results.reload(false, function(){
if(_this.config.pagination.auto_scroll_top)
{
$('html, body').animate({scrollTop: _this.$elem.find('._xlabs_results').offset().top - parseInt(_this.config.pagination.auto_scroll_top)}, 100);
}
if(_this.config.pagination.ajax_pagination_callback)
{
if(typeof _this.config.pagination.ajax_pagination_callback === 'function')
{
_this.config.pagination.ajax_pagination_callback();
}
}
//_this.preloadNextPage(); // Preload the next page after reloading
});
});
_this.preloadNextPage(); // Preload the next page on initialization
}
if(this.config.debug)
{
this.enterDebug();
}
return this;
},
update: function(aParams, _fnCallback = false){ // reload with updated params
let _this = this;
let container = this.$elem;
let config = this.config;
this.setParams(aParams);
container.css('opacity', '.6');
_this.stopSentinel();
$.ajax({
url: container.attr('data-ajax-path'),
data: {
aParams: aParams
},
type: 'post',
dataType: 'html',
success: function(data){
if(_this.config.infinite_scroll)
{
container.find('._pagination').remove();
container.find('._search_totals').remove();
container.find('._xlabs_results').append(data);
_this.initSentinel();
_this.config.$sentinel.data('isLoading', false);
//_this.$elem.find('.preloader').remove();
_this.$elem.find('.preloader').addClass('d-none');
window.history.replaceState({
htmlContent: _this.$elem.html()
}, document.title, window.location.href);
} else {
container.find('._xlabs_results').html(data);
}
container.css('opacity', '1');
if(config.debug)
{
_this.blink();
console.log('Updated ' + aParams['container_id']);
}
if(typeof _fnCallback == 'function')
{
_fnCallback();
}
_this.preloadNextPage(); // Preload the next page after updating
},
error: function(){
container.css('opacity', '1');
}
});
},
reload: function(reset = false, _fnCallback = false){ // keeping current params; when reset true, will use original request params
let _this = this;
let container = this.$elem;
let config = this.config;
let aParams = reset ? this.getInitialParams() : this.getParams();
container.css('opacity', '.6');
_this.stopSentinel();
if(_this.cachedPages[aParams.page])
{
if(_this.config.infinite_scroll)
{
container.find('._pagination').remove();
container.find('._search_totals').remove();
container.find('._xlabs_results').append(_this.cachedPages[aParams.page]);
_this.initSentinel();
_this.config.$sentinel.data('isLoading', false);
_this.$elem.find('.preloader').addClass('d-none');
_this.$elem.find('._goTop').removeClass('d-none');
window.history.replaceState({
htmlContent: _this.$elem.html()
}, document.title, window.location.href);
} else {
container.find('._xlabs_results').html(_this.cachedPages[aParams.page]);
}
container.css('opacity', '1');
if(config.debug)
{
_this.blink();
console.log('Reloaded ' + aParams['container_id']);
}
if(typeof _fnCallback == 'function')
{
_fnCallback();
}
//if($(_this.cachedPages[aParams.page]).find('._results_item').length)
//{
_this.preloadNextPage();
//}
} else {
$.ajax({
url: container.attr('data-ajax-path'),
data: {
aParams: aParams
},
type: 'post',
dataType: 'html',
success: function(data){
if(_this.config.infinite_scroll)
{
container.find('._pagination').remove();
container.find('._search_totals').remove();
container.find('._xlabs_results').append(data);
_this.initSentinel();
_this.config.$sentinel.data('isLoading', false);
_this.$elem.find('.preloader').addClass('d-none');
window.history.replaceState({
htmlContent: _this.$elem.html()
}, document.title, window.location.href);
} else {
_this.cachedPages[aParams.page] = data;
container.find('._xlabs_results').html(data);
}
container.css('opacity', '1');
if(config.debug)
{
_this.blink();
console.log('Reloaded ' + aParams['container_id']);
}
if(typeof _fnCallback == 'function')
{
_fnCallback();
}
//if($(data).find('._results_item').length)
//{
_this.preloadNextPage();
//}
},
error: function(){
container.css('opacity', '1');
}
});
}
},
preloadNextPage: function(){
let _this = this;
let currentParams = _this.getParams();
let nextPageParams = $.extend({}, currentParams, {page: parseInt(currentParams.page) + 1});
if(_this.cachedPages[nextPageParams.page])
{
return; // Page is already cached
}
let nextPageCmd = _this.getNextPageCmd();
if(!nextPageCmd.length)
{
return;
}
$.ajax({
url: _this.$elem.attr('data-ajax-path'),
data: {
aParams: nextPageParams
},
type: 'post',
dataType: 'html',
success: function(data){
_this.cachedPages[nextPageParams.page] = data; // Cache the next page content
}
});
},
getInitialParams: function(){
return JSON.parse(this.$elem.attr('data-original-params'));
},
getParams: function(){
return JSON.parse(this.$elem.attr('data-ajax-params'));
},
setParams: function(aParams){
this.$elem.attr('data-ajax-params', JSON.stringify(aParams));
return this;
},
getParam: function(param){
let params = this.getParams();
return params[param];
},
setParam: function(param, value){
let params = this.getParams();
params[param] = value;
this.setParams(params);
return this;
},
removeParam: function(param){
let params = this.getParams();
delete(params[param]);
this.setParams(params);
return this;
},
clear: function(){
let _this = this;
_this.$elem.find('._xlabs_results ._results_item').remove();
_this.$elem.find('._xlabs_results ._no_results').remove();
},
clearCachedPages: function(){
let _this = this;
_this.cachedPages = {};
},
initSentinel: function(){ // for infinite scroll
let _this = this;
if(_this.config.observer)
{
_this.config.observer.disconnect();
}
_this.config.observer = new IntersectionObserver(function(entries) {
if(entries[0].isIntersecting)
{
if(_this.config.$sentinel.data('isLoading')) return;
_this.config.$sentinel.data('isLoading', true);
let nextPageCmd = _this.getNextPageCmd();
let isLastPage = !nextPageCmd.length;
if(isLastPage)
{
_this.config.observer.disconnect();
return;
}
_this.$elem.find('.preloader').removeClass('d-none');
setTimeout(function(){
nextPageCmd.find('a').click();
}, 0);
}
});
// Start observing the sentinel element
_this.config.observer.observe(_this.config.$sentinel[0]);
},
stopSentinel: function(){
let _this = this;
if(_this.config.observer)
{
_this.config.observer.disconnect();
}
},
resetInfiniteScroll: function(){ // required when infinite scroll results have to be reset
let _this = this;
let container = this.$elem;
_this.clear();
_this.clearCachedPages();
container.find('._results').remove();
},
getNextPageCmd: function(){
let _this = this;
let paginationCmds = _this.$elem.find('.page-item');
let currentPageCmd = _this.$elem.find('.page-item.active');
let currentPageIndex = paginationCmds.index(currentPageCmd);
return paginationCmds.eq(currentPageIndex + 1);
},
enterDebug: function(){ // this function can be removed; it´s just to visually check that the plugin is being executed for a container
console.log('resultsContainer initialized for container ' + this.$elem.attr('data-container-id'));
this.$elem.css({
'border': '1px solid #2196F3'
});
},
blink: function(){ // debug purposes
let container = this.$elem;
//container.fadeOut(250).fadeIn(250).fadeOut(250).fadeIn(250);
container.addClass('_resultsContainerBlink');
setTimeout(function()
{
container.removeClass('_resultsContainerBlink');
}, 1000);
}
};
resultsContainer.defaults = resultsContainer.prototype.defaults;
$.fn.resultsContainer = function(options = {}) {
//return $(this).data('plugin.resultsContainer') ? $(this).data('plugin.resultsContainer') : new resultsContainer(this, options);
return $(this).data('plugin.resultsContainer') ? $(this).data('plugin.resultsContainer') : this.each(function(){
$(this).data('plugin.resultsContainer') ? $(this).data('plugin.resultsContainer') : new resultsContainer(this, options);
});
};
window.resultsContainer = resultsContainer;
})(window, jQuery);
$(document).ready(function(){
$('._xlabs_results_wrapper').resultsContainer();
});
function updateContentBlockResults(aParams_container, updated_aParams)
{
aParams_container.resultsContainer().update(updated_aParams);
}
</script>