/**
* @file js/classes/features/PagingFeature.js
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PagingFeature
* @ingroup js_classes_features
*
* @brief Feature that implements paging on grids.
*/
(function($) {
/**
* @constructor
* @inheritDoc
* @extends $.pkp.classes.features.GeneralPagingFeature
*/
$.pkp.classes.features.PagingFeature =
function(gridHandler, options) {
this.parent(gridHandler, options);
};
$.pkp.classes.Helper.inherits(
$.pkp.classes.features.PagingFeature,
$.pkp.classes.features.GeneralPagingFeature);
/**
* @inheritDoc
*/
$.pkp.classes.features.PagingFeature.prototype.init =
function() {
this.configPagingLinks_();
this.configItemsPerPageElement_();
};
/**
* @inheritDoc
*/
$.pkp.classes.features.PagingFeature.prototype.addFeatureHtml =
function($gridElement, options) {
$gridElement.append(options.pagingMarkup);
};
//
// Hooks implementation.
//
/**
* @inheritDoc
*/
$.pkp.classes.features.PagingFeature.prototype.resequenceRows =
function(sequenceMap) {
var $rows = this.gridHandler.getRows(),
extraRowsNum, index,
options = this.getOptions();
// Clean any extra rows that might still be visible from old range data.
extraRowsNum = $rows.length - options.currentItemsPerPage;
if (extraRowsNum > 0) {
for (index = 0; index < extraRowsNum; index++) {
this.gridHandler.deleteElement($rows.first(), true);
}
}
return false;
};
/**
* @inheritDoc
*/
$.pkp.classes.features.PagingFeature.prototype.refreshGrid =
function(opt_elementId) {
var options = this.getOptions(), params, $firstRow, $lastRow;
params = this.gridHandler.getFetchExtraParams();
params[options.pageParamName] = options.currentPage;
params[options.itemsPerPageParamName] = options.currentItemsPerPage;
$firstRow = this.gridHandler.getRows().first();
$lastRow = this.gridHandler.getRows().last();
if ($firstRow.length == 0) {
params.topLimitRowId = 0;
} else {
params.topLimitRowId = this.gridHandler.getRowDataId($firstRow);
}
if ($lastRow.length == 0) {
params.bottomLimitRowId = 0;
} else {
params.bottomLimitRowId = this.gridHandler.getRowDataId($lastRow);
}
this.setGridParams(params);
return false;
};
/**
* @inheritDoc
*/
$.pkp.classes.features.PagingFeature.prototype.replaceElementResponseHandler =
function(handledJsonData) {
var rowMarkup, rowDataId, pagingInfo, options, $rows, castJsonData;
options = this.getOptions();
castJsonData = /** @type {{deletedRowReplacement: string,
pagingInfo: string,
loadLastPage: boolean,
newTopRow: string}} */
(handledJsonData);
if (castJsonData.deletedRowReplacement != undefined) {
rowMarkup = handledJsonData.deletedRowReplacement;
this.gridHandler.insertOrReplaceElement(rowMarkup);
}
if (castJsonData.pagingInfo != undefined) {
pagingInfo = handledJsonData.pagingInfo;
this.setOptions(pagingInfo);
this.gridHandler.replacePartialWith(pagingInfo.pagingMarkup,
$('div.gridPaging', this.getGridHtmlElement()));
this.init();
}
if (castJsonData.loadLastPage) {
this.getGridHtmlElement().trigger('dataChanged');
}
if (castJsonData.newTopRow != undefined) {
// Check if we need to remove one row from the bottom
// to keep the same range info count value.
$rows = this.gridHandler.getRows();
if (options.currentItemsPerPage == $rows.length) {
this.gridHandler.deleteElement($rows.last(), true);
}
rowMarkup = handledJsonData.newTopRow;
this.gridHandler.insertOrReplaceElement(rowMarkup, true);
}
return false;
};
//
// Private helper methods.
//
/**
* Configure paging links.
*
* @private
*/
$.pkp.classes.features.PagingFeature.prototype.configPagingLinks_ =
function() {
var options, $pagingDiv, $links, index, limit, $link, regex, match,
clickPagesCallback;
options = this.getOptions();
$pagingDiv = $('div.gridPaging', this.getGridHtmlElement());
if ($pagingDiv) {
clickPagesCallback = this.callbackWrapper(
function(sourceElement, event) {
regex = new RegExp('[?&]' + options.pageParamName +
'(?:=([^&]*))?', 'i');
match = regex.exec($(event.target).attr('href'));
if (match != null) {
options.currentPage = parseInt(match[1], 10);
this.getGridHtmlElement().trigger('dataChanged');
}
// Stop event handling.
return false;
}, this);
$links = $pagingDiv.find('a').
not('.showMoreItems').not('.showLessItems');
for (index = 0, limit = $links.length; index < limit; index++) {
$link = $($links[index]);
$link.click(clickPagesCallback);
}
}
};
/**
* Configure items per page element.
*
* @private
*/
$.pkp.classes.features.PagingFeature.prototype.configItemsPerPageElement_ =
function() {
var options, $pagingDiv, index, limit, $select, itemsPerPageValues,
changeItemsPerPageCallback;
options = this.getOptions();
$pagingDiv = $('div.gridPaging', this.getGridHtmlElement());
if ($pagingDiv) {
changeItemsPerPageCallback = this.callbackWrapper(
function(sourceElement, event) {
options.currentItemsPerPage = parseInt($('option',
event.target).filter(':selected').attr('value'), 10);
// Reset to first page.
options.currentPage = 1;
this.getGridHtmlElement().trigger('dataChanged');
// Stop event handling.
return false;
}, this);
$select = $pagingDiv.find('select.itemsPerPage');
itemsPerPageValues = [10, 25, 50, 75, 100];
if ($.inArray(options.defaultItemsPerPage,
itemsPerPageValues) < 0) {
itemsPerPageValues.push(options.defaultItemsPerPage);
}
itemsPerPageValues.sort(function(a, b) { return a - b; });
if (options.itemsTotal <= itemsPerPageValues[0]) {
$('div.gridItemsPerPage', $pagingDiv).hide();
} else {
limit = itemsPerPageValues.length - 1;
for (index = 0; index <= limit; index++) {
$select.append($('<option value="' + itemsPerPageValues[index] +
'">' + itemsPerPageValues[index] + '</option>'));
}
$select.val(options.currentItemsPerPage.toString());
$select.change(changeItemsPerPageCallback);
}
}
};
}(jQuery));
|