336 lines
13 KiB
JavaScript
336 lines
13 KiB
JavaScript
(function ($) {
|
|
var settings = {
|
|
scrollTimeout: 0, // milliseconds
|
|
rowHeight: 30,
|
|
hidePopoversContainer: null
|
|
};
|
|
|
|
var createMarkup = function ($this) {
|
|
if (!$this) {
|
|
throw '$this does not exist';
|
|
}
|
|
|
|
// if markup is already created
|
|
if ($this.data('popupMenu')) {
|
|
return;
|
|
}
|
|
var dropdownContainer = $this.find('.dropdown-menu').on('click', dropDownInsideClick);
|
|
var chevron = $this.find('.dropdown-toggle').on('click', function () {
|
|
if (!$this.hasClass('open') && !$this.data('popovers-inited'))
|
|
{
|
|
$this.data('popovers-inited', true);
|
|
$this.find('.popover-warning').each(function () {
|
|
var $item = $(this);
|
|
initPopover($item);
|
|
});
|
|
}
|
|
setDropDownPosition($this, $(this), dropdownContainer);
|
|
});
|
|
$this.data('popupMenu', true);
|
|
|
|
return $this;
|
|
};
|
|
var setupWindow = function ($this) {
|
|
if (!$this) {
|
|
throw '$this does not exist';
|
|
}
|
|
if (!settings.hidePopoversContainer || settings.hidePopoversContainer.length <= 0) {
|
|
return;
|
|
}
|
|
var popoverContainer = $('.' + settings.hidePopoversContainer);
|
|
var menuClass = popoverContainer.data('menuclass');
|
|
if (popoverContainer.length > 0) {
|
|
var data = $(window).data('pm.scroll.src');
|
|
if (!data)
|
|
data = {};
|
|
// add container if it is not specified yet
|
|
if (!data[settings.hidePopoversContainer])
|
|
data[settings.hidePopoversContainer] = {};
|
|
// add menu class to scrolling container to identify which popovers to close
|
|
data[settings.hidePopoversContainer][menuClass] = true;
|
|
// store updated list of containers in data
|
|
$(window).data('pm.scroll.src', data);
|
|
}
|
|
return $this;
|
|
};
|
|
var setupContainer = function ($this) {
|
|
if (!$this) {
|
|
throw '$this does not exist';
|
|
}
|
|
if (!settings.hidePopoversContainer || settings.hidePopoversContainer.length <= 0) {
|
|
return;
|
|
}
|
|
var popoverContainer = $('.' + settings.hidePopoversContainer);
|
|
var scrollContainerClass = popoverContainer.data('scrollcontainerclass');
|
|
var menuClass = popoverContainer.data('menuclass');
|
|
if (scrollContainerClass)
|
|
{
|
|
var scrollContainer = $('.' + scrollContainerClass);
|
|
// store containers whose popups should be hidden on scrollContainer.scroll
|
|
scrollContainer.each(function (i, obj) {
|
|
var data = $(obj).data('pm.scroll.src');
|
|
if (!data)
|
|
data = {};
|
|
// add container if it is not specified yet
|
|
if (!data[settings.hidePopoversContainer])
|
|
data[settings.hidePopoversContainer] = {};
|
|
// add menu class to scrolling container to identify which popovers to close
|
|
data[settings.hidePopoversContainer][menuClass] = true;
|
|
// store updated list of containers in data
|
|
$(obj).data('pm.scroll.src', data);
|
|
});
|
|
setupScrollEvent(scrollContainer);
|
|
}
|
|
// gather menuCssClasses
|
|
var menuClasses = $(document).data('pm.click.menu') || {};
|
|
menuClasses[menuClass] = true;
|
|
$(document).data('pm.click.menu', menuClasses);
|
|
// gather popupmenu containers
|
|
var containers = $(document).data('pm.click.container') || {};
|
|
containers[settings.hidePopoversContainer] = true;
|
|
$(document).data('pm.click.container', containers);
|
|
|
|
return $this;
|
|
};
|
|
var setupWindowEvents = function () {
|
|
setupScrollEvent(window);
|
|
setupClickEvent(document);
|
|
};
|
|
function setupScrollEvent(obj) {
|
|
$(obj).off('scroll.pm').on('scroll.pm', function () {
|
|
if (settings.scrollTimeout > 0)
|
|
{
|
|
if ($(obj).data('scroll.pm.timeout')) {
|
|
clearTimeout($(obj).data('scroll.pm.timeout'));
|
|
}
|
|
$(obj).data('scroll.pm.timeout', setTimeout(onScroll, settings.scrollTimeout, obj));
|
|
}
|
|
else
|
|
onScroll(obj);
|
|
});
|
|
};
|
|
function setupClickEvent(obj) {
|
|
$(obj).off('click.pm').on('click.pm', function () {
|
|
onClick(obj);
|
|
});
|
|
$(document).off('hidden.bs.dropdown.pm').on('hidden.bs.dropdown.pm', function (e, obj) {
|
|
$(e.target).find('a.popover-warning:data(bs.popover)').popover('destroy');
|
|
});
|
|
};
|
|
var initPopover = function ($item) {
|
|
if ($item.data('checklock-table') && $item.data('checklock-id') && $item.data('checklock-url'))
|
|
{
|
|
$item.on('click', function () {
|
|
var tbl = $item.data('checklock-table');
|
|
var id = $item.data('checklock-id');
|
|
var url = $item.data('checklock-url');
|
|
var openInNewTab = ($item.data('in-newtab') !== undefined);
|
|
var backName = $item.data('checklock-backname');
|
|
var query = $item.data('checklock-query');
|
|
if (!URI)
|
|
throw 'Cannot find URI component declared in URIjs.js';
|
|
if (CheckLock($item, tbl, id)) {
|
|
var currentUrl = document.location.pathname + document.location.search;
|
|
var navigateToUrl = URI(url);
|
|
if (url && url.length > 0) {
|
|
var urlId = navigateToUrl.query(true).id;
|
|
if (!urlId || urlId.length <= 0)
|
|
navigateToUrl = navigateToUrl.setQuery('id', id);
|
|
}
|
|
else
|
|
throw 'Cannot set target navigation URL';
|
|
navigateToUrl = navigateToUrl.setQuery('backUrl', currentUrl);
|
|
if (backName && (backName.length > 0))
|
|
navigateToUrl = navigateToUrl.setQuery("backName", encodeURIComponent(backName));
|
|
if (query && query.length > 0)
|
|
navigateToUrl = navigateToUrl.toString() + '&' + query;
|
|
|
|
if (openInNewTab) {
|
|
window.open(navigateToUrl, '_blank');
|
|
}
|
|
else {
|
|
document.location.href = navigateToUrl;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
var onChevronClick = function ($this) {
|
|
$this.find('.modal').modal('show');
|
|
};
|
|
var setDropDownPosition = function (popupMenu, button, dropdown) {
|
|
calcProps(button, dropdown, settings.rowHeight);
|
|
var popoverContainer = popupMenu.closest('.' + settings.hidePopoversContainer);
|
|
hideRedundantPopovers(popoverContainer, null);
|
|
}
|
|
function calcProps(button, dropdown, liHeight) {
|
|
var rows = dropdown.find("li").length;
|
|
if (rows > 3)
|
|
rows = rows - 1;
|
|
|
|
var menumax = rows * liHeight;
|
|
if (rows >= 2)
|
|
menumax = menumax + 25;
|
|
dropdown.css('overflow', 'hidden');
|
|
var curmaxheight = 300;
|
|
var totalMaxheight = 400;
|
|
var menumax_keep = menumax;
|
|
var y = $(window.top).height();
|
|
var bOffset = button.offset().top - window.pageYOffset;
|
|
|
|
var y1 = bOffset + button.outerHeight();
|
|
var dropDownLeft = button.offset().left - window.pageXOffset;
|
|
var dropDownTop = bOffset + button.outerHeight();
|
|
var sc1 = y - y1;
|
|
|
|
if (curmaxheight + dropDownTop > window.innerHeight)
|
|
sc1 = bOffset;
|
|
|
|
if (menumax > sc1)
|
|
menumax = (sc1 - 50);
|
|
|
|
if (menumax > totalMaxheight)
|
|
menumax = totalMaxheight;
|
|
var direction = 'bottom';
|
|
if (menumax + dropDownTop > window.innerHeight) {
|
|
if (menumax_keep < menumax)
|
|
dropDownTop = (bOffset - menumax_keep);
|
|
else
|
|
dropDownTop = (bOffset - menumax);
|
|
direction = 'top'
|
|
}
|
|
|
|
if (menumax < menumax_keep) {
|
|
var delta = menumax_keep - menumax
|
|
if (delta > 25)
|
|
dropdown.css('overflow', 'auto');
|
|
if (curmaxheight > menumax) {
|
|
menumax = curmaxheight;
|
|
}
|
|
}
|
|
if (direction === 'top') {
|
|
dropdown.css('max-height', menumax + "px");
|
|
if (menumax < curmaxheight)
|
|
menumaxdph = $(dropdown).outerHeight();
|
|
dropDownTop = (bOffset - menumax);
|
|
|
|
} else {
|
|
dropdown.css('max-height', menumax + "px");
|
|
}
|
|
dropdown.css('position', 'fixed');
|
|
dropdown.css('top', dropDownTop + "px");
|
|
dropdown.css('left', dropDownLeft + "px");
|
|
dropdown.css('z-index', '499');
|
|
setDropDownHorizontalPosition(button, dropdown)
|
|
}
|
|
function setDropDownHorizontalPosition(button, dropdown) {
|
|
var rows = dropdown.find("li").length;
|
|
if (rows > 0) {
|
|
var l = button.offset().left + $(button).parent().width();
|
|
var w = $(dropdown).innerWidth();
|
|
var docW = window.innerWidth;
|
|
|
|
var isEntirelyVisible = (l + w <= docW);
|
|
|
|
if (!isEntirelyVisible) {
|
|
var totheright = l - w;
|
|
dropdown.css('left', totheright + 'px');
|
|
} else {
|
|
|
|
}
|
|
}
|
|
}
|
|
function dropDownInsideClick(event) {
|
|
if (!event)
|
|
event = window.event;
|
|
|
|
var container = null, button = null;
|
|
if ($(event.target).hasClass('dropdown-menu'))
|
|
container = $(event.target);
|
|
else {
|
|
button = $(event.target);
|
|
container = button.closest('.dropdown-menu');
|
|
}
|
|
hideRedundantPopovers(container, button);
|
|
|
|
if (event.stopPropagation)
|
|
event.stopPropagation();
|
|
else
|
|
window.event.cancelBubble = true;
|
|
}
|
|
function hideRedundantPopovers(container, currentBtn) {
|
|
if (!container) {
|
|
return;
|
|
}
|
|
|
|
var btn = null;
|
|
if (currentBtn) {
|
|
if (currentBtn.is('[data-toggle="popover"]'))
|
|
btn = currentBtn;
|
|
else
|
|
btn = currentBtn.closest('[data-toggle="popover"]');
|
|
}
|
|
|
|
container.find('a.popover-warning:data(bs.popover)').not(btn).popover('destroy');
|
|
}
|
|
function onScroll(obj) {
|
|
//var startDate = new Date().getTime();
|
|
// get a list of containers to handle for the specified scrolling container
|
|
var data = $(obj).data('pm.scroll.src');
|
|
//console.log('window scroll.pm. data = ' + data);
|
|
if (data) {
|
|
$.each(data, function (key, item) {
|
|
//console.log('window scroll.pm. data.each = ' + key + '; item.length' + item.length);
|
|
var container = $('.' + key);
|
|
if (item) {
|
|
$.each(item, function (menuClassKey, menuClassElem) {
|
|
//console.log('window scroll.pm. item.each = ' + menuClassKey);
|
|
container.find('.' + menuClassKey).removeClass('open');
|
|
});
|
|
}
|
|
hideRedundantPopovers(container, null);
|
|
});
|
|
}
|
|
//var endDate = new Date().getTime();
|
|
//console.log('hiding popup menus and popovers took: ' + (endDate - startDate) + ' ms');
|
|
}
|
|
function onClick(obj) {
|
|
//var startDate = new Date().getTime();
|
|
// get a list of containers to handle for the specified dom element
|
|
var menus = $(obj).data('pm.click.menu');
|
|
var containers = $(obj).data('pm.click.container');
|
|
if (menus) {
|
|
$.each(menus, function (key, item) {
|
|
var menuItem = $('.' + key).removeClass('open');
|
|
});
|
|
}
|
|
if (containers) {
|
|
$.each(containers, function (key, item) {
|
|
hideRedundantPopovers($('.' + key), null);
|
|
});
|
|
}
|
|
//var endDate = new Date().getTime();
|
|
//console.log('PM. document click took: ' + (endDate - startDate) + ' ms');
|
|
}
|
|
|
|
var methods = {
|
|
init: function (options) {
|
|
settings = $.extend(true, settings, options);
|
|
this.each(function () {
|
|
var $this = $(this);
|
|
createMarkup($this);
|
|
setupContainer($this);
|
|
setupWindow($this);
|
|
});
|
|
setupWindowEvents();
|
|
}
|
|
};
|
|
|
|
$.fn.popupMenu = function (options) {
|
|
if (typeof options === 'string' && typeof methods[options] === 'function') {
|
|
return methods[options].apply(this, Array.prototype.slice.call(arguments, 1));
|
|
} else if (typeof options === 'object' || !options) {
|
|
return methods.init.apply(this, arguments);
|
|
}
|
|
};
|
|
}(jQuery)); |