File: development/modules/pagination/js/pagination.js
import $ from 'jquery';
import {isNumber} from '../../../js/utils/type';
import {eventType} from '../../../js/utils/events';
import DOMModule from '../../__base/dommodule';
class Pagination extends DOMModule {
constructor(options) {
super(options);
this.$nextBtn = this.$findChilds('[data-pagination-cmd="next"]');
this.$prevBtn = this.$findChilds('[data-pagination-cmd="prev"]');
this.$input = this.$findChilds('.pagination-input');
this.$pageCountNode = this.$findChilds('[data-pagination-counter]');
}
/**
* Creates a new Pagination instance without the "new" keyword but does not
* initialize it
* @method of
* @static
* @for Modules.Pagination
* @param {node|string|configs} node Node, CSS selector or configuration object
* @return {Pagination} A new instance
*
* @example
* import Pagination from './modules/pagination/js/pagination';
*
* const myPagination = Pagination.of('[data-widget=Pagination]');
* myPagination.render().startUp();
*/
static of (node) {
return new Pagination(node);
}
/**
* Finds and initializes all Paginations on a page at once
* @method findAll
* @static
* @for Modules.Pagination
* @param {string} selector CSS selector to match nodes against
* @return {array} A list of instances
*
* @example
* import Pagination from './modules/pagination/js/pagination';
*
* Pagination.findAll('[data-widget=Pagination]');
*/
static findAll(selector) {
return $(selector).toArray().filter((node) => {
return !$(node).data('defer');
}).map((node) => {
const pagination = Pagination.of(node);
pagination.render().startUp();
return pagination;
});
}
render() {
var count = parseInt(this.$pageCountNode.html(), 10),
desire = parseInt(this.$input.val(), 10)
this.pageCount = isNumber(count) ? count : 1;
this.desiredPage = this.currentPage = isNumber(desire) ? desire : 1;
this._updateButtons();
this._updateInput();
return this;
}
startUp() {
this.$nextBtn.on(eventType.CLICK, this._handleNextClick.bind(this));
this.$prevBtn.on(eventType.CLICK, this._handlePrevClick.bind(this));
this.$input.on(eventType.INPUT, this._handleInputChange.bind(this));
this.$input.on(eventType.FOCUSOUT, this._handleFocusOut.bind(this));
}
changed () {
this.setCurrentPage(this.desiredPage);
this.notifyObservers({
page: this.desiredPage
})
}
/* Event Listeners
==================== */
_handlePrevClick(evt){
if (this.desiredPage > 1){
this.desiredPage -= 1;
this.changed();
}
evt.preventDefault();
}
_handleNextClick(evt){
if (this.desiredPage <= this.pageCount-1){
this.desiredPage += 1;
this.changed();
}
evt.preventDefault();
}
_handleInputChange(evt){
var $target = $(evt.currentTarget);
var inputVal = $target.val();
if (inputVal.length > 0) {
if ($.isNumeric(inputVal)){
inputVal = parseInt(inputVal, 10);
if (inputVal > this.pageCount) {
this.desiredPage = this.pageCount;
} else if (inputVal <= 0) {
this.desiredPage = 1;
} else {
this.desiredPage = inputVal;
}
} else {
this.desiredPage = this.currentPage
}
$target.val(this.desiredPage);
this.changed();
} else {
this.desiredPage = this.currentPage
this.changed();
}
evt.preventDefault();
}
_handleFocusOut(evt){
var $target = $(evt.currentTarget);
if ($target.val().length === 0) {
this.desiredPage = this.currentPage;
$target.val(this.desiredPage);
this.changed();
}
}
/* Getters and Setters
==================== */
getDesiredPage(){
return this.desiredPage;
}
setCurrentPage(newPage){
this.currentPage = this.desiredPage = parseInt(newPage, 10);
this.$input.val(this.currentPage);
this._updateButtons();
}
setPageCount(pageCount){
this.pageCount = parseInt(pageCount,10);
this.$pageCountNode.html(this.pageCount);
this._updateInput();
this._updateButtons();
}
/* Internal helpers
==================== */
_updateButtons(){
if (this.currentPage === 1) {
this._disableButton(this.$prevBtn);
} else {
this._enableButton(this.$prevBtn);
}
if (this.currentPage === this.pageCount) {
this._disableButton(this.$nextBtn);
} else {
this._enableButton(this.$nextBtn);
}
}
_disableButton($btn){
$btn.addClass('m-disabled');
$btn.prop('disabled', true);
}
_enableButton($btn){
$btn.removeClass('m-disabled');
$btn.prop('disabled', null);
}
_updateInput(){
if (this.pageCount === 1) {
this.$input.prop('disabled', true);
} else {
this.$input.prop('disabled', null);
}
}
}
export default Pagination;