119 lines
3.3 KiB
JavaScript
119 lines
3.3 KiB
JavaScript
/**
|
|
* @file js/controllers/ExtrasOnDemandHandler.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 ExtrasOnDemandHandler
|
|
* @ingroup js_controllers
|
|
*
|
|
* @brief A basic handler for extras on demand UI pattern.
|
|
*/
|
|
(function($) {
|
|
|
|
|
|
/**
|
|
* @constructor
|
|
*
|
|
* @extends $.pkp.classes.Handler
|
|
*
|
|
* @param {jQueryObject} $widgetWrapper An HTML element that contains the
|
|
* widget.
|
|
* @param {Object} options Handler options.
|
|
*/
|
|
$.pkp.controllers.ExtrasOnDemandHandler = function($widgetWrapper, options) {
|
|
this.parent($widgetWrapper, options);
|
|
|
|
$('.toggleExtras', $widgetWrapper).click(
|
|
this.callbackWrapper(this.toggleExtras));
|
|
};
|
|
$.pkp.classes.Helper.inherits(
|
|
$.pkp.controllers.ExtrasOnDemandHandler, $.pkp.classes.Handler);
|
|
|
|
|
|
//
|
|
// Public methods
|
|
//
|
|
/**
|
|
* Event handler that is called when toggle extras div is clicked.
|
|
*
|
|
* @param {HTMLElement} toggleExtras The div that is clicked to toggle extras.
|
|
* @param {Event} event The triggering event.
|
|
*/
|
|
$.pkp.controllers.ExtrasOnDemandHandler.prototype.toggleExtras =
|
|
function(toggleExtras, event) {
|
|
var $widgetWrapper = this.getHtmlElement(),
|
|
$scrollable;
|
|
|
|
event.preventDefault();
|
|
|
|
$widgetWrapper.toggleClass('active');
|
|
|
|
if ($widgetWrapper.hasClass('active')) {
|
|
// Identify if there is a scrollable parent.
|
|
$scrollable = $widgetWrapper.closest('.scrollable');
|
|
if ($scrollable.length > 0) {
|
|
// Scroll the parent so that all extra content in
|
|
// extras container is visible.
|
|
this.scrollToMakeVisible_($widgetWrapper, $scrollable);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
// Private methods
|
|
//
|
|
/**
|
|
* Scroll a scrollable element to make the
|
|
* given content element visible. The content element
|
|
* must be a descendant of a scrollable
|
|
* element (needs to have class "scrollable").
|
|
*
|
|
* NB: This method depends on the position() method
|
|
* to refer to the same parent element for both the
|
|
* content element and the scrollable element.
|
|
*
|
|
* @private
|
|
*
|
|
* @param {jQueryObject} $widgetWrapper The element to be made visible.
|
|
* @param {Array|jQueryObject} $scrollable The parent scrollable element.
|
|
*/
|
|
$.pkp.controllers.ExtrasOnDemandHandler.prototype.scrollToMakeVisible_ =
|
|
function($widgetWrapper, $scrollable) {
|
|
var extrasWidgetTop, scrollingWidgetTop, currentScrollingTop,
|
|
hiddenPixels, newScrollingTop;
|
|
|
|
extrasWidgetTop = $widgetWrapper.position().top;
|
|
scrollingWidgetTop = $scrollable.position().top;
|
|
currentScrollingTop = parseInt($scrollable.scrollTop(), 10);
|
|
|
|
// Do we have to scroll down or scroll up?
|
|
if (extrasWidgetTop > scrollingWidgetTop) {
|
|
// Consider scrolling down...
|
|
|
|
// Calculate the number of hidden pixels of the child
|
|
// element within the scrollable element.
|
|
hiddenPixels = Math.ceil(extrasWidgetTop +
|
|
$widgetWrapper.height() - $scrollable.height());
|
|
|
|
// Scroll down if parts or all of this widget are hidden.
|
|
if (hiddenPixels > 0) {
|
|
$scrollable.scrollTop(currentScrollingTop + hiddenPixels);
|
|
}
|
|
} else {
|
|
// Scroll up...
|
|
|
|
// Calculate the new scrolling top.
|
|
newScrollingTop = Math.max(Math.floor(
|
|
currentScrollingTop + extrasWidgetTop - scrollingWidgetTop), 0);
|
|
|
|
// Set the new scrolling top.
|
|
$scrollable.scrollTop(newScrollingTop);
|
|
}
|
|
};
|
|
|
|
|
|
}(jQuery));
|