first commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @file js/classes/features/CollapsibleGridFeature.js
|
||||
*
|
||||
* Copyright (c) 2016-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 CollapsibleGridFeature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Adds collapse/expand functionality to grids.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @inheritDoc
|
||||
* @extends $.pkp.classes.features.Feature
|
||||
*/
|
||||
$.pkp.classes.features.CollapsibleGridFeature =
|
||||
function(gridHandler, options) {
|
||||
this.parent(gridHandler, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.classes.features.CollapsibleGridFeature,
|
||||
$.pkp.classes.features.Feature);
|
||||
|
||||
|
||||
//
|
||||
// Getter and setters.
|
||||
//
|
||||
/**
|
||||
* Get the collapse/expand control link selector.
|
||||
* @return {string}
|
||||
*/
|
||||
$.pkp.classes.features.CollapsibleGridFeature.prototype.getControlSelector =
|
||||
function() {
|
||||
return "a[id^='collapsibleGridControl-expandGridControlLink-button-']";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.CollapsibleGridFeature.prototype.init =
|
||||
function() {
|
||||
$(this.getControlSelector(), this.getGridHtmlElement()).
|
||||
click(this.callbackWrapper(this.toggleGridClickHandler_, this));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.CollapsibleGridFeature.prototype.
|
||||
addFeatureHtml = function($gridElement, options) {
|
||||
var castOptions = /** @type {{collapsibleLink: string?}} */ (options);
|
||||
$gridElement.find('div.grid_header_bar').prepend(castOptions.collapsibleLink);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Collapse/expand grid.
|
||||
* @private
|
||||
* @param {Object} callingContext The calling element or object.
|
||||
* @param {Event=} opt_event The triggering event.
|
||||
* @return {boolean} Should return false to stop event processing.
|
||||
*/
|
||||
$.pkp.classes.features.CollapsibleGridFeature.prototype.
|
||||
toggleGridClickHandler_ = function(callingContext, opt_event) {
|
||||
var $control = this.getGridHtmlElement().find(this.getControlSelector());
|
||||
|
||||
this.getGridHtmlElement().find('div.grid_header').siblings().toggle();
|
||||
$control.toggleClass('expand_all').toggleClass('collapse_all');
|
||||
|
||||
// Hide the search controls, if they are visible.
|
||||
this.getGridHtmlElement().
|
||||
find('div.grid_header_bar .search_extras_collapse').click();
|
||||
|
||||
// Toggle all grid actions.
|
||||
this.getGridHtmlElement().find('div.grid_header span.options').toggle();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* @defgroup js_classes_features
|
||||
*/
|
||||
/**
|
||||
* @file js/classes/features/Feature.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 Feature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Base grid feature class.
|
||||
* @see lib/pkp/classes/controllers/grid/feature/GridFeature.php
|
||||
*
|
||||
* We use the features concept of the ext js framework:
|
||||
* http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.feature.Feature
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.classes.features = $.pkp.classes.features || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends $.pkp.classes.ObjectProxy
|
||||
* @param {$.pkp.controllers.grid.GridHandler} gridHandler The grid
|
||||
* handler object.
|
||||
* @param {Array} options Associated options.
|
||||
*/
|
||||
$.pkp.classes.features.Feature =
|
||||
function(gridHandler, options) {
|
||||
this.gridHandler = gridHandler;
|
||||
this.options_ = options;
|
||||
this.addFeatureHtml(this.getGridHtmlElement(), options);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Protected properties.
|
||||
//
|
||||
/**
|
||||
* The grid that this feature is attached to.
|
||||
* @protected
|
||||
* @type {$.pkp.controllers.grid.GridHandler}
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.gridHandler = null;
|
||||
|
||||
|
||||
//
|
||||
// Private properties.
|
||||
//
|
||||
/**
|
||||
* This feature configuration options.
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.options_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Setters and getters.
|
||||
//
|
||||
/**
|
||||
* @param {Object} options The feature options.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.setOptions =
|
||||
function(options) {
|
||||
this.options_ = options;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Object} The feature options.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.getOptions =
|
||||
function() {
|
||||
return this.options_;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Public template methods.
|
||||
//
|
||||
/**
|
||||
* Initialize this feature. Needs to be extended to implement
|
||||
* specific initialization. This method will always be called
|
||||
* by the components that this feature is attached to, in the
|
||||
* moment of the attachment.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.init =
|
||||
function() {
|
||||
throw new Error('Abstract method!');
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Template methods (hooks into grid widgets).
|
||||
//
|
||||
/**
|
||||
* Hook into the add new element grid functionality.
|
||||
* @param {jQueryObject} $newElement The new element to be added.
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.addElement =
|
||||
function($newElement) {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hook into the replace element content grid functionality.
|
||||
* @param {jQueryObject} $newContent The element new content to be shown.
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.replaceElement =
|
||||
function($newContent) {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hook into the resequence rows grid functionality.
|
||||
* @param {Object} sequenceMap The grid rows sequence.
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.resequenceRows =
|
||||
function(sequenceMap) {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hook into the refresh grid functionality. Called just before
|
||||
* the fetch (grid or row) call is done.
|
||||
* @param {number|Object=} opt_elementId
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.refreshGrid =
|
||||
function(opt_elementId) {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hook into the replace element response handler. Called after the
|
||||
* response is handled.
|
||||
* @param {Object} handledJsonData Object with the response content handled
|
||||
* by the grid.
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.replaceElementResponseHandler =
|
||||
function(handledJsonData) {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
/**
|
||||
* Use the grid handler object and call the
|
||||
* callback wrapper method there.
|
||||
* @see $.pkp.classes.Handler.callbackWrapper()
|
||||
* @return {Function} Callback function.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.callbackWrapper =
|
||||
function(callback, opt_context) {
|
||||
return this.gridHandler.callbackWrapper(callback, opt_context);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Extend to add extra html elements in the component
|
||||
* that this feature is attached to.
|
||||
* @param {jQueryObject} $gridElement Grid element to add elements to.
|
||||
* @param {Object} options Feature options.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.addFeatureHtml =
|
||||
function($gridElement, options) {
|
||||
// Default implementation does nothing.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the html element of the grid that this feature
|
||||
* is attached to.
|
||||
*
|
||||
* @return {jQueryObject} Return the grid's HTML element.
|
||||
*/
|
||||
$.pkp.classes.features.Feature.prototype.getGridHtmlElement =
|
||||
function() {
|
||||
return this.gridHandler.getHtmlElement();
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @file js/classes/features/GeneralPagingFeature.js
|
||||
*
|
||||
* Copyright (c) 2016-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 GeneralPagingFeature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Base class that implements general functionalities for features
|
||||
* that handles paging on grids.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @inheritDoc
|
||||
* @extends $.pkp.classes.features.Feature
|
||||
*/
|
||||
$.pkp.classes.features.GeneralPagingFeature =
|
||||
function(gridHandler, options) {
|
||||
options.defaultItemsPerPage = parseInt(options.defaultItemsPerPage, 10);
|
||||
options.currentItemsPerPage = parseInt(options.currentItemsPerPage, 10);
|
||||
if (!options.itemsTotal) {
|
||||
options.itemsTotal = 0;
|
||||
} else {
|
||||
options.itemsTotal = parseInt(options.itemsTotal, 10);
|
||||
}
|
||||
options.currentPage = parseInt(options.currentPage, 10);
|
||||
this.parent(gridHandler, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.classes.features.GeneralPagingFeature,
|
||||
$.pkp.classes.features.Feature);
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* @return {{itemsPerPageParamName: string,
|
||||
* defaultItemsPerPage: number,
|
||||
* currentItemsPerPage: number,
|
||||
* itemsTotal: number,
|
||||
* pageParamName: string,
|
||||
* currentPage: number,
|
||||
filter: string,
|
||||
* pagingMarkup: string }}
|
||||
* @override
|
||||
*/
|
||||
$.pkp.classes.features.GeneralPagingFeature.prototype.getOptions =
|
||||
function() {
|
||||
var castOptions = /** @type {{itemsPerPageParamName: string,
|
||||
defaultItemsPerPage: number,
|
||||
currentItemsPerPage: number,
|
||||
itemsTotal: number,
|
||||
pageParamName: string,
|
||||
currentPage: number,
|
||||
filter: string,
|
||||
pagingMarkup: string }} */
|
||||
(this.parent('getOptions'));
|
||||
|
||||
return castOptions;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
/**
|
||||
* Set grid requests extra parameters.
|
||||
* @param {Object} params
|
||||
*/
|
||||
$.pkp.classes.features.GeneralPagingFeature.prototype.setGridParams =
|
||||
function(params) {
|
||||
var options = this.getOptions(), filter;
|
||||
|
||||
// Add the filter data, if any.
|
||||
if (options.hasOwnProperty('filter')) {
|
||||
filter = $.parseJSON(options.filter);
|
||||
$.extend(true, params, filter);
|
||||
}
|
||||
|
||||
this.gridHandler.setFetchExtraParams(params);
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,339 @@
|
||||
/**
|
||||
* @file js/classes/features/InfiniteScrollingFeature.js
|
||||
*
|
||||
* Copyright (c) 2016-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 InfiniteScrollingFeature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Feature that implements infinite scrolling on grids.
|
||||
* It doesn't support category grids.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @inheritDoc
|
||||
* @extends $.pkp.classes.features.GeneralPagingFeature
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature =
|
||||
function(gridHandler, options) {
|
||||
this.parent(gridHandler, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.classes.features.InfiniteScrollingFeature,
|
||||
$.pkp.classes.features.GeneralPagingFeature);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The scrollable element.
|
||||
* @private
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.
|
||||
$scrollableElement_ = $();
|
||||
|
||||
|
||||
/**
|
||||
* The scrolling observer callback function.
|
||||
* @private
|
||||
* @type {Function}
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.
|
||||
observeScrollCallback_ = function() {};
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GeneralPagingFeature
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.init =
|
||||
function() {
|
||||
var $scrollableElement = $('div.scrollable', this.getGridHtmlElement());
|
||||
if (!$scrollableElement.length) {
|
||||
this.gridHandler.publishEvent('pkpObserveScrolling');
|
||||
this.gridHandler.publishEvent('pkpRemoveScrollingObserver');
|
||||
}
|
||||
this.$scrollableElement_ = $scrollableElement;
|
||||
this.observeScrollCallback_ = this.gridHandler.callbackWrapper(
|
||||
this.observeScroll_, this);
|
||||
this.addScrollHandler_();
|
||||
this.fixGridHeight_();
|
||||
this.addPagingDataToRows_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.addFeatureHtml =
|
||||
function($gridElement, options) {
|
||||
var castOptions = /** @type {{pagingMarkup: string?,
|
||||
loadingContainer: string?}} */ (options);
|
||||
$gridElement.append(castOptions.pagingMarkup);
|
||||
$gridElement.find('.pkp_linkaction_moreItems')
|
||||
.click(this.gridHandler.callbackWrapper(this.loadMoreItems_, this));
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.refreshGrid =
|
||||
function(opt_elementId) {
|
||||
var options = this.getOptions(), params, $firstRow, $lastRow, page, $gridRow,
|
||||
elementId;
|
||||
|
||||
params = this.gridHandler.getFetchExtraParams();
|
||||
params[options.pageParamName] = options.currentPage;
|
||||
|
||||
if (opt_elementId && opt_elementId !==
|
||||
$.pkp.controllers.grid.GridHandler.FETCH_ALL_ROWS_ID) {
|
||||
// We need to make sure we pass the right page for the element.
|
||||
elementId = (/** @type {number} */ (opt_elementId));
|
||||
$gridRow = this.gridHandler.getRowByDataId(elementId);
|
||||
if ($gridRow.length == 1) {
|
||||
params[options.pageParamName] = Number($gridRow.attr('data-paging'));
|
||||
}
|
||||
}
|
||||
|
||||
params[options.itemsPerPageParamName] = options.currentItemsPerPage;
|
||||
|
||||
this.setGridParams(params);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.
|
||||
replaceElementResponseHandler = function(handledJsonData) {
|
||||
var pagingInfo, options, castJsonData, rowMarkup;
|
||||
options = this.getOptions();
|
||||
castJsonData = /** @type {{pagingInfo: Object,
|
||||
deletedRowReplacement: string}} */
|
||||
(handledJsonData);
|
||||
|
||||
if (castJsonData.deletedRowReplacement != undefined) {
|
||||
rowMarkup = handledJsonData.deletedRowReplacement;
|
||||
this.gridHandler.insertOrReplaceElement(rowMarkup);
|
||||
this.updatePagingDataInAllRows_();
|
||||
}
|
||||
|
||||
this.addScrollHandler_();
|
||||
|
||||
if (castJsonData.pagingInfo != undefined) {
|
||||
pagingInfo = handledJsonData.pagingInfo;
|
||||
this.setOptions(pagingInfo);
|
||||
|
||||
if (pagingInfo.pagingMarkup != undefined) {
|
||||
$('div.gridPagingScrolling', this.getGridHtmlElement()).
|
||||
replaceWith(pagingInfo.pagingMarkup);
|
||||
}
|
||||
}
|
||||
|
||||
this.addPagingDataToRows_();
|
||||
|
||||
this.toggleLoadingContainer_();
|
||||
|
||||
this.getGridHtmlElement().find('.pkp_linkaction_moreItems').
|
||||
click(this.gridHandler.callbackWrapper(this.loadMoreItems_, this));
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Scroll handler to detect when it's time to request more rows.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {HTMLElement} sourceElement
|
||||
* @param {Event} event
|
||||
* @return {boolean}
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.observeScroll_ =
|
||||
function(sourceElement, event) {
|
||||
var options = this.getOptions(), sourceElementHeight,
|
||||
bottomLimit, windowDimensions;
|
||||
if (options.itemsTotal == this.gridHandler.getRows().length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.getGridHtmlElement().is(':visible')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($(sourceElement).hasClass('scrollable')) {
|
||||
sourceElementHeight = $(sourceElement).height();
|
||||
bottomLimit = sourceElement.scrollHeight;
|
||||
} else {
|
||||
windowDimensions = $.pkp.controllers.SiteHandler.
|
||||
prototype.getWindowDimensions();
|
||||
sourceElementHeight = windowDimensions.height;
|
||||
bottomLimit = this.getGridHtmlElement().offset().top +
|
||||
this.getGridHtmlElement().height();
|
||||
}
|
||||
|
||||
if (sourceElementHeight + $(sourceElement).scrollTop() >= bottomLimit) {
|
||||
// Avoid multiple rows requests.
|
||||
if (this.$scrollableElement_.length) {
|
||||
this.$scrollableElement_.unbind('scroll');
|
||||
} else {
|
||||
this.getGridHtmlElement().trigger('pkpRemoveScrollingObserver',
|
||||
[this.observeScrollCallback_]);
|
||||
}
|
||||
|
||||
this.loadMoreItems_();
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fix the grid height to acomodate the number of initial visible rows.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.fixGridHeight_ =
|
||||
function() {
|
||||
var $scrollableDivs = $('div.scrollable', this.getGridHtmlElement()),
|
||||
index, limit, $div, timer, length;
|
||||
|
||||
if ($scrollableDivs.length > 0) {
|
||||
timer = setInterval(function() {
|
||||
if ($scrollableDivs.is(':visible')) {
|
||||
clearInterval(timer);
|
||||
length = $scrollableDivs.length;
|
||||
for (index = 0, limit = length; index < limit; index++) {
|
||||
$div = $($scrollableDivs[index]);
|
||||
if ($div.get(0).scrollHeight > $div.height()) {
|
||||
$div.css('max-height', $div.get(0).scrollHeight - 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
},300);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add paging data to the respective rows.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.addPagingDataToRows_ =
|
||||
function() {
|
||||
var $rows, options = this.getOptions();
|
||||
$rows = this.gridHandler.getRows().filter('tr:not([data-paging])');
|
||||
$rows.attr('data-paging', options.currentPage);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update paging data in all grid rows.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.
|
||||
updatePagingDataInAllRows_ = function() {
|
||||
var $rows, options = this.getOptions(), index, limit, page = 1,
|
||||
itemsCount = 1;
|
||||
$rows = this.gridHandler.getRows();
|
||||
$rows.removeAttr('data-paging');
|
||||
|
||||
for (index = 0, limit = $rows.length; index < limit; index++) {
|
||||
$($rows[index]).attr('data-paging', page);
|
||||
itemsCount++;
|
||||
if (itemsCount > options.currentItemsPerPage) {
|
||||
itemsCount = 1;
|
||||
page++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add scroll handler to the grid element.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.addScrollHandler_ =
|
||||
function() {
|
||||
var $scrollableElement = this.$scrollableElement_;
|
||||
if ($scrollableElement.length) {
|
||||
$scrollableElement.
|
||||
scroll(this.observeScrollCallback_);
|
||||
} else {
|
||||
this.getGridHtmlElement().trigger('pkpObserveScrolling',
|
||||
[this.observeScrollCallback_]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Toggle the scrolling loading element.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {boolean=} opt_show
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.
|
||||
toggleLoadingContainer_ = function(opt_show) {
|
||||
var $loadingElement =
|
||||
this.getGridHtmlElement().find('div.gridPagingScrolling div.pkp_loading'),
|
||||
$scrollableElement = this.$scrollableElement_,
|
||||
scrollTop,
|
||||
loadingHeight = $loadingElement.height(),
|
||||
scrollTarget;
|
||||
|
||||
if (opt_show) {
|
||||
this.getGridHtmlElement().addClass('loading');
|
||||
scrollTop = $scrollableElement.scrollTop();
|
||||
scrollTarget = /** @type {number} */ (scrollTop + loadingHeight);
|
||||
$scrollableElement.scrollTop(scrollTarget);
|
||||
} else {
|
||||
this.getGridHtmlElement().removeClass('loading');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Trigger necessary actions for the grid to
|
||||
* load next page items.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
*/
|
||||
$.pkp.classes.features.InfiniteScrollingFeature.prototype.
|
||||
loadMoreItems_ = function() {
|
||||
var options = this.getOptions();
|
||||
|
||||
// Show the loading icon.
|
||||
this.toggleLoadingContainer_(true);
|
||||
|
||||
options.currentPage = Number($('tr.gridRow',
|
||||
this.getGridHtmlElement()).last().attr('data-paging')) + 1;
|
||||
this.getGridHtmlElement().trigger('dataChanged',
|
||||
[$.pkp.controllers.grid.GridHandler.FETCH_ALL_ROWS_ID]);
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* @file js/classes/features/OrderCategoryGridItemsFeature.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 OrderCategoryGridItemsFeature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Feature for ordering category grid items.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @inheritDoc
|
||||
* @extends $.pkp.classes.features.OrderGridItemsFeature
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature =
|
||||
function(gridHandler, options) {
|
||||
this.parent(gridHandler, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature,
|
||||
$.pkp.classes.features.OrderGridItemsFeature);
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from OrderItemsFeature.
|
||||
//
|
||||
/**
|
||||
* Setup the sortable plugin.
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.
|
||||
setupSortablePlugin = function() {
|
||||
|
||||
var $categories, index, limit, $category, userAgent;
|
||||
|
||||
this.applySortPlgOnElements(
|
||||
this.getGridHtmlElement(), 'tbody.orderable', null);
|
||||
|
||||
// FIXME *7610*: IE8 can't handle well ordering in both categories and
|
||||
// category rows.
|
||||
userAgent = navigator.userAgent.toLowerCase();
|
||||
if (/msie/.test(userAgent) &&
|
||||
parseInt(userAgent.substr(userAgent.indexOf('msie') + 5, 1), 10) <= 8) {
|
||||
return;
|
||||
}
|
||||
|
||||
$categories = this.gridHandler.getCategories();
|
||||
for (index = 0, limit = $categories.length; index < limit; index++) {
|
||||
$category = $($categories[index]);
|
||||
this.applySortPlgOnElements($category, 'tr.orderable', null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.
|
||||
saveOrderHandler = function() {
|
||||
this.gridHandler.updateEmptyPlaceholderPosition();
|
||||
this.parent('saveOrderHandler');
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.
|
||||
cancelOrderHandler = function() {
|
||||
|
||||
var categorySequence = this.getCategorySequence_(this.itemsOrder);
|
||||
this.parent('cancelOrderHandler');
|
||||
this.gridHandler.resequenceCategories(categorySequence);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.
|
||||
toggleItemsDragMode = function() {
|
||||
this.parent('toggleItemsDragMode');
|
||||
|
||||
var isOrdering = this.isOrdering,
|
||||
$categories = this.gridHandler.getCategories(),
|
||||
index, limit, $category;
|
||||
|
||||
for (index = 0, limit = $categories.length; index < limit; index++) {
|
||||
$category = $($categories[index]);
|
||||
this.toggleCategoryDragMode_($category);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.
|
||||
addOrderingClassToRows = function() {
|
||||
|
||||
var options = this.getOptions(),
|
||||
type = parseInt(options.type, 10), $categories;
|
||||
|
||||
if (type == $.pkp.cons.ORDER_CATEGORY_GRID_CATEGORIES_ONLY ||
|
||||
type == $.pkp.cons.ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS) {
|
||||
$categories = this.gridHandler.getCategories();
|
||||
$categories.addClass('orderable');
|
||||
}
|
||||
|
||||
if (type == $.pkp.cons.ORDER_CATEGORY_GRID_CATEGORIES_ROWS_ONLY ||
|
||||
type == $.pkp.cons.ORDER_CATEGORY_GRID_CATEGORIES_AND_ROWS) {
|
||||
this.parent('addOrderingClassToRows');
|
||||
}
|
||||
|
||||
// We don't want to order category rows tr elements, so
|
||||
// remove any style that might be added by calling parent.
|
||||
this.gridHandler.getCategoryRow().removeClass('orderable');
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Overriden method from OrderGridItemsFeature
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.getItemsDataId =
|
||||
function() {
|
||||
var categoriesSeq = this.getCategorySequence_(this.itemsOrder),
|
||||
itemsDataId = [],
|
||||
index, limit,
|
||||
$category, categoryRowsDataId, categoryDataId;
|
||||
|
||||
for (index = 0, limit = categoriesSeq.length; index < limit; index++) {
|
||||
$category = $('#' + categoriesSeq[index]);
|
||||
categoryRowsDataId = this.getRowsDataId($category);
|
||||
categoryDataId = this.gridHandler.getCategoryDataId($category);
|
||||
itemsDataId.push(
|
||||
{'categoryId': categoryDataId, 'rowsId': categoryRowsDataId });
|
||||
}
|
||||
|
||||
return itemsDataId;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Enable/disable category drag mode.
|
||||
* @param {jQueryObject} $category Category to set mode on.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.
|
||||
toggleCategoryDragMode_ = function($category) {
|
||||
var isOrdering = this.isOrdering,
|
||||
$categoryRow = this.gridHandler.getCategoryRow($category),
|
||||
$categoryRowColumn = $('td:first', $categoryRow),
|
||||
moveClasses = this.getMoveItemClasses();
|
||||
|
||||
if (isOrdering) {
|
||||
$categoryRowColumn.addClass(moveClasses);
|
||||
} else {
|
||||
$categoryRowColumn.removeClass(moveClasses);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the categories sequence, based on the passed items order.
|
||||
* @param {Array} itemsOrder Items order.
|
||||
* @return {Array} A sequence array with the category data id as values.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderCategoryGridItemsFeature.prototype.
|
||||
getCategorySequence_ = function(itemsOrder) {
|
||||
var index, limit, categorySequence = [], categoryDataId, categoryId;
|
||||
for (index = 0, limit = itemsOrder.length; index < limit; index++) {
|
||||
categoryDataId = this.gridHandler
|
||||
.getCategoryDataIdByRowId(itemsOrder[index]);
|
||||
categoryId = this.gridHandler.getCategoryIdPrefix() + categoryDataId;
|
||||
if ($.inArray(categoryId, categorySequence) > -1) {
|
||||
continue;
|
||||
}
|
||||
categorySequence.push(categoryId);
|
||||
}
|
||||
|
||||
return categorySequence;
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file js/classes/features/OrderGridItemsFeature.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 OrderGridItemsFeature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Feature for ordering grid items.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @inheritDoc
|
||||
* @extends $.pkp.classes.features.OrderItemsFeature
|
||||
*/
|
||||
$.pkp.classes.features.OrderGridItemsFeature =
|
||||
function(gridHandler, options) {
|
||||
this.parent(gridHandler, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.classes.features.OrderGridItemsFeature,
|
||||
$.pkp.classes.features.OrderItemsFeature);
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from OrderItemsFeature.
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderGridItemsFeature.prototype.setupSortablePlugin =
|
||||
function() {
|
||||
this.applySortPlgOnElements(
|
||||
this.getGridHtmlElement(), 'tr.orderable', null);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderGridItemsFeature.prototype.saveOrderHandler =
|
||||
function() {
|
||||
|
||||
var stringifiedData, saveOrderCallback,
|
||||
options = /** @type {{saveItemsSequenceUrl: string}} */
|
||||
(this.getOptions()),
|
||||
returner;
|
||||
|
||||
this.parent('saveOrderHandler');
|
||||
|
||||
stringifiedData = JSON.stringify(this.getItemsDataId());
|
||||
saveOrderCallback = this.callbackWrapper(
|
||||
this.saveOrderResponseHandler_, this);
|
||||
$.post(options.saveItemsSequenceUrl,
|
||||
{data: stringifiedData, csrfToken: options.csrfToken},
|
||||
saveOrderCallback, 'json');
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Protected methods to be overriden by subclasses
|
||||
//
|
||||
/**
|
||||
* Get all items data id in a sequence array.
|
||||
* @return {Array} List of all items data.
|
||||
*/
|
||||
$.pkp.classes.features.OrderGridItemsFeature.prototype.getItemsDataId =
|
||||
function() {
|
||||
return this.getRowsDataId(this.getGridHtmlElement());
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Save order response handler.
|
||||
* @private
|
||||
*
|
||||
* @param {Object} ajaxContext The AJAX request context.
|
||||
* @param {Object} jsonData A parsed JSON response object.
|
||||
*/
|
||||
$.pkp.classes.features.OrderGridItemsFeature.prototype.
|
||||
saveOrderResponseHandler_ = function(ajaxContext, jsonData) {
|
||||
var processedJsonData = this.gridHandler.handleJson(jsonData);
|
||||
this.toggleState(false);
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,639 @@
|
||||
/**
|
||||
* @file js/classes/features/OrderItemsFeature.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 OrderItemsFeature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Base feature class for ordering grid items.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {jQueryObject} gridHandler The handler of
|
||||
* the grid element that this feature is attached to.
|
||||
* @param {Object} options Configuration of this feature.
|
||||
* @extends $.pkp.classes.features.Feature
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature =
|
||||
function(gridHandler, options) {
|
||||
this.parent(gridHandler, options);
|
||||
|
||||
this.$orderButton_ = $('.pkp_linkaction_orderItems',
|
||||
this.getGridHtmlElement());
|
||||
this.$finishControl_ = $('.order_finish_controls', this.getGridHtmlElement());
|
||||
|
||||
if (this.$orderButton_.length === 0) {
|
||||
// No order button, it will always stay in ordering mode.
|
||||
this.isOrdering = true;
|
||||
}
|
||||
|
||||
this.itemsOrder = [];
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.classes.features.OrderItemsFeature,
|
||||
$.pkp.classes.features.Feature);
|
||||
|
||||
|
||||
//
|
||||
// Protected properties
|
||||
//
|
||||
/**
|
||||
* Item sequence.
|
||||
* @protected
|
||||
* @type {Array}
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.itemsOrder = null;
|
||||
|
||||
|
||||
/**
|
||||
* Flag to control if user is ordering items.
|
||||
* @protected
|
||||
* @type {boolean}
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.isOrdering = false;
|
||||
|
||||
|
||||
//
|
||||
// Private properties.
|
||||
//
|
||||
/**
|
||||
* Initiate ordering state button.
|
||||
* @private
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.$orderButton_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Cancel ordering state button.
|
||||
* @private
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.$cancelButton_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Save ordering state button.
|
||||
* @private
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.$saveButton_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Ordering finish control.
|
||||
* @private
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.$finishControl_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters.
|
||||
//
|
||||
/**
|
||||
* Get the order button.
|
||||
* @return {jQueryObject} The order button JQuery object.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.getOrderButton =
|
||||
function() {
|
||||
return this.$orderButton_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the finish control.
|
||||
* @return {jQueryObject} The JQuery "finish" control.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.getFinishControl =
|
||||
function() {
|
||||
return this.$finishControl_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get save order button.
|
||||
*
|
||||
* @return {jQueryObject} The "save order" JQuery object.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.getSaveOrderButton =
|
||||
function() {
|
||||
return this.getFinishControl().find('.saveButton');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get cancel order link.
|
||||
*
|
||||
* @return {jQueryObject} The "cancel order" JQuery control.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.getCancelOrderButton =
|
||||
function() {
|
||||
return this.getFinishControl().find('.cancelFormButton');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the move item row action element selector.
|
||||
* @return {string} Return the element selector.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.
|
||||
getMoveItemRowActionSelector = function() {
|
||||
return '.orderable .pkp_linkaction_moveItem';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the css classes used to stylize the ordering items.
|
||||
* @return {string} CSS classes.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.getMoveItemClasses =
|
||||
function() {
|
||||
return 'pkp_helpers_moveicon ordering';
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Public template methods.
|
||||
//
|
||||
/**
|
||||
* Called every time user start dragging an item.
|
||||
* @param {jQueryObject} contextElement The element this event occurred for.
|
||||
* @param {Event} event The drag/drop event.
|
||||
* @param {Object} ui Object with data related to the event elements.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.dragStartCallback =
|
||||
function(contextElement, event, ui) {
|
||||
// The default implementation does nothing.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called every time user stop dragging an item.
|
||||
* @param {jQueryObject} contextElement The element this event occurred for.
|
||||
* @param {Event} event The drag/drop event.
|
||||
* @param {Object} ui Object with data related to the event elements.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.dragStopCallback =
|
||||
function(contextElement, event, ui) {
|
||||
// The default implementation does nothing.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called every time sequence is changed.
|
||||
* @param {jQueryObject} contextElement The element this event occurred for.
|
||||
* @param {Event} event The drag/drop event.
|
||||
* @param {Object} ui Object with data related to the event elements.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.updateOrderCallback =
|
||||
function(contextElement, event, ui) {
|
||||
// The default implementation does nothing.
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from Feature
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.init =
|
||||
function() {
|
||||
|
||||
this.addOrderingClassToRows();
|
||||
this.toggleMoveItemRowAction(this.isOrdering);
|
||||
this.getGridHtmlElement().find('div.order_message').hide();
|
||||
|
||||
this.toggleOrderLink_();
|
||||
if (this.isOrdering) {
|
||||
this.setupSortablePlugin();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.addFeatureHtml =
|
||||
function($gridElement, options) {
|
||||
var castOptions = /** @type {{orderFinishControls: string?,
|
||||
orderMessage: string?}} */ (options),
|
||||
$orderFinishControls, orderMessageHtml, $gridRows;
|
||||
if (castOptions.orderFinishControls !== undefined) {
|
||||
$orderFinishControls = $(castOptions.orderFinishControls);
|
||||
$gridElement.find('table').last().after($orderFinishControls);
|
||||
$orderFinishControls.hide();
|
||||
}
|
||||
|
||||
if (castOptions.orderMessage !== undefined) {
|
||||
orderMessageHtml = castOptions.orderMessage;
|
||||
$gridRows = $gridElement.find('.gridRow').filter(function(index, element) {
|
||||
return !Boolean($(this).find('a.pkp_linkaction_moveItem').length);
|
||||
});
|
||||
$gridRows.find('td:first-child').prepend(orderMessageHtml);
|
||||
}
|
||||
|
||||
this.updateOrderLinkVisibility_();
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Protected template methods.
|
||||
//
|
||||
/**
|
||||
* Add orderable class to grid rows.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.addOrderingClassToRows =
|
||||
function() {
|
||||
// Add ordering class to grid rows.
|
||||
var $gridRows = this.gridHandler.getRows().filter(function(index, element) {
|
||||
return $(this).find('a.pkp_linkaction_moveItem').length;
|
||||
});
|
||||
$gridRows.addClass('orderable');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Setup the sortable plugin. Must be implemented in subclasses.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.setupSortablePlugin =
|
||||
function() {
|
||||
// Default implementation does nothing.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called every time storeOrder is called. This is a chance to subclasses
|
||||
* execute operations with each row that has their sequence being saved.
|
||||
* @param {number} index The current row index position inside the rows
|
||||
* jQuery object.
|
||||
* @param {jQueryObject} $row Row for which to store the sequence.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.storeRowOrder =
|
||||
function(index, $row) {
|
||||
// The default implementation does nothing.
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
/**
|
||||
* Initiate ordering button click event handler.
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.clickOrderHandler =
|
||||
function() {
|
||||
this.gridHandler.hideAllVisibleRowActions();
|
||||
this.storeOrder(this.gridHandler.getRows());
|
||||
this.toggleState(true);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Save order handler.
|
||||
* @return {boolean} Return false to stop click event processing.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.saveOrderHandler =
|
||||
function() {
|
||||
var $rows;
|
||||
|
||||
this.gridHandler.updateControlRowsPosition();
|
||||
this.unbindOrderFinishControlsHandlers_();
|
||||
$rows = this.gridHandler.getRows();
|
||||
this.storeOrder($rows);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cancel ordering action click event handler.
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.cancelOrderHandler =
|
||||
function() {
|
||||
this.gridHandler.resequenceRows(this.itemsOrder);
|
||||
this.toggleState(false);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Execute all operations necessary to change the state of the
|
||||
* ordering process (enabled or disabled).
|
||||
* @param {boolean} isOrdering Is ordering process active?
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.toggleState =
|
||||
function(isOrdering) {
|
||||
this.isOrdering = isOrdering;
|
||||
this.toggleGridLinkActions_();
|
||||
this.toggleOrderLink_();
|
||||
this.toggleFinishControl_();
|
||||
this.toggleItemsDragMode();
|
||||
this.setupSortablePlugin();
|
||||
this.setupNonOrderableMessage_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set rows sequence store, using
|
||||
* the sequence of the passed items.
|
||||
*
|
||||
* @param {jQueryObject} $rows The rows to be used to get the sequence
|
||||
* information.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.storeOrder =
|
||||
function($rows) {
|
||||
var index, limit, $row, elementId;
|
||||
this.itemsOrder = [];
|
||||
for (index = 0, limit = $rows.length; index < limit; index++) {
|
||||
$row = $($rows[index]);
|
||||
elementId = $row.attr('id');
|
||||
|
||||
this.itemsOrder.push(elementId);
|
||||
|
||||
// Give a chance to subclasses do extra operations to store
|
||||
// the current row order.
|
||||
this.storeRowOrder(index, $row);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable the items drag mode.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.toggleItemsDragMode =
|
||||
function() {
|
||||
var isOrdering = this.isOrdering,
|
||||
$rows = this.gridHandler.getRows(),
|
||||
$orderableRows = $rows.filter('.orderable'),
|
||||
moveClasses = this.getMoveItemClasses();
|
||||
|
||||
if (isOrdering) {
|
||||
$orderableRows.addClass(moveClasses);
|
||||
} else {
|
||||
$orderableRows.removeClass(moveClasses);
|
||||
}
|
||||
|
||||
this.toggleMoveItemRowAction(isOrdering);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply (disabled or enabled) the sortable plugin on passed elements.
|
||||
* @param {jQueryObject} $container The element that contain all the orderable
|
||||
* items.
|
||||
* @param {string} itemsSelector The jQuery selector for orderable items.
|
||||
* @param {Object?} extraParams Optional set of extra parameters for sortable.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.applySortPlgOnElements =
|
||||
function($container, itemsSelector, extraParams) {
|
||||
var isOrdering = this.isOrdering,
|
||||
dragStartCallback = this.gridHandler.callbackWrapper(
|
||||
this.dragStartCallback, this),
|
||||
dragStopCallback = this.gridHandler.callbackWrapper(
|
||||
this.dragStopCallback, this),
|
||||
orderItemCallback = this.gridHandler.callbackWrapper(
|
||||
this.updateOrderCallback, this),
|
||||
config = {
|
||||
disabled: !isOrdering,
|
||||
items: itemsSelector,
|
||||
activate: dragStartCallback,
|
||||
deactivate: dragStopCallback,
|
||||
update: orderItemCallback,
|
||||
tolerance: 'pointer'};
|
||||
|
||||
if (typeof extraParams === 'object') {
|
||||
config = $.extend(true, config, extraParams);
|
||||
}
|
||||
|
||||
$container.sortable(config);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the data element id of all rows inside the passed
|
||||
* container, in the current order.
|
||||
* @param {jQueryObject} $rowsContainer The element that contains the rows
|
||||
* that will be used to retrieve the id.
|
||||
* @return {Array} A sequence array with data element ids as values.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.getRowsDataId =
|
||||
function($rowsContainer) {
|
||||
var index, rowDataIds = [], $row, rowDataId;
|
||||
for (index in this.itemsOrder) {
|
||||
$row = $('#' + this.itemsOrder[index], $rowsContainer);
|
||||
if ($row.length < 1) {
|
||||
continue;
|
||||
}
|
||||
rowDataId = this.gridHandler.getRowDataId($row);
|
||||
rowDataIds.push(rowDataId);
|
||||
}
|
||||
|
||||
return rowDataIds;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show/hide the move item row action (position left).
|
||||
* @param {boolean} enable New enable state.
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.toggleMoveItemRowAction =
|
||||
function(enable) {
|
||||
var $grid = this.getGridHtmlElement(),
|
||||
$actionsContainer = $('div.row_actions', $grid),
|
||||
allLinksButMoveItemSelector = 'a:not(' +
|
||||
this.getMoveItemRowActionSelector() + ')',
|
||||
$actions = $actionsContainer.find(allLinksButMoveItemSelector),
|
||||
$moveItemRowAction = $(this.getMoveItemRowActionSelector(), $grid),
|
||||
$rowActionsContainer, $rowActions;
|
||||
|
||||
if (enable) {
|
||||
$actions.addClass('pkp_helpers_display_none');
|
||||
$moveItemRowAction.show();
|
||||
// Make sure row actions div is visible.
|
||||
this.gridHandler.showRowActionsDiv();
|
||||
} else {
|
||||
$actions.removeClass('pkp_helpers_display_none');
|
||||
|
||||
$rowActionsContainer = $('.gridRow div.row_actions', $grid);
|
||||
$rowActions = $rowActionsContainer.
|
||||
find(allLinksButMoveItemSelector);
|
||||
if ($rowActions.length === 0) {
|
||||
// No link action to show, hide row actions div.
|
||||
this.gridHandler.hideRowActionsDiv();
|
||||
}
|
||||
$moveItemRowAction.hide();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Hooks implementation.
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.addElement =
|
||||
function($element) {
|
||||
this.addOrderingClassToRows();
|
||||
this.toggleItemsDragMode();
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.replaceElement =
|
||||
function($content) {
|
||||
this.addOrderingClassToRows();
|
||||
this.toggleItemsDragMode();
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.
|
||||
replaceElementResponseHandler = function(handledJsonData) {
|
||||
this.updateOrderLinkVisibility_();
|
||||
this.setupNonOrderableMessage_();
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Make sure that the order action visibility state is correct,
|
||||
* based on the grid rows number.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.
|
||||
updateOrderLinkVisibility_ = function() {
|
||||
var $orderLink = $('.pkp_linkaction_orderItems', this.getGridHtmlElement());
|
||||
if (this.gridHandler.getRows().length <= 1) {
|
||||
$orderLink.hide();
|
||||
} else {
|
||||
$orderLink.show();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the state of the grid link actions, based on current ordering state.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.toggleGridLinkActions_ =
|
||||
function() {
|
||||
var isOrdering = this.isOrdering,
|
||||
// We want to enable/disable all link actions, except this
|
||||
// features controls.
|
||||
$gridLinkActions = $('.pkp_controllers_linkAction',
|
||||
this.getGridHtmlElement()).not(
|
||||
this.getMoveItemRowActionSelector()).not(
|
||||
this.getOrderButton()).not(
|
||||
this.getFinishControl().find('*'));
|
||||
|
||||
this.gridHandler.changeLinkActionsState(!isOrdering, $gridLinkActions);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable the order link action.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.toggleOrderLink_ =
|
||||
function() {
|
||||
if (this.isOrdering) {
|
||||
this.$orderButton_.unbind('click');
|
||||
this.$orderButton_.attr('disabled', 'disabled');
|
||||
} else {
|
||||
var clickHandler = this.gridHandler.callbackWrapper(
|
||||
this.clickOrderHandler, this);
|
||||
this.$orderButton_.click(clickHandler);
|
||||
this.$orderButton_.removeAttr('disabled');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show/hide the ordering process finish control, based
|
||||
* on the current ordering state.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.toggleFinishControl_ =
|
||||
function() {
|
||||
if (this.isOrdering) {
|
||||
this.bindOrderFinishControlsHandlers_();
|
||||
this.getFinishControl().slideDown(300);
|
||||
} else {
|
||||
this.unbindOrderFinishControlsHandlers_();
|
||||
this.getFinishControl().slideUp(300);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bind event handlers to the controls that finish the
|
||||
* ordering action (save and cancel).
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.
|
||||
bindOrderFinishControlsHandlers_ = function() {
|
||||
var $saveButton = this.getSaveOrderButton(),
|
||||
$cancelLink = this.getCancelOrderButton(),
|
||||
cancelLinkHandler = this.gridHandler.callbackWrapper(
|
||||
this.cancelOrderHandler, this),
|
||||
saveButtonHandler = this.gridHandler.callbackWrapper(
|
||||
this.saveOrderHandler, this);
|
||||
|
||||
$saveButton.click(saveButtonHandler);
|
||||
$cancelLink.click(cancelLinkHandler);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unbind event handlers from the controls that finish the
|
||||
* ordering action (save and cancel).
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.
|
||||
unbindOrderFinishControlsHandlers_ = function() {
|
||||
|
||||
this.getSaveOrderButton().unbind('click');
|
||||
this.getCancelOrderButton().unbind('click');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Toggle hover action to show message for non orderable
|
||||
* grid rows.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderItemsFeature.prototype.
|
||||
setupNonOrderableMessage_ = function() {
|
||||
if (this.isOrdering) {
|
||||
this.gridHandler.getRows().hover(function() {
|
||||
$(this).find('div.order_message').toggle();
|
||||
});
|
||||
} else {
|
||||
this.gridHandler.getRows().unbind('mouseenter mouseleave');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* @file js/classes/features/OrderListbuilderItemsFeature.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 OrderListbuilderItemsFeature
|
||||
* @ingroup js_classes_features
|
||||
*
|
||||
* @brief Feature for ordering grid items.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @inheritDoc
|
||||
* @extends $.pkp.classes.features.OrderItemsFeature
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature =
|
||||
function(gridHandler, options) {
|
||||
this.parent(gridHandler, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature,
|
||||
$.pkp.classes.features.OrderItemsFeature);
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from OrderItemsFeature.
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.addFeatureHtml =
|
||||
function($gridElement, options) {
|
||||
|
||||
var $itemSequenceInput, $gridRows, index, limit, $gridRow,
|
||||
$itemSequenceInputClone;
|
||||
|
||||
this.parent('addFeatureHtml', $gridElement, options);
|
||||
|
||||
$itemSequenceInput = this.getSequenceInput_();
|
||||
$gridRows = this.gridHandler.getRows();
|
||||
for (index = 0, limit = $gridRows.length; index < limit; index++) {
|
||||
$gridRow = $($gridRows[index]);
|
||||
$itemSequenceInputClone = $itemSequenceInput.clone();
|
||||
|
||||
$('td.first_column', $gridRow).append($itemSequenceInputClone);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set up the sortable plugin.
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.
|
||||
setupSortablePlugin = function() {
|
||||
this.applySortPlgOnElements(
|
||||
this.getGridHtmlElement(), 'tr.orderable', null);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from ToggleableOrderItemsFeature.
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.init =
|
||||
function() {
|
||||
this.parent('init');
|
||||
this.toggleItemsDragMode();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.toggleState =
|
||||
function(isOrdering) {
|
||||
this.parent('toggleState', isOrdering);
|
||||
this.toggleContentHandlers_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.storeRowOrder =
|
||||
function(index, $row) {
|
||||
var seq = index + 1,
|
||||
$orderableInput = $row.find('.itemSequence'),
|
||||
$modifiedInput;
|
||||
|
||||
$orderableInput.attr('value', seq);
|
||||
$modifiedInput = $row.find('.isModified');
|
||||
$modifiedInput.attr('value', 1);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.saveOrderHandler =
|
||||
function() {
|
||||
this.parent('saveOrderHandler');
|
||||
this.toggleState(false);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.
|
||||
updateOrderCallback = function(contextElement, event, ui) {
|
||||
|
||||
var $rows;
|
||||
this.parent('updateOrderCallback');
|
||||
$rows = this.gridHandler.getRows();
|
||||
this.storeOrder($rows);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.
|
||||
clickOrderHandler = function() {
|
||||
var $selects = $('select:visible', this.getGridHtmlElement()),
|
||||
index, limit;
|
||||
if ($selects.length > 0) {
|
||||
for (index = 0, limit = $selects.length; index < limit; index++) {
|
||||
this.gridHandler.saveRow($($selects[index]).parents('.gridRow'));
|
||||
}
|
||||
}
|
||||
|
||||
return /** @type {boolean} */ (this.parent('clickOrderHandler'));
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Implemented Feature template hook methods.
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.addElement =
|
||||
function($newElement) {
|
||||
this.parent('addElement', $newElement);
|
||||
this.formatAndStoreNewRow_($newElement);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.replaceElement =
|
||||
function($newContent) {
|
||||
this.parent('replaceElement', $newContent);
|
||||
this.formatAndStoreNewRow_($newContent);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Get the sequence input html element.
|
||||
* @private
|
||||
* @return {jQueryObject} Sequence input.
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.
|
||||
getSequenceInput_ = function() {
|
||||
return $('<input type="hidden" name="newRowId[sequence]" ' +
|
||||
'class="itemSequence" />');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable row content handlers.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.
|
||||
toggleContentHandlers_ = function() {
|
||||
var $rows = this.gridHandler.getRows(),
|
||||
index, limit, $row;
|
||||
for (index = 0, limit = $rows.length; index < limit; index++) {
|
||||
$row = $($rows[index]);
|
||||
if (this.isOrdering) {
|
||||
$row.find('.gridCellDisplay').unbind('click');
|
||||
} else {
|
||||
this.gridHandler.attachContentHandlers_($row);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Format and store new row.
|
||||
* @private
|
||||
* @param {jQueryObject} $row The new row element.
|
||||
*/
|
||||
$.pkp.classes.features.OrderListbuilderItemsFeature.prototype.
|
||||
formatAndStoreNewRow_ = function($row) {
|
||||
|
||||
var $rows;
|
||||
|
||||
$row.children().after(this.getSequenceInput_());
|
||||
$rows = this.gridHandler.getRows();
|
||||
this.storeOrder($rows);
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* @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));
|
||||
Reference in New Issue
Block a user