import jQ from 'jquery';
import ProductPagination from "./product-pagination";
import FilterApi from "../../../../../api/filter-api";
import Selector from "../../../../../helpers/selector";
import Class from "../../../../../helpers/class";
import Globals from "../../../../../helpers/globals";
import Settings from "../../../../../helpers/settings";
import Utils from "../../../../../helpers/utils";
import BoostPFS from "../../../../../boost-pfs";
import SearchResultPanels from '../search-result-panels';
import SearchResultPanelItem from '../search-result-panel-item';
/**
* Product pagination - load more
* @extends ProductPagination
*/
class ProductPaginationInfinite extends ProductPagination {
/**
* @constructs
*/
constructor() {
super();
this.$element = jQ(Selector.bottomPagination);
// Add more settings
jQ.extend(this.settings, {
positionShowInfiniteLoading: Settings.getSettingValue('general.positionShowInfiniteLoading'),
sessionStorageCurrentNextPage: Settings.getSettingValue('general.sessionStorageCurrentNextPage'),
sessionStoragePreviousPageEvent: Settings.getSettingValue('general.sessionStoragePreviousPageEvent')
});
}
/**
* Get te raw HTML template for pagination - infinite loading
* @param {String} tempType
*/
getTemplate() {
return `
<div class="{{class.productLoadMore}}-loading" style="display: none;">
<div class="{{class.productLoadMore}}-icon"></div>
</div>
`;
}
/**
* Replace the brackets in raw html template with proper values for infinite loading
* @returns {String} HTML string
*/
compileTemplate() {
return this.getTemplate()
.replace(/{{class.productLoadMore}}/g, Class.productLoadMore);
}
/**
* Return whether or not the pagination - infinite loading is rendered
*/
isRender() {
return this.data !== null && SearchResultPanels.isPanelActive(SearchResultPanelItem.Enum.PRODUCT);
}
/**
* Render the pagination - infinite loading
*/
render() {
// Blank the default pagination
this.$element.empty();
// Show the pagination block
this.$element.show();
// Add loading element
if (this.$loadMore.find(Selector.loadMoreLoading).length == 0) {
var loadingHtml = this.compileTemplate();
this.$loadMore.prepend(loadingHtml);
this.$loadMore.show();
}
// hide loading
this.hideLoading();
}
/**
* Bind the event on infinite loading
*/
bindEvents() {
// Previous page data
if (Utils.isLoadPreviousPagePaginationType()) {
this.nextPage = parseInt(window.sessionStorage.getItem(this.settings.sessionStorageCurrentNextPage));
} else {
this.nextPage = Globals.queryParams.page;
}
// Check if total products is greater than limit per page * curent page,
// do the infinite loading function, else do nothing
if (this.totalProduct > (this.settings.limit * this.nextPage)) {
// Using scrolling to prevent callling onscroll twice
this.scrolling = false;
// Onscroll event, when windown reaches the bottom of product list
this.scrollToBottom = false;
// Check if pagination exists, do the infinite function
if (this.$element.length > 0) {
// When scroll down, do the infinite function
jQ(window).on('scroll', this._onScrollEvent.bind(this));
}
}
}
/**
* Bind the scroll event on Window to load more product
* @param {Object} event - DOM event
*/
_onScrollEvent(event) {
event.preventDefault();
event.stopPropagation();
// Ignore load more if the product list is loading
if (jQ(Selector.products).hasClass(Class.productWrapLoading) || !SearchResultPanels.isPanelActive(SearchResultPanelItem.Enum.PRODUCT)) return false;
if (this._isScrollToBottom()) {
this._loadMoreProducts();
}
}
_isScrollToBottom() {
// get height of scroll bar
var scrollbarHeight = jQ(window).height() * (jQ(window).height() / jQ(document).outerHeight());
// get position of the pagination bottom
var maxPos = parseInt(this.$element.offset().top);
var maxScroll = parseInt(jQ(window).scrollTop()) + scrollbarHeight + parseInt(this.settings.positionShowInfiniteLoading);
if ((jQ(window).scrollTop() + jQ(window).height() + scrollbarHeight) >= jQ(document).outerHeight() - 100) {
this.scrollToBottom = true;
}
// Return true if scroll to the end of product list
return (!this.scrolling && this.data.products.length > 0) && (maxScroll >= maxPos || (maxScroll < maxPos && this.scrollToBottom));
}
_loadMoreProducts() {
// Show Loading
this.showLoading();
// Prevent scrolling twice
this.scrolling = true;
// Next page
this.nextPage++;
// Send request if current page is smaller or equal to total number of pages
var totalPage = Math.ceil(this.totalProduct / this.settings.limit);
if (this.nextPage <= totalPage) {
Globals.internalClick = true;
// Set limit param
FilterApi.setParam('limit', this.settings.limit);
// Set new page param
FilterApi.setParam('page', this.nextPage);
if (Utils.FilterResult.isAdvancedPaginationType()) {
// If the previous page feature is activated
if (Utils.isLoadPreviousPagePaginationType()) {
// Save the previous page data
window.sessionStorage.setItem(this.settings.sessionStorageCurrentNextPage, this.nextPage);
window.sessionStorage.setItem(this.settings.sessionStoragePreviousPageEvent, 0);
}
// Apply filter with new navigation url
FilterApi.applyFilter('page');
} else {
// Apply filter without new navigation url
var filter = BoostPFS.instance.filter;
FilterApi.getFilterData('page', filter.setData.bind(filter));
}
}
}
}
export default ProductPaginationInfinite;