EnVisageOnline/Main/Source/EnVisage/Scripts/main.js

924 lines
32 KiB
JavaScript

var C_EMPTY_GUID = '00000000-0000-0000-0000-000000000000';
var app; // Variable declaration for angular app
var _lockers = 0;
function increaseLockers() {
if (_lockers < 0)
_lockers = 0;
_lockers++;
}
function decreaseLockers() {
if (_lockers > 0)
_lockers--;
if (_lockers < 0)
_lockers = 0;
}
function canUnblockUI() {
return _lockers === 0;
}
function isUIBlocked() {
return _lockers > 0;
}
function showErrorModal(title, message, errorCode) {
title = title || 'Oops!';
message = message || 'An error occurred while processing your request. Please, try again later.';
if (errorCode)
message += ' ErrorCode = ' + errorCode;
var modal = $("#modal-error");
if (modal != null) {
var divTitle = $("#modal-error .modal-title");
if (divTitle != null)
divTitle.text(title);
var divMessage = $("#modal-error .modal-body");
if (divMessage != null) {
divMessage.text($.trim(message));
if (divMessage.text().length > 0) {
$("#modal-error").modal();
}
}
}
}
function enableElement(obj, enable) {
if (enable) {
$(obj).removeAttr('disabled');
} else {
$(obj).attr('disabled', 'disabled');
}
}
function blockUI() {
increaseLockers();
$.blockUI({ message: "<div class='spinner2'>Loading...</div>", ignoreIfBlocked: true });
}
function blockUIRace() {
increaseLockers();
$.blockUI({ message: "<div class='spinnerRace'>Loading...</div>", ignoreIfBlocked: true });
}
function unblockUI() {
decreaseLockers();
if (canUnblockUI())
$.unblockUI();
}
(function ($) {
$.validator.unobtrusive.parseDynamicContent = function (selector) {
//use the normal unobstrusive.parse method
$.validator.unobtrusive.parse(selector);
//get the relevant form
var form = $(selector).first().closest('form');
//get the collections of unobstrusive validators, and jquery validators
//and compare the two
var unobtrusiveValidation = form.data('unobtrusiveValidation');
var validator = form.validate();
$.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
if (validator.settings.rules[elname] == undefined) {
var args = {};
$.extend(args, elrules);
args.messages = unobtrusiveValidation.options.messages[elname];
//edit:use quoted strings for the name selector
$(form).find("[name='" + elname + "']").rules("add", args);
} else {
$.each(elrules, function (rulename, data) {
if (validator.settings.rules[elname][rulename] == undefined) {
var args = {};
args[rulename] = data;
args.messages = unobtrusiveValidation.options.messages[elname];
//edit:use quoted strings for the name selector
$(form).find("[name='" + elname + "']").rules("add", args);
}
});
}
});
if (validator.settings.errorPlacement == undefined)
validator.settings.errorPlacement = unobtrusiveValidation.options.errorPlacement;
};
})($);
(function ($) {
$.QueryString = (function (a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i) {
var p = a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));
})($);
Number.prototype.formatNumber = function (c, d, t) {
var n = this,
c = isNaN(c = Math.abs(c)) ? 2 : c,
d = d == undefined ? "." : d,
t = t == undefined ? "," : t,
s = n < 0 ? "-" : "",
i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
j = (j = i.length) > 3 ? j % 3 : 0;
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};
Number.prototype.formatDuration = function () {
var result = this;
if (this > 0) { // get years
}
if (this > 0) { // get days
}
if (this > 0) { // get hours
}
return result;
};
function union(arr1, arr2) {
var result = new Array();
var fa = (arr1 || []);
for (var i = 0; i < fa.length; i++) {
if (result.indexOf(fa[i]) < 0)
result.push(fa[i]);
}
var sa = (arr2 || []);
for (var i = 0; i < sa.length; i++) {
if (result.indexOf(sa[i]) < 0)
result.push(sa[i]);
}
return result;
};
function binarySearch(ar, x, left, right, searchIndex4Insert, key) {
if (!ar || !$.isArray(ar))
throw 'ar is not array!';
if (left > right || ar.length <= 0)
return -1;
var mid = Math.floor((left + right) / 2);
if (mid == ar.length) {
return searchIndex4Insert === true ? ar.length : -1;
}
var arMid = key ? ar[mid][key] : ar[mid];
if (arMid == x)
return mid;
if (searchIndex4Insert === true) {
var prev = Number.MIN_VALUE,
next = Number.MAX_VALUE;
if (mid > 0 && mid < ar.length) {
prev = (key ? ar[mid - 1][key] : ar[mid - 1]) || Number.MIN_VALUE;
}
if (mid >= 0 && (mid + 1) < ar.length) {
next = ((key ? ar[mid + 1][key] : ar[mid + 1]) || Number.MAX_VALUE);
}
if (prev == x)
return mid - 1;
if (next == x)
return mid + 1;
if (prev < x && x < arMid)
return mid;
if (arMid < x && x < next)
return mid + 1;
}
if (arMid < x)
return binarySearch(ar, x, mid + 1, right, searchIndex4Insert, key);
if (arMid > x)
return binarySearch(ar, x, left, mid - 1, searchIndex4Insert, key);
};
/*
* Generate a random uuid.
*
* USAGE: Math.uuid(length, radix)
* length - the desired number of characters
* radix - the number of allowable values for each character.
*
* EXAMPLES:
* // No arguments - returns RFC4122, version 4 ID
* >>> Math.uuid()
* "92329D39-6F5C-4520-ABFC-AAB64544E172"
*
* // One argument - returns ID of the specified length
* >>> Math.uuid(15) // 15 character ID (default base=62)
* "VcydxgltxrVZSTV"
*
* // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
* >>> Math.uuid(8, 2) // 8 character ID (base=2)
* "01001010"
* >>> Math.uuid(8, 10) // 8 character ID (base=10)
* "47473046"
* >>> Math.uuid(8, 16) // 8 character ID (base=16)
* "098F4D35"
*/
Math.uuid = (function () {
// Private array of chars to use
var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
return function (len, radix) {
var chars = CHARS, uuid = [], rnd = Math.random;
radix = radix || chars.length;
if (len) {
// Compact form
for (var i = 0; i < len; i++) uuid[i] = chars[0 | rnd() * radix];
} else {
// rfc4122, version 4 form
var r;
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (var i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | rnd() * 16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
}
}
}
return uuid.join('');
};
})();
function initMainJS() {
$("select").on("select2-focus", function (e) {
$(".minicolors-panel").css('display', 'none');
$(".datepicker-dropdown").css('display', 'none');
});
}
//todo: remove other instances
$.fn.modal.Constructor.prototype.enforceFocus = function () {
var that = this;
$(document).on('focusin.modal', function (e) {
if ($(e.target).hasClass('select2-input')) {
return true;
}
if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
that.$element.focus();
}
});
};
function setDropdownProps(button, dropdown, liHeight) {
var clientid = $(dropdown)[0].id;
var rows = $("#" + clientid + " 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)
}
setDropDownHorizontalPosition = function (button, dropdown) {
var clientid = $(dropdown)[0].id;
var rows = $("#" + clientid + " 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 {
}
}
}
jQuery.getScrollBarWidthHeight = function () {
var inner = $('<p></p>').css({
'width': '100%',
'height': '100%'
});
var outer = $('<div></div>').css({
'position': 'absolute',
'width': '100px',
'height': '100px',
'top': '0',
'left': '0',
'visibility': 'hidden',
'overflow': 'hidden'
}).append(inner);
$(document.body).append(outer);
var w1 = inner.width(), h1 = inner.height();
outer.css('overflow', 'scroll');
var w2 = inner.width(), h2 = inner.height();
if (w1 == w2 && outer[0].clientWidth) {
w2 = outer[0].clientWidth;
}
if (h1 == h2 && outer[0].clientHeight) {
h2 = outer[0].clientHeight;
}
outer.detach();
var pixelRatioMultiplier = 1.00;
//AG: I've commented out the lines below because window.devicePixelRatio is a bad practice to determine the zoom although it works
//correctly on the desktop browsers - this supposed to show HIDPI screens and will not work correctly on tablets and phones and probably HIDPI desktop screens as well
//if (window.devicePixelRatio != null && window.devicePixelRatio != 0)
// pixelRatioMultiplier = window.devicePixelRatio.toFixed(2);
return [Math.round((w1 - w2) * pixelRatioMultiplier), Math.round((h1 - h2) * pixelRatioMultiplier)];
};
initMainJS();
Object.size = function (obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
var _bigColorPalette = ["#67B7DC", "#FDD400", "#CC4748", "#CD82AD", "#2F4074", "#448E4D", "#B7B83F", "#B9783F",
"#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
"#5A0007", "#809693", "#92896B", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
"#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
"#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
"#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
"#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
"#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
"#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
"#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
"#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
"#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
"#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
"#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C",
"#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800",
"#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51",
"#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58",
"#7A7BFF", "#D68E01", "#353339", "#78AFA1", "#FEB2C6", "#75797C", "#837393", "#943A4D",
"#B5F4FF", "#D2DCD5", "#9556BD", "#6A714A", "#001325", "#02525F", "#0AA3F7", "#E98176",
"#DBD5DD", "#5EBCD1", "#3D4F44", "#7E6405", "#02684E", "#962B75", "#8D8546", "#9695C5",
"#E773CE", "#D86A78", "#3E89BE", "#CA834E", "#518A87", "#5B113C", "#55813B", "#E704C4",
"#00005F", "#A97399", "#4B8160", "#59738A", "#FF5DA7", "#F7C9BF", "#643127", "#513A01",
"#6B94AA", "#51A058", "#A45B02", "#1D1702", "#E20027", "#E7AB63", "#4C6001", "#9C6966",
"#64547B", "#97979E", "#006A66", "#391406", "#F4D749", "#0045D2", "#006C31", "#DDB6D0",
"#7C6571", "#9FB2A4", "#00D891", "#15A08A", "#BC65E9", "#000000", "#C6DC99", "#203B3C",
"#671190", "#6B3A64", "#F5E1FF", "#FFA0F2", "#CCAA35", "#374527", "#8BB400", "#797868",
"#C6005A", "#3B000A", "#C86240", "#29607C", "#402334", "#7D5A44", "#CCB87C", "#B88183",
"#AA5199", "#B5D6C3", "#A38469", "#9F94F0", "#A74571", "#B894A6", "#71BB8C", "#00B433",
"#789EC9", "#6D80BA", "#953F00", "#5EFF03", "#E4FFFC", "#1BE177", "#BCB1E5", "#76912F",
"#003109", "#0060CD", "#D20096", "#895563", "#29201D", "#5B3213", "#A76F42", "#89412E",
"#1A3A2A", "#494B5A", "#A88C85", "#F4ABAA", "#A3F3AB", "#00C6C8", "#EA8B66", "#958A9F",
"#BDC9D2", "#9FA064", "#BE4700", "#658188", "#83A485", "#453C23", "#47675D", "#3A3F00",
"#061203", "#DFFB71", "#868E7E", "#98D058", "#6C8F7D", "#D7BFC2", "#3C3E6E", "#D83D66",
];
// it needs for sending XSRF-Token in the form to the server
function getAntiXSRFRequest(url, data, tokenFieldId) {
var tokenField = null;
if (tokenFieldId && tokenFieldId.length && tokenFieldId.val)
tokenField = tokenFieldId;
else {
tokenFieldId = tokenFieldId || '__RequestVerificationToken';
tokenField = $('input[name=' + tokenFieldId + ']');
}
if (tokenField.length == 0) {
throw 'There is no token field with id: ' + tokenFieldId;
return null;
}
return {
method: 'POST',
url: url,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ model: data }),
dataType: 'JSON',
headers: {
"__RequestVerificationToken": tokenField.val()
}
};
}
function compileDynamicAngularHtml(container) {
var injector = $('[ng-app]').injector();
injector.invoke([
"$compile", "$rootScope", function ($compile, $rootScope) {
$compile(container)($rootScope);
$rootScope.$apply();
}
]);
}
function destroyAngularForm(event) {
if (!event)
return;
var controllers = angular.element(event.currentTarget).find('[ng-controller]');
for (var i = 0; i < controllers.length; i++) {
if (angular.isElement(controllers[i])) {
var scope = angular.element(controllers[i]).scope();
if (!!scope)
scope.$destroy();
}
}
}
function triggerBroadcastFromRootScope(eventName, eventData) {
if (!eventName || !eventData)
return;
var injector = $('[ng-app]').injector();
if (!injector)
return;
var rootScope = injector.get('$rootScope');
if (!rootScope)
return;
rootScope.$broadcast(eventName, eventData);
}
function CalculateMonthSpread(graphId, data) {
if (!data) return 1;
if (data.length == 0) return 1;
var length = data.length; //number of x data points
if (data[data.length - 1][0] - data[0][0] < 31449600000) length = length / 4.33; //if period less then a year we just draw months weekly, if over - we display years by months
if (length < 13) return 1; //do not toch rerids for less then a year
var width = $('#' + graphId).width();
var mult = 50 / ((width - 100) / length); // divide desired length of average label by length of actual
return Math.ceil(mult);
}
function formatDateRange(startDate, endDate, includeBoth) {
startDate = new Date(startDate);
endDate = new Date(endDate);
if ((startDate.getTime() || 0) <= 0 || (endDate.getTime() || 0) <= 0)
return '';
var totalDays = Math.ceil(Math.max((endDate - startDate) / (1000 * 60 * 60 * 24), 0)) + (includeBoth && (endDate >= startDate) ? 1 : 0);
var weeks = Math.floor((totalDays / 7.0));
var days = totalDays % 7;
var weeksFormat = '',
daysFormat = days + ' day' + (days > 1 ? 's' : '');
if (weeks > 0) {
weeksFormat = weeks + ' wk' + (weeks > 1 ? 's' : '');
if (days <= 0)
daysFormat = '';
}
return (weeksFormat + ' ' + daysFormat).trim();
}
function formatUniversalDate(date) {
return date.getFullYear() + "-" + (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1) + "-" + (date.getDate() < 10 ? '0' : '') + date.getDate();
}
function addDaysToDate(date, days) {
date = new Date(date);
return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
};
function isGuidEmpty(guid) {
if (!guid || typeof guid !== 'string')
return true;
return guid.replace(/0/g, '').replace(/-/g, '').trim().length <= 0;
};
function htmlEncode(text) {
return String(text)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
function htmlDecode(text) {
return String(text)
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'")
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
}
function hideRedundantPopovers(container, currentBtn) {
if (!container) {
return;
}
var id = null;
if (currentBtn) {
if (currentBtn.is('[data-toggle="popover"]'))
id = currentBtn.attr('id');
else
id = currentBtn.closest('[data-toggle="popover"]').attr('id');
}
container.find('a.popover-warning:data(bs.popover)' + (!!id ? ('[id!="' + id + '"]') : '')).popover('destroy');
}
function checkBrowser() {
var userAgent = window.navigator.userAgent;
var browsers = { chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer/i, ie1: /trident/i };
for (var key in browsers) {
if (browsers[key].test(userAgent)) {
return key;
}
};
return 'unknown';
}
function getUniqueColor(idx, usedColors) {
var palette = PixelAdmin.settings.consts.COLORS;
if (palette.length < 1)
return null;
if (palette.length == 1)
return palette[0];
var clr;
for (var i = idx; i < palette.length; i++) {
clr = palette[i % (palette.length - 1)];
if (usedColors.indexOf(clr) < 0) {
usedColors.push(clr);
break;
}
}
return clr;
}
function handleAjaxResponse(result, successCallback, errorCallback, finalCallback, form, prefix) {
var resultStatus = result != null ? result.Status : undefined;
if (resultStatus) {
if (successCallback)
successCallback(result);
// hide summary validation messages
form.find("[data-valmsg-summary=true]")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
} else {
var errors = result != null && result.Errors ? result.Errors : undefined;
displayValidationErrors(errors, form, prefix);
if (errorCallback) {
errorCallback(result);
}
}
}
function displayValidationErrors(errors, form, prefix) {
if (!errors)
return;
var $form = form;
var $ul = $form.find("[data-valmsg-summary=true] > ul");
var $validator = $form.validate();
var fldErrors = {};
var generalErrors = [];
$ul.empty();
$.each(errors, function (idx, error) {
if (error.ErrorMessages) {
$.each(error.ErrorMessages, function (msgIdx, msg) {
if (!msg || msg.length == 0)
return;
$ul.append('<li>' + msg + '</li>');
if (error.FieldName) {
var fieldName = prefix ? error.FieldName.substring(prefix.length) : error.FieldName;
if ($form.find('[name="'+ fieldName + '"]').length)
fldErrors[fieldName] = msg;
else
generalErrors.push(msg);
} else {
generalErrors.push(msg);
}
});
}
});
if (Object.keys(fldErrors).length > 0) {
// force to mark fields as invalid and display field validation messages
$validator.showErrors(fldErrors);
}
$form.find("[data-valmsg-summary=true]")
.addClass("validation-summary-errors")
.removeClass("validation-summary-valid");
}
function pageReload() {
var url = document.location.href;
var hashPos = url.indexOf('#');
if (hashPos > 0)
url = url.substr(0, hashPos);
document.location.href = url;
}
function reloadDataTable(tableSelector) {
// refresh data in the table without reseting of user's current page
$(tableSelector).DataTable().ajax.reload(null, false);
};
/* ======= Date conversion function ======== */
function DateTimeConverter() {
}
DateTimeConverter.msFormatAsLocalString = function (dateUtcMilliseconds) {
if (!dateUtcMilliseconds || !$.isNumeric(dateUtcMilliseconds))
throw "DateTimeConverter: Unable to convert UTC milliseconds to local date string (value: " + dateUtcMilliseconds + ")";
var localDate = new Date(dateUtcMilliseconds);
if (isNaN(localDate.getTime()))
throw "DateTimeConverter: Argument " + dateUtcMilliseconds + " is not valid date";
var year = localDate.getFullYear();
var month = localDate.getMonth() + 1;
var day = localDate.getDate();
var result =
(month > 9 ? String(month) : '0' + String(month)) + '/' +
(day > 9 ? String(day) : '0' + String(day)) + '/' +
String(year);
return result;
};
DateTimeConverter.msFormatAsUtcString = function (dateUtcMilliseconds) {
if (!dateUtcMilliseconds || !$.isNumeric(dateUtcMilliseconds))
throw "DateTimeConverter: Unable to convert UTC milliseconds to date string (value: " + dateUtcMilliseconds + ")";
var date = new Date(dateUtcMilliseconds);
if (isNaN(date.getTime()))
throw "DateTimeConverter: Argument " + dateUtcMilliseconds + " is not valid date";
var year = date.getUTCFullYear();
var month = date.getUTCMonth() + 1;
var day = date.getUTCDate();
var result =
(month > 9 ? String(month) : '0' + String(month)) + '/' +
(day > 9 ? String(day) : '0' + String(day)) + '/' +
String(year);
return result;
};
DateTimeConverter.msToUtcDate = function (dateAsMs) {
if (!dateAsMs || !$.isNumeric(dateAsMs) || (Number(dateAsMs) < 0))
throw "DateTimeConverter: Unable to convert UTC milliseconds to UTC date. Incoming value is invalid";
var date = new Date(Number(dateAsMs));
var utcYear = date.getUTCFullYear();
var utcMonth = date.getUTCMonth();
var utcDay = date.getUTCDate();
var result = new Date(utcYear, utcMonth, utcDay);
return result;
};
DateTimeConverter.msToLocalDate = function (dateAsMs) {
if (!dateAsMs || !$.isNumeric(dateAsMs) || (Number(dateAsMs) < 0))
throw "DateTimeConverter: Unable to convert UTC milliseconds to local date. Incoming value is invalid";
var result = new Date(Number(dateAsMs));
return result;
};
DateTimeConverter.stringToMs = function (localDateAsText) {
if (!localDateAsText || (localDateAsText.length < 6) || ((new Date(localDateAsText)).getTime() < 1))
throw "DateTimeConverter: Unable to convert local string date to local milliseconds. Incoming value is invalid";
var localDate = new Date(localDateAsText);
var year = localDate.getFullYear();
var month = localDate.getMonth();
var day = localDate.getDate();
var result = Date.UTC(year, month, day);
return result;
};
DateTimeConverter.dateToMs = function (localDateAsDate) {
if (!localDateAsDate || isNaN(localDateAsDate.getTime()))
throw "DateTimeConverter: Unable to convert local date to UTC milliseconds. Incoming date value is invalid";
var utcYear = localDateAsDate.getUTCFullYear();
var utcMonth = localDateAsDate.getUTCMonth();
var utcDay = localDateAsDate.getUTCDate();
var result = Date.UTC(utcYear, utcMonth, utcDay);
return result;
};
DateTimeConverter.jsonDateToMs = function (jsonDate) {
if (!jsonDate || typeof jsonDate !== 'string')
throw "DateTimeConverter: Unable to convert jsonDate to milliseconds. Incoming value is invalid";
var d = /\/Date\((\d*)\)\//.exec(jsonDate);
var date = (d) ? new Date(+d[1]) : jsonDate;
return DateTimeConverter.dateToMs(date);
}
DateTimeConverter.getUtcNowMs = function () {
var localNow = new Date();
var utcYear = localNow.getUTCFullYear();
var utcMonth = localNow.getUTCMonth();
var utcDay = localNow.getUTCDate();
var utcHours = localNow.getUTCHours();
var utcMinutes = localNow.getUTCMinutes();
var utcSeconds = localNow.getUTCSeconds();
var result = Date.UTC(utcYear, utcMonth, utcDay, utcHours, utcMinutes, utcSeconds);
return result;
};
DateTimeConverter.getLocalNowMs = function () {
var localNow = new Date();
var result = localNow.getTime();
return result;
};
Object.values = function (obj) {
if (!obj || (typeof obj !== 'object')) {
return [];
}
var values = [];
for (var key in obj) {
values.push(obj[key]);
}
return values;
};
Object.keysInObject = function (keys, obj) {
if (!keys || !keys.length) {
throw 'keys collection is empty';
}
if (!obj || (typeof obj !== 'object')) {
return false;
}
for (var i = 0; i < keys.length; i++) {
if (!(keys[i] in obj)) {
return false;
}
}
return true;
};
Object.parseBoolean = function (value) {
if (value == null || value == undefined) {
return false;
}
if (typeof value === 'boolean') {
return value;
}
return value.toLowerCase() === 'true';
};
Math.quantityPrecision = 1000000;
Math.costPrecision = 10000;
Math.roundQuantity = function (value, decimals) {
var denominator = decimals == null ? Math.quantityPrecision : (10*decimals);
return Math.round(value * denominator) / denominator;
};
Math.roundCost = function (value) {
return Math.round(value * Math.costPrecision) / Math.costPrecision;
};
/* ======= Number distribution along array items ======== */
function calculateDistribution() {}
// sums values of "sourceValues" array for the specified index range "targetIndexes"
calculateDistribution.calculateSumOnRange = function (sourceValues, targetIndexes) {
if (!sourceValues || !sourceValues.length || !targetIndexes || !targetIndexes.length) {
return 0;
}
var result = 0;
for (var i = 0; i < targetIndexes.length; i++) {
result += (sourceValues[targetIndexes[i]] || 0);
}
return result;
};
// distributes provided "total" value between sourceValues array values with the specified index range "targetIndexes"
calculateDistribution.distributeValue = function (sourceValues, targetIndexes, total, decimals) {
if (!sourceValues || !sourceValues.length) {
return null;
}
// if targetIndexes collection is not passed we need to align total on all sourceValues collection
targetIndexes = targetIndexes || Array.apply(null, { length: sourceValues.length }).map(Number.call, Number);
var result = {};
var oldTotal = Math.roundQuantity(this.calculateSumOnRange(sourceValues, targetIndexes) || 0);
var newTotal = parseFloat(total) || 0;
var distributedNewValue = 0;
var lastIndex = targetIndexes[targetIndexes.length - 1];
if (oldTotal == 0) {
var newValue = Math.roundQuantity(newTotal / targetIndexes.length, decimals);
for (var i = 0; i < targetIndexes.length - 1; i++) {
// Example: we need to distribute 0.000002 between 4 cells.
// newValue will be 0.000002 / 4 = 0.0000005 ~ 0.000001
// if we distribute this value in targetIndexes.length - 1 cells (3) we get distributedNewValue = 0.000003
// and -0.000001 in the last cell: newTotal - distributedNewValue = (0.000002 - 0.000003)
// so we should check over allocation and break distribution
var tempResult = Math.roundQuantity(distributedNewValue + newValue, decimals);
if (tempResult <= newTotal) {
result[targetIndexes[i]] = newValue;
distributedNewValue = tempResult;
}
else {
lastIndex = targetIndexes[i];
break;
}
}
}
else {
var factor = newTotal / oldTotal;
var distributedOldValue = 0;
for (var i = 0; i < targetIndexes.length - 1; i++) {
var oldValue = (sourceValues[targetIndexes[i]] || 0);
var newValue = Math.roundQuantity(oldValue * factor, decimals);
distributedOldValue = Math.roundQuantity(distributedOldValue + oldValue, decimals);
// example: passed 31 cells, but only 5 of them have values; so we should affect only these cells
if (distributedOldValue == oldTotal) {
lastIndex = targetIndexes[i];
break;
}
else {
result[targetIndexes[i]] = newValue;
distributedNewValue = Math.roundQuantity(distributedNewValue + newValue, decimals);
}
}
}
result[lastIndex] = Math.roundQuantity(newTotal - distributedNewValue, decimals);
return result;
};
(function ($) {
$.extend($.fn, {
busyIndicator: function (c) {
b = $(this);
var d = b.find(".k-loading-mask");
c ? d.length || (d = $("<div class='k-loading-mask'><span class='k-loading-text'>Loading...</span><div class='k-loading-image'/><div class='k-loading-color'/></div>").width(b.outerWidth()).height(b.outerHeight()).prependTo(b)) : d && d.remove()
}
});
})($);
HandleSSOAjaxReAuth = function ($xhr, retrycallBackfn, _retryCounter) {
if ($xhr.responseText && _retryCounter <=5) {
var newWindow = window.open('/Account/ssoAuthRefresh', 'ssoRefresh', "height=200,width=400,status=yes,toolbar=no,menubar=no,location=no");
setTimeout(retrycallBackfn, 5000);
} else {
//log the error message/display oops error
console.log("Failed ajax call for datarefresh!");
}
}