salix/front/core/components/pagination/pagination.js

104 lines
2.9 KiB
JavaScript

import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss';
/**
* Pagination component that automatically loads more rows when
* the user scrolls down an element.
*
* @property {Paginable} model The model used for pagination
* @property {String} scrollSelector The the scrollable element selector
* @property {HTMLElement} scrollElement The scrollable element
* @property {Number} scrollOffset The distance, in pixels, until the end that activates the loading of the next rows
* @property {Number} maxLoads The maximum of loads that are automatically performed on scroll, 0 for no limit
*/
class Pagination extends Component {
constructor($element, $scope) {
super($element, $scope);
this.scrollOffset = 500;
this.maxLoads = 5;
this.nLoads = 0;
this.scrollHandler = e => this.onScroll(e);
}
$onInit() {
if (!this._scrollElement)
this.scrollElement = window;
}
set scrollSelector(value) {
this._scrollSelector = value;
this.scrollElement = document.querySelector(value);
}
get scrollSelector() {
return this._scrollSelector;
}
set scrollElement(value) {
if (this._scrollElement)
this._scrollElement.removeEventListener('scroll', this.scrollHandler);
this._scrollElement = value;
if (value)
this._scrollElement.addEventListener('scroll', this.scrollHandler);
}
get scrollElement() {
return this._scrollElement;
}
onScroll() {
let scrollInfo;
let scrollElement = this.scrollElement;
if (scrollElement == window) {
scrollInfo = {
top: window.pageYOffset,
height: window.innerHeight,
position: window.document.body.scrollHeight
};
} else {
scrollInfo = {
top: scrollElement.scrollTop,
height: scrollElement.clientHeight,
position: scrollElement.scrollHeight
};
}
let shouldLoad = scrollInfo.top + scrollInfo.height >= (scrollInfo.position - this.scrollOffset)
&& !this.model.isLoading
&& (this.maxLoads <= 0 || this.nLoads < this.maxLoads);
if (shouldLoad) {
this.nLoads++;
this.model.loadMore();
this.$.$apply();
}
}
onLoadClick() {
if (this.maxLoads > 0 && this.nLoads == this.maxLoads)
this.nLoads = 0;
this.model.loadMore();
}
$onDestroy() {
this.scrollElement = null;
}
}
ngModule.component('vnPagination', {
template: require('./pagination.html'),
bindings: {
model: '<',
scrollSelector: '@?',
scrollElement: '<?',
scrollOffset: '<?',
maxLoads: '<?'
},
controller: Pagination
});