first commit
This commit is contained in:
@@ -0,0 +1,411 @@
|
||||
/**
|
||||
* @file js/controllers/grid/CategoryGridHandler.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 CategoryGridHandler
|
||||
* @ingroup js_controllers_grid
|
||||
*
|
||||
* @brief Category grid handler.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.grid.GridHandler
|
||||
*
|
||||
* @param {jQueryObject} $grid The grid this handler is
|
||||
* attached to.
|
||||
* @param {Object} options Grid handler configuration.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler = function($grid, options) {
|
||||
this.parent($grid, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits($.pkp.controllers.grid.CategoryGridHandler,
|
||||
$.pkp.controllers.grid.GridHandler);
|
||||
|
||||
|
||||
//
|
||||
// Public methods.
|
||||
//
|
||||
/**
|
||||
* Get category id prefix.
|
||||
* @return {string} Category id prefix.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getCategoryIdPrefix =
|
||||
function() {
|
||||
return this.getGridIdPrefix() + '-category-';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get categories tbody element.
|
||||
* @return {jQueryObject} Categories tbody elements.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getCategories =
|
||||
function() {
|
||||
return $('.category_grid_body:not(.empty)',
|
||||
this.getHtmlElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get a category tbody element by category data id.
|
||||
* @param {string} categoryDataId The category data id.
|
||||
* @return {jQueryObject} Category tbody element.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getCategoryByDataId =
|
||||
function(categoryDataId) {
|
||||
return $('#' + this.getCategoryIdPrefix() + categoryDataId);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the category row inside a tbody category element. If none element
|
||||
* is passed, get all grid category rows.
|
||||
* @param {jQueryObject} $opt_category Category tbody element.
|
||||
* @return {jQueryObject} Category rows.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getCategoryRow =
|
||||
function($opt_category) {
|
||||
var $context = this.getHtmlElement();
|
||||
if ($opt_category !== undefined) {
|
||||
$context = $opt_category;
|
||||
}
|
||||
|
||||
return $('tr.category', $context);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get rows inside a tbody category element, excluding the category row.
|
||||
* @param {jQueryObject} $category Category tbody element.
|
||||
* @return {jQueryObject} Category rows.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getRowsInCategory =
|
||||
function($category) {
|
||||
return $('tr.gridRow', $category).not('.category');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the category empty placeholder.
|
||||
* @param {jQueryObject} $category A grid category element.
|
||||
* @return {jQueryObject} The category empty placeholder.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.
|
||||
getCategoryEmptyPlaceholder = function($category) {
|
||||
var selector = '#' + $category.attr('id') + '-emptyPlaceholder';
|
||||
return $(selector, this.getHtmlElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the category data id by the passed category element.
|
||||
* @param {jQueryObject} $category Category element.
|
||||
* @return {string} Category data id.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getCategoryDataId =
|
||||
function($category) {
|
||||
var categoryId = $category.attr('id'),
|
||||
startExtractPosition = this.getCategoryIdPrefix().length;
|
||||
|
||||
return /** @type {string} */ (categoryId.slice(startExtractPosition));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the category data id by the passed row element id.
|
||||
* @param {string} gridRowId Category row element id.
|
||||
* @return {string} Category data id.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getCategoryDataIdByRowId =
|
||||
function(gridRowId) {
|
||||
// Remove the category id prefix to avoid getting wrong data.
|
||||
gridRowId = gridRowId.replace(this.getCategoryIdPrefix(), ' ');
|
||||
|
||||
// Get the category data id.
|
||||
var categoryDataId = gridRowId.match('(.*)-row');
|
||||
return $.trim(categoryDataId[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the id prefix of the grid row inside a category.
|
||||
* @return {string}
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getRowIdPrefix =
|
||||
function() {
|
||||
return this.getGridIdPrefix() + '-category-';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the grid row by the passed data element id.
|
||||
* @param {number} rowDataId
|
||||
* @return {jQueryObject}
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getRowByDataId =
|
||||
function(rowDataId) {
|
||||
this.parent('getRowByDataId', rowDataId);
|
||||
return $('#' + this.getRowIdPrefix() + this.currentCategoryId_ +
|
||||
'-row-' + rowDataId, this.getHtmlElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the data element id of the passed grid row.
|
||||
* @param {jQueryObject} $gridRow The grid row JQuery object.
|
||||
* @return {string} The data element id of the passed grid row.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getRowDataId =
|
||||
function($gridRow) {
|
||||
var rowDataId;
|
||||
rowDataId = $gridRow.attr('id').
|
||||
slice(this.getRowIdPrefix().length);
|
||||
rowDataId = rowDataId.match('-row-(.*)');
|
||||
return /** @type {string} */ ($.trim(rowDataId[1]));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Append a category to the end of the list.
|
||||
* @param {jQueryObject} $category Category to append.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.appendCategory =
|
||||
function($category) {
|
||||
var $gridBody = this.getHtmlElement().find(this.bodySelector);
|
||||
$gridBody.append($category);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Re-sequence all category elements based on the passed sequence map.
|
||||
* @param {Array} sequenceMap A sequence array with the category
|
||||
* element id as value.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.resequenceCategories =
|
||||
function(sequenceMap) {
|
||||
var categoryId, index, $category;
|
||||
for (index in sequenceMap) {
|
||||
categoryId = sequenceMap[index];
|
||||
$category = $('#' + categoryId);
|
||||
this.appendCategory($category);
|
||||
}
|
||||
|
||||
this.updateEmptyPlaceholderPosition();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Move all empty category placeholders to their correct position,
|
||||
* below of each correspondent category element.
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.
|
||||
updateEmptyPlaceholderPosition = function() {
|
||||
var $categories = this.getCategories(),
|
||||
index, limit,
|
||||
$category, $emptyPlaceholder;
|
||||
for (index = 0, limit = $categories.length; index < limit; index++) {
|
||||
$category = $($categories[index]);
|
||||
$emptyPlaceholder = this.getCategoryEmptyPlaceholder($category);
|
||||
if ($emptyPlaceholder.length > 0) {
|
||||
$emptyPlaceholder.insertAfter($category);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.initialize =
|
||||
function(options) {
|
||||
// Save the URL to fetch a whole category.
|
||||
this.fetchCategoryUrl_ = options.fetchCategoryUrl;
|
||||
|
||||
this.parent('initialize', options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getElementsByType =
|
||||
function($element) {
|
||||
if ($element.hasClass('category_grid_body')) {
|
||||
return this.getCategories();
|
||||
} else {
|
||||
return /** @type {jQueryObject} */ (
|
||||
this.parent('getElementsByType', $element));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.getEmptyElement =
|
||||
function($element) {
|
||||
if ($element.hasClass('category_grid_body')) {
|
||||
// Return the grid empty element placeholder.
|
||||
return this.getHtmlElement().find('.empty').not('.category_placeholder');
|
||||
} else {
|
||||
return /** @type {jQueryObject} */ (
|
||||
this.parent('getEmptyElement', $element));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.refreshGridHandler =
|
||||
function(sourceElement, event, opt_elementId) {
|
||||
|
||||
var fetchedAlready = false, elementIds,
|
||||
// Hack to avoid closure compiler warnings on type difference
|
||||
castElementId = /** @type {{parentElementId: number}} */ (opt_elementId);
|
||||
|
||||
if (opt_elementId !== undefined) {
|
||||
// Check if we want to refresh a row inside a category.
|
||||
if (castElementId.parentElementId !== undefined) {
|
||||
elementIds = {rowId: opt_elementId[0],
|
||||
rowCategoryId: castElementId.parentElementId};
|
||||
|
||||
// Store the category id.
|
||||
this.currentCategoryId_ = castElementId.parentElementId;
|
||||
|
||||
// Retrieve a single row from the server.
|
||||
$.get(this.fetchRowUrl, elementIds,
|
||||
this.callbackWrapper(
|
||||
this.replaceElementResponseHandler), 'json');
|
||||
} else {
|
||||
// Retrieve the entire category from the server.
|
||||
$.get(this.fetchCategoryUrl_, {rowId: opt_elementId},
|
||||
this.callbackWrapper(
|
||||
this.replaceElementResponseHandler), 'json');
|
||||
}
|
||||
fetchedAlready = true;
|
||||
}
|
||||
|
||||
this.parent('refreshGridHandler', sourceElement,
|
||||
event, opt_elementId, fetchedAlready);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.deleteElement =
|
||||
function($element) {
|
||||
|
||||
var $gridBody, index, limit, $parent, $emptyPlaceholder;
|
||||
|
||||
if ($element.length > 1) {
|
||||
// Category and category row have the same element data id,
|
||||
// handle this case.
|
||||
if ($element.length == 2 &&
|
||||
$element.hasClass('category_grid_body') &&
|
||||
$element.hasClass('category')) {
|
||||
// Always delete the entire category.
|
||||
$element = $element.filter('.category_grid_body');
|
||||
}
|
||||
|
||||
// Sometimes grid rows inside different categories may have
|
||||
// the same id. Try to find the correct one to delete.
|
||||
if (this.currentCategoryId_) {
|
||||
$gridBody = this.getCategoryByDataId(this.currentCategoryId_);
|
||||
for (index = 0, limit = $element.length; index < limit; index++) {
|
||||
$parent = $($element[index]).
|
||||
parents('#' + $gridBody.attr('id'));
|
||||
if ($parent.length === 1) {
|
||||
$element = $($element[index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($element.hasClass('category_grid_body')) {
|
||||
// Need to delete the category empty placeholder.
|
||||
$emptyPlaceholder = this.getCategoryEmptyPlaceholder($element);
|
||||
this.unbindPartial($emptyPlaceholder);
|
||||
$emptyPlaceholder.remove();
|
||||
}
|
||||
|
||||
this.parent('deleteElement', $element);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.addElement =
|
||||
function($element) {
|
||||
var $gridBody = null, categoryDataId, $emptyPlaceholder;
|
||||
|
||||
if ($element.hasClass('gridRow')) {
|
||||
// New row must be inside a category.
|
||||
categoryDataId = /** @type {string} */ (
|
||||
this.getCategoryDataIdByRowId(
|
||||
/** @type {string} */ ($element.attr('id'))));
|
||||
$gridBody = /** @type {jQueryObject} */ (
|
||||
this.getCategoryByDataId(categoryDataId));
|
||||
}
|
||||
|
||||
// Add the element.
|
||||
this.parent('addElement', $element, $gridBody);
|
||||
|
||||
// Make sure the placeholder is the last grid element.
|
||||
if ($element.hasClass('category_grid_body')) {
|
||||
$emptyPlaceholder = this.getEmptyElement($element);
|
||||
this.getHtmlElement().find(this.bodySelector).append($emptyPlaceholder);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.replaceElement =
|
||||
function($existingElement, $newElement) {
|
||||
|
||||
if ($newElement.hasClass('category_grid_body')) {
|
||||
// Need to delete the category empty placeholder.
|
||||
var $emptyPlaceholder = this.getCategoryEmptyPlaceholder($existingElement);
|
||||
this.unbindPartial($emptyPlaceholder);
|
||||
$emptyPlaceholder.remove();
|
||||
}
|
||||
|
||||
this.parent('replaceElement', $existingElement, $newElement);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.CategoryGridHandler.prototype.hasSameNumOfColumns =
|
||||
function($row) {
|
||||
var $element = $row,
|
||||
checkColSpan = false;
|
||||
|
||||
if ($row.hasClass('category_grid_body')) {
|
||||
$element = $row.find('tr');
|
||||
checkColSpan = true;
|
||||
}
|
||||
|
||||
return /** @type {boolean} */ (
|
||||
this.parent('hasSameNumOfColumns', $element, checkColSpan));
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,983 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/GridHandler.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 GridHandler
|
||||
* @ingroup js_controllers_grid
|
||||
*
|
||||
* @brief Grid row handler.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
// Define the namespace.
|
||||
$.pkp.controllers.grid = $.pkp.controllers.grid || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.classes.Handler
|
||||
*
|
||||
* @param {jQueryObject} $grid The grid this handler is
|
||||
* attached to.
|
||||
* @param {{features}} options Grid handler configuration.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler = function($grid, options) {
|
||||
this.parent($grid, options);
|
||||
|
||||
// We give a chance for this handler to initialize
|
||||
// before we initialize its features.
|
||||
this.initialize(options);
|
||||
|
||||
this.initFeatures_(options.features);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits($.pkp.controllers.grid.GridHandler,
|
||||
$.pkp.classes.Handler);
|
||||
|
||||
|
||||
//
|
||||
// Constants.
|
||||
//
|
||||
/**
|
||||
* Flag to be used to fetch all curent page grid rows.
|
||||
* @public
|
||||
* @type {Object}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.FETCH_ALL_ROWS_ID = {};
|
||||
|
||||
|
||||
//
|
||||
// Protected properties
|
||||
//
|
||||
/**
|
||||
* The selector for the grid body.
|
||||
* @protected
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.bodySelector = null;
|
||||
|
||||
|
||||
/**
|
||||
* The URL to fetch a grid row.
|
||||
* @protected
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.fetchRowUrl = null;
|
||||
|
||||
|
||||
/**
|
||||
* The URL to fetch all loaded grid rows.
|
||||
* @protected
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.fetchRowsUrl = null;
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The id of the grid.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.gridId_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The URL to fetch the entire grid.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.fetchGridUrl_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* This grid features.
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.features_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Fetch elements extra request parameters.
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.fetchExtraParams_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Get fetch element extra request parameters.
|
||||
* @return {Object} Extra request parameters.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getFetchExtraParams =
|
||||
function() {
|
||||
return this.fetchExtraParams_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set fetch element extra request parameters.
|
||||
* @param {Object} extraParams Extra request parameters.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.setFetchExtraParams =
|
||||
function(extraParams) {
|
||||
this.fetchExtraParams_ = extraParams;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the fetch row URL.
|
||||
* @return {?string} URL to the "fetch row" operation handler.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getFetchRowUrl =
|
||||
function() {
|
||||
|
||||
return this.fetchRowUrl;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the fetch rows URL.
|
||||
* @return {?string} URL to the "fetch rows" operation handler.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getFetchRowsUrl =
|
||||
function() {
|
||||
|
||||
return this.fetchRowsUrl;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get all grid rows.
|
||||
*
|
||||
* @return {jQueryObject} The rows as a JQuery object.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getRows =
|
||||
function() {
|
||||
return $('.gridRow', this.getHtmlElement()).not('.gridRowDeleted');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the id prefix of this grid.
|
||||
* @return {string} The ID prefix of this grid.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getGridIdPrefix =
|
||||
function() {
|
||||
return 'component-' + this.gridId_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the id prefix of this grid row.
|
||||
* @return {string} The id prefix of this grid row.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getRowIdPrefix =
|
||||
function() {
|
||||
return this.getGridIdPrefix() + '-row-';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the grid row by the passed data element id.
|
||||
* @param {number} rowDataId
|
||||
* @param {number=} opt_parentElementId
|
||||
* @return {jQueryObject}
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getRowByDataId =
|
||||
function(rowDataId, opt_parentElementId) {
|
||||
return $('#' +
|
||||
this.getRowIdPrefix() +
|
||||
$.pkp.classes.Helper.escapeJQuerySelector(String(rowDataId)),
|
||||
this.getHtmlElement());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the data element id of the passed grid row.
|
||||
* @param {jQueryObject} $gridRow The grid row JQuery object.
|
||||
* @return {string} The data element id of the passed grid row.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getRowDataId =
|
||||
function($gridRow) {
|
||||
var rowDataId;
|
||||
rowDataId = /** @type {string} */ ($gridRow.attr('id').
|
||||
slice(this.getRowIdPrefix().length));
|
||||
return rowDataId;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the parent grid row of the passed element, if any.
|
||||
* @param {jQueryObject} $element The element that is inside the row.
|
||||
* @return {jQueryObject} The element parent grid row.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getParentRow =
|
||||
function($element) {
|
||||
return $element.parents('.gridRow:first');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the same type elements of the passed element.
|
||||
* @param {jQueryObject} $element The element to get the type from.
|
||||
* @return {jQueryObject} The grid elements with the same type
|
||||
* of the passed element.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getElementsByType =
|
||||
function($element) {
|
||||
if ($element.hasClass('gridRow')) {
|
||||
var $container = $element.parents('tbody:first');
|
||||
return $('.gridRow', $container);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the empty element based on the type of the passed element.
|
||||
* @param {jQueryObject} $element The element to get the type from.
|
||||
* @return {jQueryObject} The empty element.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getEmptyElement =
|
||||
function($element) {
|
||||
if ($element.hasClass('gridRow')) {
|
||||
// Return the rows empty element placeholder.
|
||||
var $container = $element.parents('tbody:first');
|
||||
return $container.next('.empty');
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show/hide row actions.
|
||||
*
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.toggleRowActions =
|
||||
function(sourceElement, event) {
|
||||
|
||||
// Don't follow the link
|
||||
event.preventDefault();
|
||||
|
||||
// Toggle the extras link class.
|
||||
$(sourceElement).toggleClass('show_extras');
|
||||
$(sourceElement).toggleClass('hide_extras');
|
||||
|
||||
// Toggle the row actions.
|
||||
var $controlRow = $(sourceElement).parents('tr').next('.row_controls');
|
||||
this.applyToggleRowActionEffect_($controlRow);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hide all visible row controls.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.hideAllVisibleRowActions =
|
||||
function() {
|
||||
this.getHtmlElement().find('a.hide_extras').click();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hide row actions div container.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.hideRowActionsDiv =
|
||||
function() {
|
||||
var $rowActionDivs, index, limit, $div;
|
||||
|
||||
$rowActionDivs = $('.gridRow div.row_actions', this.getHtmlElement());
|
||||
$rowActionDivs.hide();
|
||||
|
||||
// FIXME: Hack to correctly align the first column cell content after
|
||||
// hiding the row actions div.
|
||||
for (index = 0, limit = $rowActionDivs.length; index < limit; index++) {
|
||||
$div = $($rowActionDivs[index]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show row actions div container.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.showRowActionsDiv =
|
||||
function() {
|
||||
var $rowActionDivs, index, limit, $div;
|
||||
|
||||
$rowActionDivs = $('.gridRow div.row_actions', this.getHtmlElement());
|
||||
$rowActionDivs.show();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable all link actions inside this grid.
|
||||
* @param {boolean} enable Enable/disable flag.
|
||||
* @param {jQueryObject} $linkElements Link elements JQuery object.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.changeLinkActionsState =
|
||||
function(enable, $linkElements) {
|
||||
if ($linkElements === undefined) {
|
||||
$linkElements = $('.pkp_controllers_linkAction', this.getHtmlElement());
|
||||
}
|
||||
$linkElements.each(function() {
|
||||
/** {$.pkp.controllers.LinkActionHandler} */
|
||||
var linkHandler;
|
||||
linkHandler = $.pkp.classes.Handler.getHandler($(this));
|
||||
if (enable) {
|
||||
linkHandler.enableLink();
|
||||
} else {
|
||||
linkHandler.disableLink();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Re-sequence all grid rows based on the passed sequence map.
|
||||
* @param {Array} sequenceMap A sequence array with the row id or
|
||||
* row data id as value.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.resequenceRows =
|
||||
function(sequenceMap) {
|
||||
var id, index, $row;
|
||||
if (!sequenceMap) {
|
||||
return;
|
||||
}
|
||||
for (index in sequenceMap) {
|
||||
id = sequenceMap[index];
|
||||
$row = $('#' + $.pkp.classes.Helper.escapeJQuerySelector(String(id)));
|
||||
if ($row.length == 0) {
|
||||
$row = this.getRowByDataId(id);
|
||||
}
|
||||
if ($row.length == 0) {
|
||||
throw new Error('Row with id ' + id + ' not found!');
|
||||
}
|
||||
this.addElement($row);
|
||||
}
|
||||
this.updateControlRowsPosition();
|
||||
|
||||
this.callFeaturesHook('resequenceRows', sequenceMap);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Move all grid control rows to their correct position,
|
||||
* below of each correspondent data grid row.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.updateControlRowsPosition =
|
||||
function() {
|
||||
var $rows, index, limit, $row, $controlRow;
|
||||
|
||||
$rows = this.getRows();
|
||||
for (index = 0, limit = $rows.length; index < limit; index++) {
|
||||
$row = $($rows[index]);
|
||||
$controlRow = this.getControlRowByGridRow($row);
|
||||
if ($controlRow.length > 0) {
|
||||
$controlRow.insertAfter($row);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Inserts or replaces a grid element.
|
||||
* @param {string|jQueryObject} elementContent The new mark-up of the element.
|
||||
* @param {boolean=} opt_prepend Prepend the new row instead of append it?
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.insertOrReplaceElement =
|
||||
function(elementContent, opt_prepend) {
|
||||
var $newElement, newElementId, $grid, $existingElement;
|
||||
// Parse the HTML returned from the server.
|
||||
$newElement = $(elementContent);
|
||||
newElementId = $newElement.attr('id');
|
||||
|
||||
// Does the element exist already?
|
||||
$grid = this.getHtmlElement();
|
||||
$existingElement = newElementId ?
|
||||
$grid.find('#' +
|
||||
$.pkp.classes.Helper.escapeJQuerySelector(
|
||||
/** @type {string} */ (newElementId))
|
||||
) :
|
||||
null;
|
||||
|
||||
if ($existingElement !== null && $existingElement.length > 1) {
|
||||
throw new Error('There were ' + $existingElement.length +
|
||||
' rather than 0 or 1 elements to be replaced!');
|
||||
}
|
||||
|
||||
if (!this.hasSameNumOfColumns($newElement)) {
|
||||
// Redraw the whole grid so new columns
|
||||
// get added/removed to match element.
|
||||
$.get(this.fetchGridUrl_, null,
|
||||
this.callbackWrapper(this.replaceGridResponseHandler_), 'json');
|
||||
} else {
|
||||
if ($existingElement !== null && $existingElement.length === 1) {
|
||||
// Update element.
|
||||
this.replaceElement($existingElement, $newElement);
|
||||
} else {
|
||||
// Insert row.
|
||||
this.addElement($newElement, null, opt_prepend);
|
||||
}
|
||||
|
||||
// Refresh row action event binding.
|
||||
this.activateRowActions_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Delete a grid element.
|
||||
* @param {jQueryObject} $element The element to be deleted.
|
||||
* @param {boolean=} opt_noFadeOut Whether the item deletion
|
||||
* will use the fade out effect or not.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.deleteElement =
|
||||
function($element, opt_noFadeOut) {
|
||||
var lastElement, $emptyElement, deleteFunction, self;
|
||||
|
||||
// Check whether we really only match one element.
|
||||
if ($element.length !== 1) {
|
||||
throw new Error('There were ' + $element.length +
|
||||
' rather than 1 element to delete!');
|
||||
}
|
||||
|
||||
// Flag this element as deleted, so getRows()
|
||||
// will return only existing rows from now on.
|
||||
$element.addClass('gridRowDeleted');
|
||||
|
||||
// Check whether this is the last row.
|
||||
lastElement = false;
|
||||
if (this.getElementsByType($element).length == 1) {
|
||||
lastElement = true;
|
||||
}
|
||||
|
||||
// Remove the controls row, if any.
|
||||
if ($element.hasClass('gridRow')) {
|
||||
this.deleteControlsRow_($element);
|
||||
}
|
||||
|
||||
$emptyElement = this.getEmptyElement($element);
|
||||
self = this;
|
||||
deleteFunction = function() {
|
||||
self.unbindPartial($element);
|
||||
$element.remove();
|
||||
if (lastElement) {
|
||||
$emptyElement.fadeIn(100);
|
||||
}
|
||||
};
|
||||
|
||||
if (opt_noFadeOut != undefined && opt_noFadeOut) {
|
||||
deleteFunction();
|
||||
} else {
|
||||
$element.fadeOut(500, deleteFunction);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
/**
|
||||
* Set data and execute operations to initialize.
|
||||
*
|
||||
* @protected
|
||||
*
|
||||
* @param {Object} options Grid options.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.initialize =
|
||||
function(options) {
|
||||
var $searchLink;
|
||||
|
||||
// Bind the handler for the "elements changed" event.
|
||||
this.bind('dataChanged', this.refreshGridHandler);
|
||||
|
||||
// Bind the handler for the "add new row" event.
|
||||
this.bind('addRow', this.addRowHandler_);
|
||||
|
||||
// Handle grid filter events.
|
||||
this.bind('formSubmitted', this.refreshGridWithFilterHandler_);
|
||||
|
||||
// Save the ID of this grid.
|
||||
this.gridId_ = options.gridId;
|
||||
|
||||
// Save the URL to fetch a row.
|
||||
this.fetchRowUrl = options.fetchRowUrl;
|
||||
|
||||
// Save the URL to fetch all rows.
|
||||
this.fetchRowsUrl = options.fetchRowsUrl;
|
||||
|
||||
// Save the URL to fetch the entire grid
|
||||
this.fetchGridUrl_ = options.fetchGridUrl;
|
||||
|
||||
// Save the selector for the grid body.
|
||||
if ($('div.scrollable', this.getHtmlElement()).length > 0) {
|
||||
this.bodySelector = 'div.scrollable table';
|
||||
} else {
|
||||
this.bodySelector = options.bodySelector;
|
||||
}
|
||||
|
||||
// Show/hide row action feature.
|
||||
this.activateRowActions_();
|
||||
|
||||
this.setFetchExtraParams({});
|
||||
|
||||
// Search control.
|
||||
this.getHtmlElement().find('.pkp_form').hide();
|
||||
$searchLink = this.getHtmlElement().
|
||||
find('.pkp_linkaction_search');
|
||||
if ($searchLink.length !== 0) {
|
||||
$searchLink.click(
|
||||
this.callbackWrapper(function() {
|
||||
this.getHtmlElement().find('.pkp_form').toggle();
|
||||
$searchLink.toggleClass('is_open');
|
||||
}));
|
||||
} else {
|
||||
// This grid doesn't have an expand/collapse control. If there is
|
||||
// a form, expand it.
|
||||
this.getHtmlElement().find('.pkp_form').toggle();
|
||||
}
|
||||
|
||||
this.trigger('gridInitialized');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Call features hooks.
|
||||
*
|
||||
* @protected
|
||||
*
|
||||
* @param {string} hookName The name of the hook.
|
||||
* @param {Array|jQueryObject|Object|number|boolean=} opt_args
|
||||
* The arguments array.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.callFeaturesHook =
|
||||
function(hookName, opt_args) {
|
||||
var featureName;
|
||||
if (!$.isArray(opt_args)) {
|
||||
opt_args = [opt_args];
|
||||
}
|
||||
for (featureName in this.features_) {
|
||||
this.features_[featureName][hookName].
|
||||
apply(this.features_[featureName], opt_args);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Refresh either a single row of the grid or the whole grid.
|
||||
*
|
||||
* @protected
|
||||
*
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
* @param {number|Object=} opt_elementId The id of a data element that was
|
||||
* updated, added or deleted. If not given then the whole grid
|
||||
* will be refreshed.
|
||||
* @param {Boolean=} opt_fetchedAlready Flag that subclasses can send
|
||||
* telling that a fetch operation was already handled there.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.refreshGridHandler =
|
||||
function(sourceElement, event, opt_elementId, opt_fetchedAlready) {
|
||||
var params;
|
||||
|
||||
this.callFeaturesHook('refreshGrid', opt_elementId);
|
||||
|
||||
params = this.getFetchExtraParams();
|
||||
|
||||
|
||||
// Check if subclasses already handled the fetch of new elements.
|
||||
if (!opt_fetchedAlready) {
|
||||
if (opt_elementId) {
|
||||
if (opt_elementId ==
|
||||
$.pkp.controllers.grid.GridHandler.FETCH_ALL_ROWS_ID) {
|
||||
$.get(this.fetchRowsUrl, params,
|
||||
this.callbackWrapper(this.replaceElementResponseHandler), 'json');
|
||||
} else {
|
||||
params.rowId = opt_elementId;
|
||||
// Retrieve a single row from the server.
|
||||
$.get(this.fetchRowUrl, params,
|
||||
this.callbackWrapper(this.replaceElementResponseHandler), 'json');
|
||||
}
|
||||
} else {
|
||||
// Retrieve the whole grid from the server.
|
||||
$.get(this.fetchGridUrl_, params,
|
||||
this.callbackWrapper(this.replaceGridResponseHandler_), 'json');
|
||||
}
|
||||
}
|
||||
|
||||
// Let the calling context (page?) know that the grids are being redrawn.
|
||||
this.trigger('gridRefreshRequested');
|
||||
this.publishChangeEvents();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a new row to the grid.
|
||||
*
|
||||
* @protected
|
||||
*
|
||||
* @param {jQueryObject} $newRow The new row to append.
|
||||
* @param {jQueryObject=} opt_$gridBody The tbody container element.
|
||||
* @param {boolean=} opt_prepend Prepend the element instead of append it?
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.addElement =
|
||||
function($newRow, opt_$gridBody, opt_prepend) {
|
||||
|
||||
if (opt_$gridBody === undefined || opt_$gridBody === null) {
|
||||
opt_$gridBody = this.getHtmlElement().find(this.bodySelector);
|
||||
}
|
||||
|
||||
// Add the new element.
|
||||
if (opt_prepend != undefined && opt_prepend) {
|
||||
opt_$gridBody.prepend($newRow);
|
||||
} else {
|
||||
opt_$gridBody.append($newRow);
|
||||
}
|
||||
|
||||
|
||||
// Hide the empty placeholder.
|
||||
var $emptyElement = this.getEmptyElement($newRow);
|
||||
if ($emptyElement) {
|
||||
$emptyElement.hide();
|
||||
}
|
||||
|
||||
this.callFeaturesHook('addElement', $newRow);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update an existing element using the passed new element content.
|
||||
*
|
||||
* @protected
|
||||
*
|
||||
* @param {jQueryObject} $existingElement The element that is already
|
||||
* in grid.
|
||||
* @param {jQueryObject} $newElement The element with new content.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.replaceElement =
|
||||
function($existingElement, $newElement) {
|
||||
|
||||
if ($newElement.hasClass('gridRow')) {
|
||||
this.deleteControlsRow_($existingElement);
|
||||
}
|
||||
|
||||
this.replacePartialWith($newElement, $existingElement);
|
||||
this.callFeaturesHook('replaceElement', $newElement);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Does the passed row have a different number of columns than the
|
||||
* existing grid?
|
||||
*
|
||||
* @protected
|
||||
*
|
||||
* @param {jQueryObject} $row The row to be checked against grid columns.
|
||||
* @param {Boolean=} opt_checkColSpan Will get the number of row columns
|
||||
* by column span.
|
||||
* @return {boolean} Whether it has the same number of grid columns
|
||||
* or not.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.hasSameNumOfColumns =
|
||||
function($row, opt_checkColSpan) {
|
||||
var $grid, numColumns, $tdElements, numCellsInNewRow;
|
||||
|
||||
$grid = this.getHtmlElement();
|
||||
numColumns = $grid.find('th').length;
|
||||
$tdElements = $row.first().find('td');
|
||||
if (opt_checkColSpan) {
|
||||
numCellsInNewRow = $tdElements.attr('colspan');
|
||||
} else {
|
||||
numCellsInNewRow = $tdElements.length;
|
||||
}
|
||||
|
||||
return (numColumns == numCellsInNewRow);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback to insert, remove or replace a row after an
|
||||
* element has been inserted, update or deleted.
|
||||
*
|
||||
* @protected
|
||||
*
|
||||
* @param {Object} ajaxContext The AJAX request context.
|
||||
* @param {Object} jsonData A parsed JSON response object.
|
||||
* @return {boolean|undefined} Return false when no replace action is taken.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.replaceElementResponseHandler =
|
||||
function(ajaxContext, jsonData) {
|
||||
var elementId, $element, handledJsonData, castJsonData, $responseElement,
|
||||
$responseRow, $responseControlRow, $responseRows, $responseRowsControls,
|
||||
index, limit;
|
||||
|
||||
handledJsonData = this.handleJson(jsonData);
|
||||
if (handledJsonData !== false) {
|
||||
if (handledJsonData.elementNotFound) {
|
||||
// The server reported that this element no
|
||||
// longer exists in the database so let's
|
||||
// delete it.
|
||||
elementId = handledJsonData.elementNotFound;
|
||||
$element = this.getRowByDataId(elementId);
|
||||
|
||||
// Sometimes we get a delete event before the
|
||||
// element has actually been inserted (e.g. when deleting
|
||||
// elements due to a cancel action or similar).
|
||||
if ($element.length > 0) {
|
||||
this.deleteElement($element);
|
||||
}
|
||||
} else {
|
||||
// The server returned mark-up to replace
|
||||
// or insert the row.
|
||||
$responseElement = $(handledJsonData.content);
|
||||
if ($responseElement.filter("tr:not('.row_controls')").length > 1) {
|
||||
$responseRows = $responseElement.filter('tr.gridRow');
|
||||
$responseRowsControls = $responseElement.filter('tr.row_controls');
|
||||
for (index = 0, limit = $responseRows.length; index < limit; index++) {
|
||||
$responseRow = $($responseRows[index]);
|
||||
$responseControlRow = this.getControlRowByGridRow($responseRow,
|
||||
$responseRowsControls);
|
||||
this.insertOrReplaceElement($responseRow.add($responseControlRow));
|
||||
}
|
||||
} else {
|
||||
this.insertOrReplaceElement(handledJsonData.content);
|
||||
}
|
||||
|
||||
castJsonData = /** @type {{sequenceMap: Array}} */ (handledJsonData);
|
||||
this.resequenceRows(castJsonData.sequenceMap);
|
||||
}
|
||||
}
|
||||
|
||||
this.callFeaturesHook('replaceElementResponseHandler', handledJsonData);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Refresh the grid after its filter has changed.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {$.pkp.controllers.form.ClientFormHandler} filterForm
|
||||
* The filter form.
|
||||
* @param {Event} event A "formSubmitted" event.
|
||||
* @param {string} filterData Serialized filter data.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.refreshGridWithFilterHandler_ =
|
||||
function(filterForm, event, filterData) {
|
||||
|
||||
// Retrieve the grid from the server and add the
|
||||
// filter data as form data.
|
||||
$.post(this.fetchGridUrl_, filterData,
|
||||
this.callbackWrapper(this.replaceGridResponseHandler_), 'json');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a new row to the grid.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
* @param {Object} params The request parameters to use to generate
|
||||
* the new row.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.addRowHandler_ =
|
||||
function(sourceElement, event, params) {
|
||||
|
||||
// Retrieve a single new row from the server.
|
||||
$.get(this.fetchRowUrl, params,
|
||||
this.callbackWrapper(this.replaceElementResponseHandler), 'json');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback to replace a grid's content.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Object} ajaxContext The AJAX request context.
|
||||
* @param {Object} jsonData A parsed JSON response object.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.replaceGridResponseHandler_ =
|
||||
function(ajaxContext, jsonData) {
|
||||
var handledJsonData, $grid, $gridParent, $newGrid,
|
||||
isFilterVisible;
|
||||
|
||||
handledJsonData = this.handleJson(jsonData);
|
||||
if (handledJsonData !== false) {
|
||||
// Get the grid that we're updating
|
||||
$grid = this.getHtmlElement();
|
||||
$gridParent = $grid.parent();
|
||||
|
||||
isFilterVisible = $grid.find('.filter').is(':visible');
|
||||
|
||||
// Replace the grid content
|
||||
this.replaceWith(handledJsonData.content);
|
||||
|
||||
// Update the html element of this handler.
|
||||
$newGrid = $('div[id^="' + this.getGridIdPrefix() + '"]', $gridParent);
|
||||
this.setHtmlElement($newGrid);
|
||||
|
||||
// Refresh row action event binding.
|
||||
this.activateRowActions_();
|
||||
|
||||
if (isFilterVisible) {
|
||||
// Open search control again.
|
||||
$newGrid.find('.pkp_linkaction_search').click();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper that deletes the row of controls (if present).
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {jQueryObject} $row The row whose matching control row should be
|
||||
* deleted.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.deleteControlsRow_ =
|
||||
function($row) {
|
||||
var $controlRow = $('#' + $.pkp.classes.Helper.escapeJQuerySelector(
|
||||
/** @type {string} */ ($row.attr('id'))) + '-control-row',
|
||||
this.getHtmlElement());
|
||||
|
||||
if ($controlRow.is('tr') && $controlRow.hasClass('row_controls')) {
|
||||
this.unbindPartial($controlRow);
|
||||
$controlRow.remove();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the control row for the passed the grid row.
|
||||
*
|
||||
* @param {jQueryObject} $gridRow The grid row JQuery object.
|
||||
* @param {jQueryObject=} opt_$context Optional context to get
|
||||
* the control row from.
|
||||
* @return {jQueryObject} The control row JQuery object.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.getControlRowByGridRow =
|
||||
function($gridRow, opt_$context) {
|
||||
var rowId, controlRowId, $context;
|
||||
|
||||
if (opt_$context === undefined || opt_$context === null) {
|
||||
$context = this.getHtmlElement().find('tr');
|
||||
} else {
|
||||
$context = opt_$context;
|
||||
}
|
||||
|
||||
rowId = $gridRow.attr('id');
|
||||
controlRowId = rowId + '-control-row';
|
||||
return $context.filter('#' +
|
||||
$.pkp.classes.Helper.escapeJQuerySelector(controlRowId));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper that attaches any action handlers related to rows.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.activateRowActions_ =
|
||||
function() {
|
||||
|
||||
var $grid = this.getHtmlElement(),
|
||||
$gridRows = this.getHtmlElement().find('tr.gridRow').not('.category');
|
||||
|
||||
$grid.find('a.show_extras').unbind('click').bind('click',
|
||||
this.callbackWrapper(this.toggleRowActions));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply the effect for hide/show row actions.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {jQueryObject} $controlRow The control row JQuery object.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.applyToggleRowActionEffect_ =
|
||||
function($controlRow) {
|
||||
var $row;
|
||||
|
||||
$row = $controlRow.prev().find('td:not(.indent_row)');
|
||||
$row = $row.add($controlRow.prev());
|
||||
$controlRow.toggle();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a grid feature.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {string} id Feature id.
|
||||
* @param {$.pkp.classes.features.Feature} $feature The grid
|
||||
* feature to be added.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.addFeature_ =
|
||||
function(id, $feature) {
|
||||
if (!this.features_) {
|
||||
this.features_ = [];
|
||||
}
|
||||
this.features_[id] = $feature;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add grid features.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Array.<{JSClass, options}>} features The features options array.
|
||||
*/
|
||||
$.pkp.controllers.grid.GridHandler.prototype.initFeatures_ =
|
||||
function(features) {
|
||||
|
||||
var id, $feature, jsClass;
|
||||
|
||||
for (id in features) {
|
||||
// Only initiate features that have a js handler.
|
||||
jsClass = features[id].JSClass;
|
||||
if (jsClass === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$feature =
|
||||
/** @type {$.pkp.classes.features.Feature} */
|
||||
($.pkp.classes.Helper.objectFactory(
|
||||
jsClass, [this, features[id].options]));
|
||||
|
||||
this.addFeature_(id, $feature);
|
||||
this.features_[id].init();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file js/controllers/grid/files/review/AuthorReviewRevisionsGridHandler.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 AuthorReviewRevisionsGridHandler
|
||||
* @ingroup js_controllers_grid
|
||||
*
|
||||
* @brief Author revisions grid handler.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Define the namespace
|
||||
*/
|
||||
$.pkp.controllers.grid.files = $.pkp.controllers.grid.files ||
|
||||
{ review: {} };
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.grid.GridHandler
|
||||
*
|
||||
* @param {jQueryObject} $grid The grid this handler is
|
||||
* attached to.
|
||||
* @param {Object} options Grid handler configuration.
|
||||
*/
|
||||
$.pkp.controllers.grid.files.review.AuthorReviewRevisionsGridHandler = function(
|
||||
$grid, options) {
|
||||
this.parent($grid, options);
|
||||
this.bindGlobal('refreshRevisionsGrid', function() {
|
||||
this.refreshGridHandler();
|
||||
});
|
||||
};
|
||||
$.pkp.classes.Helper.inherits($.pkp.controllers.grid.files.review.
|
||||
AuthorReviewRevisionsGridHandler, $.pkp.controllers.grid.GridHandler);
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* @file js/controllers/grid/navigationMenus/form/NavigationMenuFormHandler.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 NavigationMenuFormHandler
|
||||
* @ingroup js_controllers_grid_navigationMenus_form
|
||||
*
|
||||
* @brief NavigationMenuItems form handler.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Define the namespace
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus =
|
||||
$.pkp.controllers.grid.navigationMenus ||
|
||||
{ form: {} };
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.AjaxFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $formElement The form element
|
||||
* @param {Object} options Modal options.
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler =
|
||||
function($formElement, options) {
|
||||
|
||||
this.okButton_ = options.okButton;
|
||||
this.warningModalTitle_ = options.warningModalTitle;
|
||||
this.submenuWarning_ = options.submenuWarning;
|
||||
this.itemTypeConditionalWarnings_ = options.itemTypeConditionalWarnings;
|
||||
|
||||
$formElement.on('click', '.btnConditionalDisplay',
|
||||
this.callbackWrapper(this.showConditionalDisplayWarning));
|
||||
$formElement.on('click', '.btnSubmenuWarning',
|
||||
this.callbackWrapper(this.showSubmenuWarning));
|
||||
|
||||
this.parent($formElement, options);
|
||||
this.initSorting();
|
||||
};
|
||||
|
||||
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler,
|
||||
$.pkp.controllers.form.AjaxFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* The label for the ok button on the modals displaying submenuWarning and
|
||||
* conditionalWarnings.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler
|
||||
.prototype.okButton_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The title of the modals displaying submenuWarning and conditionalWarnings.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler
|
||||
.prototype.warningModalTitle_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The warning message to display about submenus
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler
|
||||
.prototype.submenuWarning_ = undefined;
|
||||
|
||||
|
||||
/**
|
||||
* Warnings about the conditions of display for each item type.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler
|
||||
.prototype.itemTypeConditionalWarnings_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the .sortable() lists, limit nesting to one level deep and
|
||||
* ensure lists are formatted properly the CSS styles
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler.
|
||||
prototype.initSorting = function() {
|
||||
var self = this;
|
||||
|
||||
// Remove any submenu warning buttons
|
||||
$('.btnSubmenuWarning', this.getHtmlElement()).remove();
|
||||
|
||||
// Limit nesting to one level deep and ensure nested lists are formatted
|
||||
// properly for appropriate styles
|
||||
$('#pkpNavAssigned > li').each(
|
||||
function() {
|
||||
var $childList = $(this).children('ul'),
|
||||
$children = $childList.children(),
|
||||
$grandchildren = $children.find('li');
|
||||
|
||||
if (!$childList.length) {
|
||||
$(this).append('<ul></ul>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$children.length) {
|
||||
// Ensure it's just an empty ul (with no spaces) so the CSS
|
||||
// :empty psuedo class can be used
|
||||
$childList.replaceWith('<ul></ul>');
|
||||
} else {
|
||||
// Prevent nesting two levels deep by moving any items
|
||||
// nested at that level up one level.
|
||||
if ($grandchildren.length) {
|
||||
$grandchildren.each(function() {
|
||||
$(this).appendTo($childList);
|
||||
});
|
||||
}
|
||||
|
||||
// Add a submenu warning button
|
||||
if (!$(this).find(
|
||||
'> .item > .item_buttons .btnSubmenuWarning').length) {
|
||||
$(this).find('> .item > .item_buttons').prepend(
|
||||
$('<button></button>')
|
||||
.addClass('btnSubmenuWarning')
|
||||
.append(
|
||||
$('<span></span>')
|
||||
.addClass('fa fa-exclamation-triangle')
|
||||
)
|
||||
.append(
|
||||
$('<span></span>')
|
||||
.addClass('-screenReader')
|
||||
.text(self.submenuWarning_)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Reset any nesting that's been carried over from the assigned list
|
||||
$('#pkpNavUnassigned > li').each(
|
||||
function() {
|
||||
var $childList = $(this).children('ul');
|
||||
if ($childList.length) {
|
||||
$childList.find('li').each(function() {
|
||||
$(this).appendTo($('#pkpNavUnassigned'));
|
||||
});
|
||||
}
|
||||
$childList.remove();
|
||||
}
|
||||
);
|
||||
|
||||
// Initialize the sortable controls
|
||||
$('#pkpNavManagement ul').sortable({
|
||||
placeholder: 'pkp_nav_item_placeholder',
|
||||
delay: 250,
|
||||
connectWith: '#pkpNavManagement ul',
|
||||
update: this.callbackWrapper(this.updateSorting),
|
||||
start: function() {
|
||||
$('#pkpNavAssigned').addClass('pkp_is_sorting');
|
||||
},
|
||||
stop: function() {
|
||||
$('#pkpNavAssigned').removeClass('pkp_is_sorting');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Re-initialize the .sortable() components and generate the form fields
|
||||
* whenever the list is re-sorted.
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler.
|
||||
prototype.updateSorting = function() {
|
||||
var $navManagement = $('#pkpNavManagement'),
|
||||
seq = 0,
|
||||
parent = null,
|
||||
currentName = '';
|
||||
|
||||
// Re-intialize the sortable component after adjusting sort order
|
||||
this.initSorting();
|
||||
|
||||
// Remove existing hidden fields
|
||||
$('input', $navManagement).remove();
|
||||
|
||||
// Generate new hidden form fields
|
||||
$('#pkpNavAssigned > li').each(function() {
|
||||
currentName = 'menuTree[' + $(this).data('id') + ']';
|
||||
$navManagement.append('<input type="hidden" name="' +
|
||||
currentName + '[seq]" value="' +
|
||||
seq + '">');
|
||||
seq++;
|
||||
|
||||
var parentId = $(this).data('id');
|
||||
$(this).find('li').each(function() {
|
||||
currentName = 'menuTree[' + $(this).data('id') + ']';
|
||||
$navManagement.append('<input type="hidden" name="' +
|
||||
currentName + '[seq]" value="' +
|
||||
seq + '">');
|
||||
$navManagement.append('<input type="hidden" name="' +
|
||||
currentName + '[parentId]" value="' +
|
||||
parentId + '">');
|
||||
seq++;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the conditional display warning message
|
||||
* @param {jQueryObject} htmlElement The html element
|
||||
* @return {boolean}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler.
|
||||
prototype.showConditionalDisplayWarning = function(htmlElement) {
|
||||
var itemType = $(htmlElement).closest('li').data('type'),
|
||||
opts = {
|
||||
title: this.warningModalTitle_,
|
||||
okButton: this.okButton_,
|
||||
cancelButton: false,
|
||||
dialogText: this.itemTypeConditionalWarnings_[itemType]
|
||||
};
|
||||
|
||||
if (this.itemTypeConditionalWarnings_[itemType] !== null) {
|
||||
$('<div id="' + $.pkp.classes.Helper.uuid() + '" ' +
|
||||
'class="pkp_modal pkpModalWrapper" tabindex="-1"></div>')
|
||||
.pkpHandler('$.pkp.controllers.modal.ConfirmationModalHandler', opts);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the submenu link warning message
|
||||
* @return {boolean}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuFormHandler.
|
||||
prototype.showSubmenuWarning = function() {
|
||||
|
||||
var opts = {
|
||||
title: this.warningModalTitle_,
|
||||
okButton: this.okButton_,
|
||||
cancelButton: false,
|
||||
dialogText: this.submenuWarning_
|
||||
};
|
||||
|
||||
$('<div id="' + $.pkp.classes.Helper.uuid() + '" ' +
|
||||
'class="pkp_modal pkpModalWrapper" tabindex="-1"></div>')
|
||||
.pkpHandler('$.pkp.controllers.modal.ConfirmationModalHandler', opts);
|
||||
|
||||
return false;
|
||||
};
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* @file js/controllers/grid/navigationMenus/form/NavigationMenuItemsFormHandler.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 NavigationMenuItemsFormHandler
|
||||
* @ingroup js_controllers_grid_navigationMenus_form
|
||||
*
|
||||
* @brief NavigationMenuItems form handler.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.AjaxFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $formElement A wrapped HTML element that
|
||||
* represents the form interface element.
|
||||
* @param {Object} options javascript form options.
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuItemsFormHandler =
|
||||
function($formElement, options) {
|
||||
|
||||
this.parent($formElement, options);
|
||||
|
||||
this.previewUrl_ = options.previewUrl;
|
||||
this.itemTypeDescriptions_ = options.itemTypeDescriptions;
|
||||
this.itemTypeConditionalWarnings_ = options.itemTypeConditionalWarnings;
|
||||
|
||||
$('#previewButton', $formElement).click(this.callbackWrapper(
|
||||
this.showPreview_));
|
||||
|
||||
$('#menuItemType', $formElement).change(this.callbackWrapper(this.setType));
|
||||
$('#menuItemType', $formElement).trigger('change');
|
||||
};
|
||||
|
||||
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuItemsFormHandler,
|
||||
$.pkp.controllers.form.AjaxFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* The preview url.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.
|
||||
NavigationMenuItemsFormHandler.prototype.previewUrl_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Descriptions for each item type.
|
||||
* @private
|
||||
* @type {?Object}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.
|
||||
NavigationMenuItemsFormHandler.prototype.itemTypeDescriptions_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Warnings about the conditions of display for each item type.
|
||||
* @private
|
||||
* @type {?Object}
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.
|
||||
NavigationMenuItemsFormHandler.prototype
|
||||
.itemTypeConditionalWarnings_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Callback triggered on clicking the "preview"
|
||||
* button to open a preview window.
|
||||
*
|
||||
* @param {HTMLElement} submitButton The submit button.
|
||||
* @param {Event} event The event that triggered the
|
||||
* submit button.
|
||||
* @return {boolean} true.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuItemsFormHandler.
|
||||
prototype.showPreview_ = function(submitButton, event) {
|
||||
|
||||
var $formElement = this.getHtmlElement();
|
||||
$.post(this.previewUrl_,
|
||||
$formElement.serialize(),
|
||||
function(data) {
|
||||
var win = window.open('about:blank');
|
||||
win.document.open();
|
||||
win.document.write(data);
|
||||
win.document.close();
|
||||
}
|
||||
);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback triggered when the type is set
|
||||
*/
|
||||
$.pkp.controllers.grid.navigationMenus.form.NavigationMenuItemsFormHandler.
|
||||
prototype.setType = function() {
|
||||
var itemType = $('#menuItemType', this.getHtmlElement()).val(),
|
||||
$descriptionEl = $('#menuItemTypeSection [for="menuItemType"]');
|
||||
|
||||
$('.NMI_TYPE_CUSTOM_EDIT', this.getHtmlElement()).hide();
|
||||
$('#' + itemType).fadeIn();
|
||||
|
||||
if (typeof this.itemTypeDescriptions_[itemType] !== 'undefined') {
|
||||
$descriptionEl.text(this.itemTypeDescriptions_[itemType]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* @file js/controllers/grid/notifications/NotificationsGridHandler.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 NotificationsGridHandler
|
||||
* @ingroup js_controllers_grid
|
||||
*
|
||||
* @brief Category grid handler.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
// Define the namespace.
|
||||
$.pkp.controllers.grid.notifications =
|
||||
$.pkp.controllers.grid.notifications || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.grid.GridHandler
|
||||
*
|
||||
* @param {jQueryObject} $grid The grid this handler is
|
||||
* attached to.
|
||||
* @param {Object} options Grid handler configuration.
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler =
|
||||
function($grid, options) {
|
||||
|
||||
$grid.find('a[id*="markNew"]').click(
|
||||
this.callbackWrapper(this.markNewHandler_));
|
||||
|
||||
$grid.find('a[id*="markRead"]').click(
|
||||
this.callbackWrapper(this.markReadHandler_));
|
||||
|
||||
$grid.find('a[id*="deleteNotification"]').click(
|
||||
this.callbackWrapper(this.deleteHandler_));
|
||||
|
||||
this.parent($grid, options);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits($.pkp.controllers.grid.notifications
|
||||
.NotificationsGridHandler, $.pkp.controllers.grid.GridHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The CSRF token for POST requests.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler
|
||||
.prototype.csrfToken_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The "mark notifications as new" URL
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler
|
||||
.prototype.markNewUrl_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The "mark notifications as read" URL
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler
|
||||
.prototype.markReadUrl_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The "delete notifications" URL
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler
|
||||
.prototype.deleteUrl_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Extended methods from GridHandler
|
||||
//
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler.
|
||||
prototype.initialize = function(options) {
|
||||
|
||||
// Save the URLs to interact with selected sets of notifications
|
||||
this.markNewUrl_ = options.markNewUrl;
|
||||
this.markReadUrl_ = options.markReadUrl;
|
||||
this.deleteUrl_ = options.deleteUrl;
|
||||
|
||||
this.csrfToken_ = options.csrfToken;
|
||||
|
||||
this.parent('initialize', options);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
/**
|
||||
* Get the array of selected notifications
|
||||
* @private
|
||||
* @return {Array} List of selected notification IDs.
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler.prototype.
|
||||
getSelectedNotifications_ = function() {
|
||||
var selectedElements = [];
|
||||
this.getHtmlElement().find('input:checkbox:checked').each(function() {
|
||||
selectedElements.push($(this).val());
|
||||
});
|
||||
return selectedElements;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback that will be activated when the "mark new" icon is clicked
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Object} callingContext The calling element or object.
|
||||
* @param {Event=} opt_event The triggering event (e.g. a click on
|
||||
* a button.
|
||||
* @return {boolean} Should return false to stop event processing.
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler.prototype.
|
||||
markNewHandler_ = function(callingContext, opt_event) {
|
||||
$.post(this.markNewUrl_, {selectedElements: this.getSelectedNotifications_(),
|
||||
csrfToken: this.csrfToken_},
|
||||
this.callbackWrapper(this.responseHandler_, null), 'json');
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback that will be activated when the "mark read" icon is clicked
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Object} callingContext The calling element or object.
|
||||
* @param {Event=} opt_event The triggering event (e.g. a click on
|
||||
* a button.
|
||||
* @return {boolean} Should return false to stop event processing.
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler.prototype.
|
||||
markReadHandler_ = function(callingContext, opt_event) {
|
||||
$.post(this.markReadUrl_,
|
||||
{selectedElements: this.getSelectedNotifications_(),
|
||||
csrfToken: this.csrfToken_},
|
||||
this.callbackWrapper(this.responseHandler_, null), 'json');
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback that will be activated when the "delete" icon is clicked
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Object} callingContext The calling element or object.
|
||||
* @param {Event=} opt_event The triggering event (e.g. a click on
|
||||
* a button.
|
||||
* @return {boolean} Should return false to stop event processing.
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler.prototype.
|
||||
deleteHandler_ = function(callingContext, opt_event) {
|
||||
$.post(this.deleteUrl_, {selectedElements: this.getSelectedNotifications_(),
|
||||
csrfToken: this.csrfToken_},
|
||||
this.callbackWrapper(this.responseHandler_, null), 'json');
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback after a response returns from the server.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Object} ajaxContext The AJAX request context.
|
||||
* @param {Object} jsonData A parsed JSON response object.
|
||||
*/
|
||||
$.pkp.controllers.grid.notifications.NotificationsGridHandler.prototype.
|
||||
responseHandler_ = function(ajaxContext, jsonData) {
|
||||
|
||||
// Bounce the selected notification IDs back to the server
|
||||
// so that selections can be maintained
|
||||
var params = this.getFetchExtraParams();
|
||||
params.selectedNotificationIds = jsonData.content;
|
||||
this.setFetchExtraParams(params);
|
||||
|
||||
// Pass through the JSON handler to cause the grid to be
|
||||
// refreshed.
|
||||
this.handleJson(jsonData);
|
||||
};
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_queries
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/queries/QueryFormHandler.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 ReadQueryHandler
|
||||
* @ingroup js_controllers_grid_queries
|
||||
*
|
||||
* @brief Handler for a query form modal
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.queries =
|
||||
$.pkp.controllers.grid.queries || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.CancelActionAjaxFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form The query form element
|
||||
* @param {Object} options non-default Dialog options
|
||||
* to be passed into the dialog widget.
|
||||
*
|
||||
* Options are:
|
||||
* - all options documented for the CancelActionAjaxFormHandler.
|
||||
* - templateUrl: The URL to retrieve templates from.
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.QueryFormHandler =
|
||||
function($form, options) {
|
||||
this.parent($form, options);
|
||||
|
||||
// Set the URL to retrieve templates from.
|
||||
if (options.templateUrl) {
|
||||
this.templateUrl_ = options.templateUrl;
|
||||
}
|
||||
|
||||
// Attach form elements events.
|
||||
$form.find('#template').change(
|
||||
this.callbackWrapper(this.selectTemplateHandler_));
|
||||
};
|
||||
$.pkp.classes.Helper.inherits($.pkp.controllers.grid.queries.
|
||||
QueryFormHandler, $.pkp.controllers.form.CancelActionAjaxFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The URL to use to retrieve template bodies
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.
|
||||
QueryFormHandler.prototype.templateUrl_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Respond to an "item selected" call by triggering a published event.
|
||||
*
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.
|
||||
QueryFormHandler.prototype.selectTemplateHandler_ =
|
||||
function(sourceElement, event) {
|
||||
var $form = this.getHtmlElement(),
|
||||
template = $form.find('[name="template"]');
|
||||
$.post(this.templateUrl_, template.serialize(),
|
||||
this.callbackWrapper(this.updateTemplate), 'json');
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Internal callback to replace the textarea with the contents of the
|
||||
* template body.
|
||||
*
|
||||
* @param {HTMLElement} formElement The wrapped HTML form.
|
||||
* @param {Object} jsonData The data returned from the server.
|
||||
* @return {boolean} The response status.
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.
|
||||
QueryFormHandler.prototype.updateTemplate =
|
||||
function(formElement, jsonData) {
|
||||
|
||||
var $form = this.getHtmlElement(),
|
||||
processedJsonData = this.handleJson(jsonData),
|
||||
jsonDataContent =
|
||||
/** @type {{variables: Object, body: string}} */ (jsonData.content),
|
||||
$textarea = $form.find('textarea[name="comment"]'),
|
||||
editor =
|
||||
tinyMCE.EditorManager.get(/** @type {string} */ ($textarea.attr('id')));
|
||||
|
||||
if (jsonDataContent.variables) {
|
||||
$textarea.attr('data-variables', JSON.stringify(jsonDataContent.variables));
|
||||
}
|
||||
editor.setContent(jsonDataContent.body);
|
||||
$form.find('[name="subject"]').val(jsonDataContent.subject);
|
||||
|
||||
return processedJsonData.status;
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_queries
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/queries/ReadQueryHandler.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 ReadQueryHandler
|
||||
* @ingroup js_controllers_grid_queries
|
||||
*
|
||||
* @brief Handler for a "read query" modal
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.queries =
|
||||
$.pkp.controllers.grid.queries || { };
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.classes.Handler
|
||||
*
|
||||
* @param {jQueryObject} $containerElement The HTML element encapsulating
|
||||
* the carousel container.
|
||||
* @param {Object} options Handler options.
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler =
|
||||
function($containerElement, options) {
|
||||
|
||||
this.fetchNoteFormUrl_ = options.fetchNoteFormUrl;
|
||||
this.fetchParticipantsListUrl_ = options.fetchParticipantsListUrl;
|
||||
|
||||
$containerElement.find('.openNoteForm a').click(
|
||||
this.callbackWrapper(this.showNoteFormHandler_));
|
||||
|
||||
$containerElement.bind('dataChanged',
|
||||
this.callbackWrapper(this.reloadParticipantsList_));
|
||||
|
||||
$containerElement.bind('user-left-discussion', function() {
|
||||
$containerElement.parent().trigger('modalFinished');
|
||||
});
|
||||
|
||||
this.loadParticipantsList();
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler,
|
||||
$.pkp.classes.Handler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The URL to be called to fetch a new note form for a query.
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler.
|
||||
prototype.fetchNoteFormUrl_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The URL to be called to fetch a list of participants.
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler.
|
||||
prototype.fetchParticipantsListUrl_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Load the participants list.
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler.prototype.
|
||||
loadParticipantsList = function() {
|
||||
$.get(this.fetchParticipantsListUrl_,
|
||||
this.callbackWrapper(this.showFetchedParticipantsList_), 'json');
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Event handler that is called when the "new note" button is clicked.
|
||||
* @param {HTMLElement} element The checkbox input element.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler.prototype.
|
||||
showNoteFormHandler_ = function(element) {
|
||||
$(element).parents('.queryEditButtons').addClass('is_loading');
|
||||
$.get(this.fetchNoteFormUrl_,
|
||||
this.callbackWrapper(this.showFetchedNoteForm_), 'json');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event handler that is called when the new note form is ready.
|
||||
* @param {Object} ajaxContext The AJAX request context.
|
||||
* @param {Object} jsonData A parsed JSON response object.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler.prototype.
|
||||
showFetchedNoteForm_ = function(ajaxContext, jsonData) {
|
||||
|
||||
var processedJsonData = this.handleJson(jsonData),
|
||||
$noteFormContainer = $('#newNotePlaceholder', this.getHtmlElement()),
|
||||
$queryEditButtons = $('.queryEditButtons.is_loading',
|
||||
this.getHtmlElement());
|
||||
|
||||
this.unbindPartial($queryEditButtons);
|
||||
$queryEditButtons.remove();
|
||||
this.unbindPartial($noteFormContainer);
|
||||
$noteFormContainer.html(processedJsonData.content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event handler that is called when the participants list fetch is complete.
|
||||
* @param {Object} ajaxContext The AJAX request context.
|
||||
* @param {Object} jsonData A parsed JSON response object.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler.prototype.
|
||||
showFetchedParticipantsList_ = function(ajaxContext, jsonData) {
|
||||
|
||||
var processedJsonData = this.handleJson(jsonData),
|
||||
$participantsListContainer = $('#participantsListPlaceholder',
|
||||
this.getHtmlElement()),
|
||||
$leaveQueryButton = $('.leaveQueryForm', this.getHtmlElement());
|
||||
|
||||
if (processedJsonData.showLeaveQueryButton) {
|
||||
$leaveQueryButton.show();
|
||||
} else {
|
||||
$leaveQueryButton.hide();
|
||||
}
|
||||
|
||||
this.unbindPartial($participantsListContainer);
|
||||
$participantsListContainer.children().remove();
|
||||
$participantsListContainer.append(processedJsonData.content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler to update the participants list on change.
|
||||
* @param {HTMLElement} sourceElement The element that issued the
|
||||
* "dataChanged" event.
|
||||
* @param {Event} event The "dataChanged" event.
|
||||
* @param {HTMLElement} triggerElement The element that triggered
|
||||
* the "dataChanged" event.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.queries.ReadQueryHandler.prototype.
|
||||
reloadParticipantsList_ = function(sourceElement, event, triggerElement) {
|
||||
this.loadParticipantsList();
|
||||
};
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_representations_form
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/representations/form/RepresentationFormHandler.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 RepresentationFormHandler
|
||||
* @ingroup js_controllers_grid_representations_form
|
||||
*
|
||||
* @brief Handle the representations forms.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.representations =
|
||||
$.pkp.controllers.grid.representations ||
|
||||
{ form: { } };
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.AjaxFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped page element.
|
||||
* @param {Object} options handler options.
|
||||
*/
|
||||
$.pkp.controllers.grid.representations.form.RepresentationFormHandler =
|
||||
function($form, options) {
|
||||
this.parent($form, options);
|
||||
|
||||
this.remoteRepresentation_ = options.remoteRepresentation;
|
||||
if (this.remoteRepresentation_) {
|
||||
$('#remotelyHostedContent').prop('checked', true);
|
||||
$('#remote').show(20);
|
||||
$('#urlPathSection').hide();
|
||||
} else {
|
||||
$('#remotelyHostedContent').prop('checked', false);
|
||||
$('#remote').hide();
|
||||
$('#urlPathSection').show(20);
|
||||
}
|
||||
|
||||
$('#remotelyHostedContent').change(this.callbackWrapper(this.toggleRemote_));
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.representations.form.RepresentationFormHandler,
|
||||
$.pkp.controllers.form.AjaxFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
/**
|
||||
* Internal callback called on checkbox change to show or hide
|
||||
* remote URL input field.
|
||||
* @private
|
||||
* @param {HTMLElement} element The remotely hosted content checkbox.
|
||||
* @param {Event} event The event that triggered the checkbox.
|
||||
* @return {boolean} true.
|
||||
*/
|
||||
$.pkp.controllers.grid.representations.form.RepresentationFormHandler.
|
||||
prototype.toggleRemote_ = function(element, event) {
|
||||
|
||||
if ($('#remotelyHostedContent').prop('checked')) {
|
||||
// show the remote URL input field
|
||||
$('#remote').show(20);
|
||||
$('#urlPathSection').hide();
|
||||
$('input[id^="urlPath"]').val('');
|
||||
} else {
|
||||
// hide and clear the remote URL input field
|
||||
$('#remote').hide(20);
|
||||
$('input[id^="urlRemote"]').val('');
|
||||
$('#urlPathSection').show(20);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_roles_form Role form javascript
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/settings/roles/form/UserGroupFormHandler.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 UserGroupFormHandler
|
||||
* @ingroup js_controllers_grid_settings_roles_form
|
||||
*
|
||||
* @brief Handle the role create/edit form.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.settings.roles =
|
||||
$.pkp.controllers.grid.settings.roles || { form: { }};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.AjaxFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped HTML form element.
|
||||
* @param {{
|
||||
* selfRegistrationRoleIds: Array,
|
||||
* roleForbiddenStagesJSON: Object.<string, *>,
|
||||
* stagesSelector: string
|
||||
* }} options form options.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler =
|
||||
function($form, options) {
|
||||
|
||||
var $roleId = $('[id^="roleId"]', $form);
|
||||
|
||||
this.parent($form, options);
|
||||
|
||||
// Set the role IDs for which the self-registration checkbox
|
||||
// is relevant.
|
||||
if (options.selfRegistrationRoleIds) {
|
||||
this.selfRegistrationRoleIds_ = options.selfRegistrationRoleIds;
|
||||
}
|
||||
|
||||
// Set the role IDs for which the recommendOnly checkbox
|
||||
// is relevant.
|
||||
if (options.recommendOnlyRoleIds) {
|
||||
this.recommendOnlyRoleIds_ = options.recommendOnlyRoleIds;
|
||||
}
|
||||
|
||||
// Set the roles that are not able to change
|
||||
// submission metadata edit perissions
|
||||
if (options.notChangeMetadataEditPermissionRoles) {
|
||||
this.notChangeMetadataEditPermissionRoles_ =
|
||||
options.notChangeMetadataEditPermissionRoles;
|
||||
}
|
||||
|
||||
this.roleForbiddenStages_ = options.roleForbiddenStagesJSON.content;
|
||||
this.stagesSelector_ = options.stagesSelector;
|
||||
|
||||
// Initialize the "permit self register" checkbox disabled
|
||||
// state based on the form's current selection
|
||||
this.updatePermitSelfRegistration(
|
||||
/** @type {string} */ ($roleId.val()));
|
||||
|
||||
// Initialize the "permit metadata edit" checkbox disabled
|
||||
// state based on the form's current selection
|
||||
this.updatePermitMetadataEdit(
|
||||
/** @type {string} */ ($roleId.val()), false);
|
||||
|
||||
// ...also initialize the stage options, disabling the ones
|
||||
// that are forbidden for the current role.
|
||||
this.updateStageOptions(
|
||||
/** @type {string} */ ($roleId.val()));
|
||||
|
||||
// ...also initialize the recommendOnly option, disabling it
|
||||
// if it is forbidden for the current role.
|
||||
this.updateRecommendOnly(
|
||||
/** @type {string} */ ($roleId.val()));
|
||||
|
||||
// ...and make sure both it's updated when changing roles.
|
||||
$roleId.change(this.callbackWrapper(this.changeRoleId));
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler,
|
||||
$.pkp.controllers.form.AjaxFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The list of self-registration role IDs
|
||||
* @private
|
||||
* @type {Object?}
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.
|
||||
UserGroupFormHandler.prototype.selfRegistrationRoleIds_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* A list of role forbidden stages.
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.
|
||||
UserGroupFormHandler.prototype.roleForbiddenStages_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The stage options selector.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.
|
||||
UserGroupFormHandler.prototype.stagesSelector_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The list of not allowed to change submission metadata edit permissions roles
|
||||
* @private
|
||||
* @type {Object?}
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.
|
||||
UserGroupFormHandler.prototype.notChangeMetadataEditPermissionRoles_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
/**
|
||||
* Event handler that is called when the role ID dropdown is changed.
|
||||
* @param {string} dropdown The dropdown input element.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler.prototype.
|
||||
changeRoleId = function(dropdown) {
|
||||
|
||||
var dropDownValue = /** @type {string} */ ($(dropdown).val());
|
||||
|
||||
this.updatePermitSelfRegistration((dropDownValue));
|
||||
this.updatePermitMetadataEdit(/** @type {string} */ (dropDownValue), true);
|
||||
|
||||
// Also update the stages options.
|
||||
this.updateStageOptions(/** @type {string} */ (dropDownValue));
|
||||
|
||||
this.updateRecommendOnly(/** @type {string} */ (dropDownValue));
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the enabled/disabled state of the permitSelfRegistration
|
||||
* checkbox.
|
||||
* @param {number|string} roleId The role ID to select.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler.prototype.
|
||||
updatePermitSelfRegistration = function(roleId) {
|
||||
|
||||
// JQuerify the element
|
||||
var $checkbox = $('[id^="permitSelfRegistration"]'),
|
||||
$form = this.getHtmlElement(),
|
||||
i,
|
||||
found = false;
|
||||
|
||||
for (i = 0; i < this.selfRegistrationRoleIds_.length; i++) {
|
||||
if (this.selfRegistrationRoleIds_[i] == roleId) {
|
||||
found = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
$checkbox.removeAttr('disabled');
|
||||
} else {
|
||||
$checkbox.attr('disabled', 'disabled');
|
||||
$checkbox.removeAttr('checked');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the enabled/disabled state of the PermitMetadataEdit
|
||||
* checkbox.
|
||||
* @param {number|string} roleId The role ID to select.
|
||||
* @param {boolean} roleIdChanged True iff the role ID changed.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler.prototype.
|
||||
updatePermitMetadataEdit = function(roleId, roleIdChanged) {
|
||||
var i, $checkbox = $('[id^="permitMetadataEdit"]'),
|
||||
found = false;
|
||||
|
||||
for (i = 0; i < this.notChangeMetadataEditPermissionRoles_.length; i++) {
|
||||
if (this.notChangeMetadataEditPermissionRoles_[i] == roleId) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If found then the check box should be disabled and checked
|
||||
if (found) {
|
||||
$checkbox.attr('disabled', 'disabled');
|
||||
$checkbox.attr('checked', 'checked');
|
||||
$checkbox.prop('checked', 'checked');
|
||||
} else {
|
||||
$checkbox.removeAttr('disabled');
|
||||
if (roleIdChanged) {
|
||||
$checkbox.removeAttr('checked');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the stage options.
|
||||
* @param {number|string} roleId The role ID to select.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler.prototype.
|
||||
updateStageOptions = function(roleId) {
|
||||
|
||||
// JQuerify the element
|
||||
var $htmlElement = this.getHtmlElement(),
|
||||
$stageContainer = $htmlElement.find('#userGroupStageContainer'),
|
||||
$stageOptions = $(this.stagesSelector_, $htmlElement).filter('input'),
|
||||
i,
|
||||
stageId = null;
|
||||
|
||||
$stageOptions.removeAttr('disabled');
|
||||
|
||||
if (this.roleForbiddenStages_[roleId] != undefined) {
|
||||
for (i = 0; i < this.roleForbiddenStages_[roleId].length; i++) {
|
||||
stageId = this.roleForbiddenStages_[roleId][i];
|
||||
$stageOptions.filter('input[value="' + stageId + '"]').
|
||||
attr('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
|
||||
if ($htmlElement.find(
|
||||
'input[id^=\'assignedStages-\']:enabled').length == 0) {
|
||||
$stageContainer.hide('slow');
|
||||
$('#showTitle').attr('disabled', 'disabled');
|
||||
} else {
|
||||
$stageContainer.show('slow');
|
||||
$('#showTitle').removeAttr('disabled');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the enabled/disabled state of the recommendOnly checkbox.
|
||||
* @param {number|string} roleId The role ID to select.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.roles.form.UserGroupFormHandler.prototype.
|
||||
updateRecommendOnly = function(roleId) {
|
||||
|
||||
// JQuerify the element
|
||||
var $checkbox = $('[id^=\'recommendOnly\']', this.getHtmlElement()),
|
||||
i,
|
||||
found = false;
|
||||
|
||||
for (i = 0; i < this.recommendOnlyRoleIds_.length; i++) {
|
||||
if (this.recommendOnlyRoleIds_[i] == roleId) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
$checkbox.removeAttr('disabled');
|
||||
} else {
|
||||
$checkbox.attr('disabled', 'disabled');
|
||||
$checkbox.removeAttr('checked');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_users_user_form User form javascript
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/settings/user/form/UserDetailsFormHandler.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 UserDetailsFormHandler
|
||||
* @ingroup js_controllers_grid_settings_user_form
|
||||
*
|
||||
* @brief Handle the user settings form.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.settings =
|
||||
$.pkp.controllers.grid.settings || { user: { form: { } }};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.UserFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped HTML form element.
|
||||
* @param {Object} options form options.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.user.form.UserDetailsFormHandler =
|
||||
function($form, options) {
|
||||
|
||||
this.parent($form, options);
|
||||
|
||||
// Attach form elements events.
|
||||
$('[id^="generatePassword"]', $form).click(
|
||||
this.callbackWrapper(this.setGenerateRandom));
|
||||
|
||||
// Check the generate password check box.
|
||||
if ($('[id^="generatePassword"]', $form).attr('checked')) {
|
||||
this.setGenerateRandom('[id^="generatePassword"]');
|
||||
}
|
||||
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.settings.user.form.UserDetailsFormHandler,
|
||||
$.pkp.controllers.form.UserFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Public methods.
|
||||
//
|
||||
/**
|
||||
* @see AjaxFormHandler::submitForm
|
||||
* @param {Object} validator The validator plug-in.
|
||||
* @param {HTMLElement} formElement The wrapped HTML form.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.user.form.UserDetailsFormHandler.prototype.
|
||||
submitForm = function(validator, formElement) {
|
||||
|
||||
var $form = this.getHtmlElement();
|
||||
$(':password', $form).removeAttr('disabled');
|
||||
this.parent('submitForm', validator, formElement);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Event handler that is called when generate password checkbox is
|
||||
* clicked.
|
||||
* @param {string} checkbox The checkbox input element.
|
||||
*/
|
||||
$.pkp.controllers.grid.settings.user.form.UserDetailsFormHandler.prototype.
|
||||
setGenerateRandom = function(checkbox) {
|
||||
|
||||
// JQuerify the element
|
||||
var $checkbox = $(checkbox),
|
||||
$form = this.getHtmlElement(),
|
||||
passwordValue = '',
|
||||
activeAndCheck = 0;
|
||||
|
||||
if ($checkbox.prop('checked')) {
|
||||
passwordValue = '********';
|
||||
activeAndCheck = 'disabled';
|
||||
} else {
|
||||
passwordValue = '';
|
||||
activeAndCheck = '';
|
||||
}
|
||||
$(':password', $form).
|
||||
prop('disabled', activeAndCheck).val(passwordValue);
|
||||
$('[id^="sendNotify"]', $form).attr('disabled', activeAndCheck).
|
||||
prop('checked', activeAndCheck);
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file js/controllers/grid/users/UserGridHandler.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 UserGridHandler
|
||||
* @ingroup js_controllers_grid
|
||||
*
|
||||
* @brief User grid handler. Used to keep user grids in sync, such as when
|
||||
* merging users.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
// Define the namespace.
|
||||
$.pkp.controllers.grid.users = $.pkp.controllers.grid.users || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.grid.GridHandler
|
||||
*
|
||||
* @param {jQueryObject} $grid The grid this handler is
|
||||
* attached to.
|
||||
* @param {Object} options Grid handler configuration.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.UserGridHandler =
|
||||
function($grid, options) {
|
||||
this.parent($grid, options);
|
||||
|
||||
this.bindGlobal('userMerged', function() {
|
||||
|
||||
// Signal to any parent modals that they can close now
|
||||
this.trigger('modalFinished');
|
||||
|
||||
this.refreshGridHandler();
|
||||
});
|
||||
|
||||
// Refresh the grid when a user group has been added/edited
|
||||
this.bindGlobal('userGroupUpdated', function() {
|
||||
this.refreshGridHandler();
|
||||
});
|
||||
};
|
||||
$.pkp.classes.Helper.inherits($.pkp.controllers.grid.users.UserGridHandler,
|
||||
$.pkp.controllers.grid.GridHandler);
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_users_stageParticipant_form
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/AdvancedReviewerSearchHandler.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 AdvancedReviewerSearchHandler
|
||||
* @ingroup js_controllers
|
||||
*
|
||||
* @brief Handle the advanced reviewer search tab in the add reviewer modal.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.users.reviewer =
|
||||
$.pkp.controllers.grid.users.reviewer || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.classes.Handler
|
||||
*
|
||||
* @param {jQueryObject} $container the wrapped page element.
|
||||
* @param {Object} options handler options.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.AdvancedReviewerSearchHandler =
|
||||
function($container, options) {
|
||||
this.parent($container, options);
|
||||
|
||||
$container.find('.button').button();
|
||||
|
||||
pkp.eventBus.$on('selected:reviewer', function(reviewer) {
|
||||
$('#reviewerId').val(reviewer.id);
|
||||
$('[id^="selectedReviewerName"]').text(reviewer.fullName);
|
||||
$('#searchGridAndButton').hide();
|
||||
$('#regularReviewerForm').show();
|
||||
|
||||
// Set the email message for reviewers depending
|
||||
// on previous completed assignments
|
||||
var $textarea = $('#reviewerFormFooter [name="personalMessage"]'),
|
||||
$templateInput,
|
||||
$templateOption,
|
||||
editor,
|
||||
templateKey;
|
||||
if ($textarea.val()) {
|
||||
return; // The message is already set; shouldn't happen
|
||||
}
|
||||
// Only 1 template available
|
||||
$templateInput = $('#reviewerFormFooter input[name="template"]');
|
||||
// Multiple available templates
|
||||
$templateOption = $('#reviewerFormFooter select[name="template"]');
|
||||
editor = tinyMCE.EditorManager.get($textarea.attr('id'));
|
||||
templateKey = '';
|
||||
if (options.lastRoundReviewerIds.includes(reviewer.id)) {
|
||||
templateKey = 'REVIEW_REQUEST_SUBSEQUENT';
|
||||
editor.setContent(options.reviewerMessages[templateKey]);
|
||||
$templateInput.val(templateKey);
|
||||
$templateOption.find('[value="REVIEW_REQUEST"]').remove();
|
||||
} else {
|
||||
templateKey = 'REVIEW_REQUEST';
|
||||
editor.setContent(options.reviewerMessages[templateKey]);
|
||||
$templateInput.val(templateKey);
|
||||
$templateOption.find('[value="REVIEW_REQUEST_SUBSEQUENT"]').remove();
|
||||
}
|
||||
// Select the right template option to correspond
|
||||
// the one, which is set in TinyMCE
|
||||
$templateOption.find('[value="' + templateKey + '"]')
|
||||
.prop('selected', true);
|
||||
});
|
||||
|
||||
$('#regularReviewerForm').hide();
|
||||
|
||||
this.bind('refreshForm', this.handleRefresh_);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.users.reviewer.AdvancedReviewerSearchHandler,
|
||||
$.pkp.classes.Handler);
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Handle the form refresh event.
|
||||
* @private
|
||||
* @param {HTMLElement} sourceElement The element that issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
* @param {string} content HTML contents to replace element contents.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.AdvancedReviewerSearchHandler.prototype.
|
||||
handleRefresh_ = function(sourceElement, event, content) {
|
||||
|
||||
if (content) {
|
||||
this.replaceWith(content);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_users_reviewer
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/users/reviewer/ReadReviewHandler.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 ReadReviewHandler
|
||||
* @ingroup js_controllers_grid_users_reviewer
|
||||
*
|
||||
* @brief Handle the advanced reviewer search tab in the add reviewer modal.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.AjaxFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped page element.
|
||||
* @param {Object} options handler options.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.ReadReviewHandler =
|
||||
function($form, options) {
|
||||
this.parent($form, options);
|
||||
|
||||
this.reviewCompleted_ = options.reviewCompleted;
|
||||
// bind a handler to make sure that a review file has been uploaded.
|
||||
$form.find('[id^=\'submitFormButton-\']').click(this.callbackWrapper(
|
||||
this.reviewFilesRequired_));
|
||||
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.users.reviewer.ReadReviewHandler,
|
||||
$.pkp.controllers.form.AjaxFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
/**
|
||||
* Is the review completed.
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.ReadReviewHandler.
|
||||
prototype.reviewCompleted_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Internal callback called on form submit to ensure there are
|
||||
* some review files uploaded.
|
||||
* @private
|
||||
* @param {HTMLElement} submitButton The submit button.
|
||||
* @param {Event} event The event that triggered the
|
||||
* submit button.
|
||||
* @return {boolean} true.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.ReadReviewHandler.
|
||||
prototype.reviewFilesRequired_ = function(submitButton, event) {
|
||||
|
||||
if (!this.reviewCompleted_ && $('#readReviewAttachmentsGridContainer').
|
||||
find('tbody.empty:visible').length == 1) {
|
||||
// There's nothing in the files grid; don't submit the form
|
||||
this.showWarning_();
|
||||
return false;
|
||||
} else {
|
||||
// There's something in the files grid;
|
||||
this.hideWarning_();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hide the "no files" warning.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.ReadReviewHandler.
|
||||
prototype.hideWarning_ = function() {
|
||||
this.getHtmlElement().find('#noFilesWarning').hide(250);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the "no files" warning.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.ReadReviewHandler.
|
||||
prototype.showWarning_ = function() {
|
||||
this.getHtmlElement().find('#noFilesWarning').show(250);
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @file js/controllers/grid/users/reviewer/form/AddReviewerFormHandler.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 AddReviewerFormHandler
|
||||
* @ingroup js_controllers_grid_users_reviewer_form
|
||||
*
|
||||
* @brief Handle the Add Reviewer form (and template for message body).
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.grid.users.reviewer.form.EditReviewFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped HTML form element.
|
||||
* @param {Object} options form options.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
AddReviewerFormHandler = function($form, options) {
|
||||
|
||||
this.parent($form, options);
|
||||
|
||||
// Set the URL to retrieve templates from.
|
||||
if (options.templateUrl) {
|
||||
this.templateUrl_ = options.templateUrl;
|
||||
}
|
||||
|
||||
// Attach form elements events.
|
||||
$form.find('#template').change(
|
||||
this.callbackWrapper(this.selectTemplateHandler_));
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
AddReviewerFormHandler,
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
EditReviewFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The URL to use to retrieve template bodies
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
AddReviewerFormHandler.prototype.templateUrl_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
/**
|
||||
* Show the "no files" warning.
|
||||
* @protected
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.AddReviewerFormHandler.
|
||||
prototype.showWarning = function() {
|
||||
// Call the parent showWarning to show the warning
|
||||
this.parent('showWarning');
|
||||
|
||||
// Ask the reviewer form footer handler to expand the file
|
||||
// list extras-on-demand if it isn't already expanded.
|
||||
this.getHtmlElement().find('#reviewerFormFooter')
|
||||
.trigger('expandFileList');
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Respond to an "item selected" call by triggering a published event.
|
||||
*
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
AddReviewerFormHandler.prototype.selectTemplateHandler_ =
|
||||
function(sourceElement, event) {
|
||||
|
||||
var $form = this.getHtmlElement();
|
||||
$.post(this.templateUrl_, $form.find('#template').serialize(),
|
||||
this.callbackWrapper(this.updateTemplate), 'json');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Internal callback to replace the textarea with the contents of the
|
||||
* template body.
|
||||
*
|
||||
* @param {HTMLElement} formElement The wrapped HTML form.
|
||||
* @param {Object} jsonData The data returned from the server.
|
||||
* @return {boolean} The response status.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
AddReviewerFormHandler.prototype.updateTemplate =
|
||||
function(formElement, jsonData) {
|
||||
|
||||
var $form = this.getHtmlElement(),
|
||||
processedJsonData = this.handleJson(jsonData),
|
||||
$textarea = $form.find('textarea[name="personalMessage"]'),
|
||||
editor =
|
||||
tinyMCE.EditorManager.get(/** @type {string} */ ($textarea.attr('id')));
|
||||
|
||||
if (processedJsonData !== false) {
|
||||
if (processedJsonData.content !== '') {
|
||||
editor.setContent(processedJsonData.content);
|
||||
}
|
||||
}
|
||||
return processedJsonData.status;
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_users_reviewer_form
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/users/reviewer/form/EditReviewFormHandler.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 EditReviewFormHandler
|
||||
* @ingroup js_controllers_grid_users_reviewer_form
|
||||
*
|
||||
* @brief Handle the limit reviewer files form. Also used as a base class
|
||||
* for the add reviewer form handler.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.users.reviewer.form =
|
||||
$.pkp.controllers.grid.users.reviewer.form || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.UserFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped HTML form element.
|
||||
* @param {Object} options form options.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
EditReviewFormHandler = function($form, options) {
|
||||
|
||||
this.parent($form, options);
|
||||
|
||||
// When the form changes, check to see if a warning is necessary
|
||||
// (if all reviewer files are unchecked)
|
||||
$form.change(this.callbackWrapper(this.handleFormChange));
|
||||
|
||||
// When the reviewer files list loads, trigger the above check
|
||||
this.bind('urlInDivLoaded', this.handleFileListLoad_);
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.users.reviewer.form.
|
||||
EditReviewFormHandler,
|
||||
$.pkp.controllers.form.UserFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Protected methods.
|
||||
//
|
||||
/**
|
||||
* Handle a form change event.
|
||||
* @protected
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.EditReviewFormHandler.
|
||||
prototype.handleFormChange = function() {
|
||||
if (this.getHtmlElement()
|
||||
.find('input[name="selectedFiles[]"]:checked').length) {
|
||||
this.hideWarning();
|
||||
} else {
|
||||
this.showWarning();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hide the "no files" warning.
|
||||
* @protected
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.EditReviewFormHandler.
|
||||
prototype.hideWarning = function() {
|
||||
this.getHtmlElement().find('#noFilesWarning').hide(250);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the "no files" warning.
|
||||
* @protected
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.EditReviewFormHandler.
|
||||
prototype.showWarning = function() {
|
||||
this.getHtmlElement().find('#noFilesWarning').show(250);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
/**
|
||||
* Handle the loading of the reviewer files list.
|
||||
* @private
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
* @param {?string} data additional event data.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.reviewer.form.EditReviewFormHandler.
|
||||
prototype.handleFileListLoad_ =
|
||||
function(sourceElement, event, data) {
|
||||
|
||||
// Trigger a form change event to display the "no files
|
||||
// selected" warning, if necessary.
|
||||
this.getHtmlElement().change();
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file js/controllers/grid/users/stageParticipant/StageParticipantGridHandler.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 StageParticipantGridHandler
|
||||
* @ingroup js_controllers_grid
|
||||
*
|
||||
* @brief Stage participant grid handler.
|
||||
*/
|
||||
/*global pkp */
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.users.stageParticipant =
|
||||
$.pkp.controllers.grid.users.stageParticipant || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.grid.CategoryGridHandler
|
||||
*
|
||||
* @param {jQueryObject} $grid The grid this handler is
|
||||
* attached to.
|
||||
* @param {Object} options Grid handler configuration.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.StageParticipantGridHandler =
|
||||
function($grid, options) {
|
||||
this.parent($grid, options);
|
||||
|
||||
// Reload any editorial actions on the page.
|
||||
this.bind('dataChanged', function() {
|
||||
this.refreshGridHandler();
|
||||
$(['#submissionEditorDecisionsDiv',
|
||||
'#copyeditingEditorDecisionsDiv',
|
||||
'[id^=reviewDecisionsDiv]'].join(','))
|
||||
.each(function() {
|
||||
$.pkp.classes.Handler.getHandler($(this)).reload();
|
||||
});
|
||||
});
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.users.stageParticipant.StageParticipantGridHandler,
|
||||
$.pkp.controllers.grid.CategoryGridHandler);
|
||||
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_users_stageParticipant_form
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/users/stageParticipant/form/AddParticipantFormHandler.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 AddParticipantFormHandler
|
||||
* @ingroup js_controllers_grid_users_stageParticipant_form
|
||||
*
|
||||
* @brief Handle the search user filter and
|
||||
* add the value to the hidden userGroupId field.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.ClientFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped HTML form element.
|
||||
* @param {Object} options form options.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.AddParticipantFormHandler =
|
||||
function($form, options) {
|
||||
|
||||
this.parent($form, options);
|
||||
|
||||
$('select[name^=\'filterUserGroupId\']', $form).change(
|
||||
this.callbackWrapper(this.addUserGroupId));
|
||||
|
||||
$form.parent().click(function(e) {
|
||||
var $target = $(e.target), filterUserIdVal;
|
||||
if ($target.is('input[name="userId"]')) {
|
||||
filterUserIdVal = $('input[name=\'userId\']:checked').val();
|
||||
$('input[name=\'userIdSelected\']').val(
|
||||
filterUserIdVal).trigger('change');
|
||||
}
|
||||
});
|
||||
|
||||
// initially populate the input field.
|
||||
this.addUserGroupId();
|
||||
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
AddParticipantFormHandler,
|
||||
$.pkp.controllers.form.ClientFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
/**
|
||||
* Method to add the value to the hidden userGroupId field
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.AddParticipantFormHandler.
|
||||
prototype.addUserGroupId = function() {
|
||||
|
||||
var $form = this.getHtmlElement(),
|
||||
$filterUserGroupId = $form.find('select[name^=\'filterUserGroupId\']'),
|
||||
filterUserGroupIdVal = /** @type {string} */ ($filterUserGroupId.val());
|
||||
|
||||
$('input[name=\'userGroupId\']').val(filterUserGroupIdVal).trigger('change');
|
||||
};
|
||||
|
||||
|
||||
}(jQuery));
|
||||
+374
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* @defgroup js_controllers_grid_users_stageParticipant_form
|
||||
*/
|
||||
/**
|
||||
* @file js/controllers/grid/users/stageParticipant/form/StageParticipantNotifyHandler.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 StageParticipantNotifyHandler
|
||||
* @ingroup js_controllers_grid_users_stageParticipant_form
|
||||
*
|
||||
* @brief Handle Stage participant notification forms.
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
/** @type {Object} */
|
||||
$.pkp.controllers.grid.users.stageParticipant.form =
|
||||
$.pkp.controllers.grid.users.stageParticipant.form || {};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.controllers.form.AjaxFormHandler
|
||||
*
|
||||
* @param {jQueryObject} $form the wrapped HTML form element.
|
||||
* @param {Object} options form options.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler = function($form, options) {
|
||||
|
||||
this.parent($form, options);
|
||||
|
||||
// Set the URL to retrieve templates from.
|
||||
if (options.templateUrl) {
|
||||
this.templateUrl_ = options.templateUrl;
|
||||
}
|
||||
|
||||
// Set the user group IDs with the recommendOnly possibility
|
||||
if (options.possibleRecommendOnlyUserGroupIds) {
|
||||
this.possibleRecommendOnlyUserGroupIds_ =
|
||||
options.possibleRecommendOnlyUserGroupIds;
|
||||
}
|
||||
|
||||
// Set the user group IDs with the recommendOnly option set
|
||||
if (options.recommendOnlyUserGroupIds) {
|
||||
this.recommendOnlyUserGroupIds_ = options.recommendOnlyUserGroupIds;
|
||||
}
|
||||
|
||||
// Set the user group IDs that are not allowed to change the default
|
||||
// value of permitMetadataEdit
|
||||
if (options.notChangeMetadataEditPermissionRoles) {
|
||||
this.notChangeMetadataEditPermissionRoles_ =
|
||||
options.notChangeMetadataEditPermissionRoles;
|
||||
}
|
||||
|
||||
// Set the user group IDs that have the permitMetadataEdit flag set to true
|
||||
if (options.permitMetadataEditUserGroupIds) {
|
||||
this.permitMetadataEditUserGroupIds_ =
|
||||
options.permitMetadataEditUserGroupIds;
|
||||
}
|
||||
|
||||
if (options.anonymousReviewerIds) {
|
||||
this.anonymousReviewerIds_ = options.anonymousReviewerIds;
|
||||
}
|
||||
|
||||
if (options.anonymousReviewerWarning) {
|
||||
this.anonymousReviewerWarning_ = options.anonymousReviewerWarning;
|
||||
}
|
||||
|
||||
if (options.anonymousReviewerWarningOk) {
|
||||
this.anonymousReviewerWarningOk_ = options.anonymousReviewerWarningOk;
|
||||
}
|
||||
|
||||
// Update the recommendOnly option display when user group changes
|
||||
// or user is selected
|
||||
$('input[name=\'userGroupId\'], input[name=\'userIdSelected\']', $form)
|
||||
.change(this.callbackWrapper(this.updateRecommendOnly));
|
||||
|
||||
// Update the recommendOnly option display when user group changes
|
||||
// or user is selected
|
||||
$('input[name=\'userGroupId\'], input[name=\'userIdSelected\']', $form)
|
||||
.change(this.callbackWrapper(
|
||||
this.updateSubmissionMetadataEditPermitOption));
|
||||
|
||||
// Trigger a warning message if an anonymous reviewer is selected
|
||||
$('input[name=\'userIdSelected\']', $form)
|
||||
.change(this.callbackWrapper(this.maybeTriggerReviewerWarning));
|
||||
|
||||
// Attach form elements events.
|
||||
$form.find('#template').change(
|
||||
this.callbackWrapper(this.selectTemplateHandler_));
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler,
|
||||
$.pkp.controllers.form.AjaxFormHandler);
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The URL to use to retrieve template bodies
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.templateUrl_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* A list of user IDs which are already assigned anonymous reviews for this
|
||||
* submission.
|
||||
* @private
|
||||
* @type {Array}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.anonymousReviewerIds_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* A warning message to display when an anonymous reviewer is selected to be
|
||||
* added as a recipient
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.anonymousReviewerWarning_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The OK button language for the anonymous reviewer warning message
|
||||
* @private
|
||||
* @type {string?}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.
|
||||
anonymousReviewerWarningOk_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The list of not allowed to change submission metadata edit permissions roles
|
||||
* @private
|
||||
* @type {Object?}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.
|
||||
notChangeMetadataEditPermissionRoles_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The list of group ids that are allowed to edit metadata
|
||||
* @private
|
||||
* @type {Object?}
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.
|
||||
permitMetadataEditUserGroupIds_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Respond to an "item selected" call by triggering a published event.
|
||||
*
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.selectTemplateHandler_ =
|
||||
function(sourceElement, event) {
|
||||
|
||||
var $form = this.getHtmlElement();
|
||||
$.post(this.templateUrl_, $form.find('#template').serialize(),
|
||||
this.callbackWrapper(this.updateTemplate), 'json');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Internal callback to replace the textarea with the contents of the
|
||||
* template body.
|
||||
*
|
||||
* @param {HTMLElement} formElement The wrapped HTML form.
|
||||
* @param {Object} jsonData The data returned from the server.
|
||||
* @return {boolean} The response status.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.updateTemplate =
|
||||
function(formElement, jsonData) {
|
||||
|
||||
var $form = this.getHtmlElement(),
|
||||
processedJsonData = this.handleJson(jsonData),
|
||||
jsonDataContent =
|
||||
/** @type {{variables: Object, body: string}} */ (jsonData.content),
|
||||
$textarea = $form.find('textarea[name="message"]'),
|
||||
editor =
|
||||
tinyMCE.EditorManager.get(/** @type {string} */ ($textarea.attr('id')));
|
||||
|
||||
if (jsonDataContent.variables) {
|
||||
$textarea.attr('data-variables', JSON.stringify(jsonDataContent.variables));
|
||||
}
|
||||
editor.setContent(jsonDataContent.body);
|
||||
|
||||
return processedJsonData.status;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the enabled/disabled and checked state of the recommendOnly checkbox.
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.updateRecommendOnly =
|
||||
function(sourceElement, event) {
|
||||
|
||||
var $form = this.getHtmlElement(),
|
||||
$filterUserGroupId = $form.find('input[name=\'userGroupId\']'),
|
||||
$checkbox = $form.find('input[id^=\'recommendOnly\']'),
|
||||
$checkboxDiv = $form.find('.recommendOnlyWrapper'),
|
||||
i,
|
||||
found = false,
|
||||
filterUserGroupIdVal = /** @type {string} */ ($filterUserGroupId.val());
|
||||
|
||||
// If user group changes, hide the recommendOnly option
|
||||
if ($(sourceElement).prop('name') == 'userGroupId') {
|
||||
$checkbox.attr('disabled', 'disabled');
|
||||
$checkbox.removeAttr('checked');
|
||||
$checkboxDiv.hide();
|
||||
} else if ($(sourceElement).prop('name') == 'userIdSelected' &&
|
||||
!$checkboxDiv.is(':visible')) {
|
||||
// Display recommendOnly option if
|
||||
// an user group with a possible recommendOnly option is selected
|
||||
for (i = 0; i < this.possibleRecommendOnlyUserGroupIds_.length; i++) {
|
||||
if (this.possibleRecommendOnlyUserGroupIds_[i] == filterUserGroupIdVal) {
|
||||
$checkbox.removeAttr('disabled');
|
||||
$checkboxDiv.show();
|
||||
// Select the recommendOnly option if
|
||||
// an user group with a recommendOnly option set is selected
|
||||
for (i = 0; i < this.recommendOnlyUserGroupIds_.length; i++) {
|
||||
if (this.recommendOnlyUserGroupIds_[i] == filterUserGroupIdVal) {
|
||||
$checkbox.prop('checked', true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
$checkbox.attr('disabled', 'disabled');
|
||||
$checkboxDiv.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the enabled/disabled and checked state of the recommendOnly checkbox.
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.maybeTriggerReviewerWarning =
|
||||
function(sourceElement, event) {
|
||||
|
||||
var userId = $(sourceElement).val(),
|
||||
opts;
|
||||
|
||||
if (!userId || this.anonymousReviewerIds_.indexOf(userId) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
opts = {
|
||||
title: '',
|
||||
okButton: this.anonymousReviewerWarningOk_,
|
||||
cancelButton: false,
|
||||
dialogText: this.anonymousReviewerWarning_
|
||||
};
|
||||
|
||||
$('<div id="' + $.pkp.classes.Helper.uuid() + '" ' +
|
||||
'class="pkp_modal pkpModalWrapper" tabindex="-1"></div>')
|
||||
.pkpHandler('$.pkp.controllers.modal.ConfirmationModalHandler', opts);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the enabled/disabled and checked state of the recommendOnly checkbox.
|
||||
* @param {HTMLElement} sourceElement The element that
|
||||
* issued the event.
|
||||
* @param {Event} event The triggering event.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.
|
||||
updateSubmissionMetadataEditPermitOption =
|
||||
function(sourceElement, event) {
|
||||
|
||||
var $form = this.getHtmlElement(),
|
||||
$filterUserGroupId = $form.find('input[name=\'userGroupId\']'),
|
||||
$checkbox = $form.find('input[id^=\'canChangeMetadata\']'),
|
||||
$checkboxDiv = $form.find('.submissionEditMetadataPermit'),
|
||||
i,
|
||||
found = false,
|
||||
filterUserGroupIdVal = /** @type {string} */ ($filterUserGroupId.val());
|
||||
|
||||
// If user group changes, hide the canChangeMetadata option
|
||||
if ($(sourceElement).prop('name') == 'userGroupId') {
|
||||
$checkbox.attr('disabled', 'disabled');
|
||||
$checkbox.removeAttr('checked');
|
||||
$checkboxDiv.hide();
|
||||
} else if ($(sourceElement).prop('name') == 'userIdSelected' &&
|
||||
!$checkboxDiv.is(':visible')) {
|
||||
// Display canChangeMetadata option if
|
||||
// an user group with a possible canChangeMetadata option is selected
|
||||
for (i = 0; i < this.notChangeMetadataEditPermissionRoles_.length; i++) {
|
||||
if (this.notChangeMetadataEditPermissionRoles_[i] ==
|
||||
filterUserGroupIdVal) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
$checkbox.removeAttr('disabled');
|
||||
$checkboxDiv.show();
|
||||
// Select the recommendOnly option if
|
||||
// an user group with a recommendOnly option set is selected
|
||||
for (i = 0; i < this.permitMetadataEditUserGroupIds_.length; i++) {
|
||||
if (this.permitMetadataEditUserGroupIds_[i] == filterUserGroupIdVal) {
|
||||
$checkbox.prop('checked', true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$checkbox.attr('disabled', 'disabled');
|
||||
$checkboxDiv.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Internal callback called after form validation to handle the
|
||||
* response to a form submission.
|
||||
*
|
||||
* You can override this handler if you want to do custom handling
|
||||
* of a form response.
|
||||
*
|
||||
* @param {HTMLElement} formElement The wrapped HTML form.
|
||||
* @param {Object} jsonData The data returned from the server.
|
||||
* @return {boolean} The response status.
|
||||
*/
|
||||
$.pkp.controllers.grid.users.stageParticipant.form.
|
||||
StageParticipantNotifyHandler.prototype.handleResponse =
|
||||
function(formElement, jsonData) {
|
||||
|
||||
// Reload the query grid to show the newly created query.
|
||||
var $queries = $('#queriesGrid .pkp_controllers_grid');
|
||||
if ($.pkp.classes.Handler.hasHandler($queries)) {
|
||||
$.pkp.classes.Handler.getHandler($queries).trigger('dataChanged');
|
||||
}
|
||||
|
||||
return /** @type {boolean} */ (this.parent(
|
||||
'handleResponse', formElement, jsonData));
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
Reference in New Issue
Block a user