663 lines
23 KiB
JavaScript
663 lines
23 KiB
JavaScript
var $$ = {
|
|
s: function (ct) { return $('<span></span>').text(ct); },
|
|
br: function () { return $('<br />'); },
|
|
sc: function (cls, ct) { return $('<span></span>').addClass(cls).text(ct); },
|
|
td: function (param1, param2) {
|
|
var td = $('<td></td>');
|
|
if ((param1 instanceof jQuery) === true) {
|
|
td.appendTo(param1);
|
|
} else if (typeof param1 === 'object') {
|
|
td.attr(param1);
|
|
} else if (typeof param1 === 'string') {
|
|
td.text(param1);
|
|
}
|
|
if (typeof param2 === 'object') {
|
|
td.attr(param2);
|
|
} else if (typeof param2 === 'string') {
|
|
td.text(param2);
|
|
}
|
|
return td;
|
|
},
|
|
th: function (param1, param2) {
|
|
var th = $('<th></th>');
|
|
if ((param1 instanceof jQuery) === true) {
|
|
th.appendTo(param1);
|
|
} else if (typeof param1 === 'object') {
|
|
th.attr(param1);
|
|
} else if (typeof param1 === 'string') {
|
|
th.text(param1);
|
|
}
|
|
if (typeof param2 === 'object') {
|
|
th.attr(param2);
|
|
} else if (typeof param2 === 'string') {
|
|
th.text(param2);
|
|
}
|
|
return th;
|
|
},
|
|
tdc: function (cls, param1, param2) { return $$.td(param1, param2).addClass(cls); },
|
|
td2: function (ct) {
|
|
var _td3 = $('<td colspan="2" />');
|
|
if ($.type(ct) === 'string') { _td3.text(ct); } else if (ct instanceof jQuery) { _td3.append(ct); } else if (typeof ct === 'function') { ct.call(_td3); } else { _td3.html(' '); }
|
|
return _td3;
|
|
},
|
|
td3: function (ct) {
|
|
var _td3 = $('<td colspan="3" />');
|
|
if ($.type(ct) === 'string') { _td3.text(ct); } else if (ct instanceof jQuery) { _td3.append(ct); } else if (typeof ct === 'function') { ct.call(_td3); } else { _td3.html(' '); }
|
|
return _td3;
|
|
},
|
|
tdtr: function (ct, tbl) {
|
|
var tr = $$.tr().appendTo(tbl);
|
|
if ((ct instanceof jQuery) === true || typeof ct === 'string') {
|
|
ct.appendTo($$.td().appendTo(tr));
|
|
} else if (Array.isArray(ct) === true) {
|
|
$.each(ct, function (ci, cx) {
|
|
$(cx).appendTo($$.td().appendTo(tr));
|
|
});
|
|
}
|
|
return tr;
|
|
},
|
|
tr: function (param1, param2) {
|
|
var tr = $('<tr></tr>');
|
|
if ((param1 instanceof jQuery) === true) {
|
|
tr.appendTo(param1);
|
|
} else if (typeof param1 === 'object') {
|
|
tr.attr(param1);
|
|
}
|
|
if (typeof param2 === 'object') {
|
|
tr.attr(param2);
|
|
}
|
|
return tr;
|
|
},
|
|
trc: function (cls, param1) {
|
|
var tr = $('<tr></tr>').addClass(cls);
|
|
if ((param1 instanceof jQuery) === true) {
|
|
tr.appendTo(param1);
|
|
} else if (typeof param1 === 'object') {
|
|
tr.attr(param1);
|
|
}
|
|
return tr
|
|
},
|
|
d: function (att) { return $('<div></div>').attr(att || {}); },
|
|
dc: function (cls, param1, param2, param3) {
|
|
var d = $('<div></div>').addClass(cls);
|
|
if ((param1 instanceof jQuery) === true) {
|
|
d.appendTo(param1);
|
|
} else if (typeof param1 === 'object') {
|
|
d.attr(param1);
|
|
} else if (typeof param1 === 'function') {
|
|
d.click(param1);
|
|
} else if (typeof param1 === 'string') {
|
|
d.text(param1);
|
|
}
|
|
if (typeof param2 === 'string') {
|
|
d.text(param2);
|
|
} else if (typeof param2 === 'object') {
|
|
d.attr(param2);
|
|
} else if (typeof param2 === 'function') {
|
|
d.click(param2);
|
|
}
|
|
if (typeof param3 === 'string') {
|
|
d.text(param3);
|
|
} else if (typeof param3 === 'object') {
|
|
d.attr(param3);
|
|
} else if (typeof param3 === 'function') {
|
|
d.click(param3);
|
|
}
|
|
return d;
|
|
},
|
|
df: function (att) { return $('<div> </div>').attr(att || {}); },
|
|
opt: function (param1, param2, param3) {
|
|
var d = $('<option></option>');
|
|
if (typeof param1 === 'string') {
|
|
d.attr('value', param1);
|
|
} else if (typeof param1 === 'object') {
|
|
d.attr(param1);
|
|
}
|
|
if (typeof param2 === 'string') {
|
|
d.text(param2);
|
|
} else if (typeof param2 === 'object') {
|
|
d.attr(param2);
|
|
}
|
|
if (typeof param3 === 'object') {
|
|
d.attr(param3);
|
|
}
|
|
return d;
|
|
},
|
|
eOpt: function (selected) {
|
|
var _eOpt = $('<option value=""> </option>');
|
|
if (selected || false) { _eOpt.attr('selected', 'selected'); }
|
|
return _eOpt;
|
|
},
|
|
tbl: function (att) { return $('<table></table>').attr(att || {}); },
|
|
tblc: function (cls) { return $('<table></table>').addClass(cls); },
|
|
thead: function (tbl) { let h = $('<thead></thead>'); if (tbl instanceof jQuery) { h.prependTo(tbl); } return h; },
|
|
tbody: function (tbl) { let b = $('<tbody></tbody>'); if (tbl instanceof jQuery) { b.appendTo(tbl); } return b; },
|
|
tblset: function (att, parent) {
|
|
let b = $$.tbl(att || {});
|
|
if (parent instanceof jQuery) {
|
|
parent.append(b);
|
|
}
|
|
return { tbl: b, hd: $$.thead().appendTo(b), bdy: $$.tbody().appendTo(b) };
|
|
},
|
|
i: function (att) { return $('<input />').attr(att || {}); },
|
|
img: function (src, att) { return $('<img />').attr('src', src).attr(att || {}); },
|
|
sel: function (att) { return $('<select></select>').attr(att || {}); },
|
|
btn: function (att) { return $('<button></button>').attr(att || {}); },
|
|
a: function (att) { return $('<a></a>').attr(att || {}); },
|
|
li: function (att) { return $('<li></li>').attr(att || {}); },
|
|
ul: function (att) { return $('<ul></ul>').attr(att || {}); },
|
|
nav: function (att) { return $('<nav></nav>').attr(att || {}); },
|
|
lbl: function (ct, att) {
|
|
var l = $('<label></label>');
|
|
if (typeof ct === 'string') {
|
|
l.text(ct);
|
|
}
|
|
if (typeof ct === 'object') {
|
|
l.attr(ct);
|
|
} else if (typeof att === 'object') {
|
|
l.attr(att);
|
|
}
|
|
return l;
|
|
},
|
|
txt: function (att) { return $('<textarea></textarea>').attr(att || {}); },
|
|
0: function (tag, att) { return $('<' + tag + '></' + tag + '>').attr(att || {}); },
|
|
/* bootstrap */
|
|
bbtn: function (txt, cls) { return $$.btn({ type: 'button', class: 'btn' }).addClass(cls).text(txt); },
|
|
svg: (tag) => {
|
|
return $(document.createElementNS('http://www.w3.org/2000/svg', tag));
|
|
}
|
|
};
|
|
String.prototype.trim = function () { return this.replace(/^\s+|\s+$/g, ''); };
|
|
String.prototype.left = function (n) {
|
|
if ($.type(n) === 'string') {
|
|
var i = this.indexOf(n);
|
|
if (i > 0)
|
|
return this.slice(0, i);
|
|
else
|
|
return "";
|
|
} else {
|
|
return this.substring(0, n);
|
|
}
|
|
};
|
|
String.prototype.right = function (n) {
|
|
if ($.type(n) === 'string') {
|
|
var i = this.indexOf(n);
|
|
if (i > 0)
|
|
return this.substring(this.length - i);
|
|
else
|
|
return "";
|
|
} else {
|
|
return this.substring(this.length - n);
|
|
}
|
|
};
|
|
Array.prototype.move = function (old_index, new_index) {
|
|
if (new_index >= this.length) {
|
|
var k = new_index - this.length;
|
|
while ((k--) + 1) {
|
|
this.push(undefined);
|
|
}
|
|
}
|
|
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
|
|
return this; // for testing purposes
|
|
};
|
|
function getMonday(d) {
|
|
d = new Date(d);
|
|
var day = d.getDay(),
|
|
diff = d.getDate() - day + (day == 0 ? -6 : 1); // adjust when day is sunday
|
|
return new Date(d.setDate(diff));
|
|
}
|
|
(function ($) {
|
|
$.fn.appendToIf = function (target, condition) {
|
|
var t = $(this), c = (typeof condition === 'function' ? condition(t) : condition);
|
|
if ((typeof c === 'boolean' ? c : true) === true) {
|
|
t.appendTo(target);
|
|
}
|
|
return t;
|
|
};
|
|
$.fn.appendIf = function (content, condition) {
|
|
var t = $(this), c = (typeof condition === 'function' ? condition(t) : condition);
|
|
if ((typeof c === 'boolean' ? c : true) === true) {
|
|
t.append(content);
|
|
}
|
|
return t;
|
|
};
|
|
$.fn.rwText = function (text, addtitle, options) {
|
|
var tgt = $(this).empty();
|
|
options = $.extend({ wrap: true }, options);
|
|
var sa = Array.isArray(text) === true ? text : (text || '').split('\n');
|
|
$.each(sa, function (ti, tx) {
|
|
if ((tx || '') !== '') {
|
|
if (ti > 0) {
|
|
tgt.append($$.br());
|
|
}
|
|
tgt.append(options.wrap === true ? $$.s(tx) : tx);
|
|
}
|
|
});
|
|
if (addtitle || false) { tgt.attr('title', addtitle); }
|
|
return tgt;
|
|
};
|
|
$.fn.loadSel = function (url, data, complete) {
|
|
if ($(this).prop('tagName').toUpperCase() === 'SELECT') {
|
|
var sel = $(this);
|
|
$ocms.postXT.call(this, {
|
|
url: url, data: data || {}, success: function (response) {
|
|
$.each(response, function () {
|
|
sel.append($$.opt(response.value, response.text));
|
|
});
|
|
}, complete: function () {
|
|
sel.ldng(0);
|
|
if (typeof complete === 'function') {
|
|
complete.call(sel);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
$.fn.emptyWithEditors = function (parent) {
|
|
var t = $(this);
|
|
t.find(':input.tinymce').each(function (ei, ex) {
|
|
try {
|
|
var te = tinymce.get($(ex).attr('id'));
|
|
if (te) { te.remove(); }
|
|
} catch (ee) {
|
|
$.noop();
|
|
}
|
|
});
|
|
return t.empty();
|
|
};
|
|
$.fn.cssValue = function (styleName) {
|
|
if (this.length > 0) {
|
|
var cv = this.css(styleName) || '';
|
|
if (cv === '') {
|
|
return 0;
|
|
} else {
|
|
var v, r = (/(^[\d\.]*)(\D{1,3}$)/ig).exec(cv);
|
|
if (r !== null) {
|
|
switch (r[2]) {
|
|
case 'rem':
|
|
return $ocms.rpx(parseFloat(r[1]));
|
|
default:
|
|
return parseFloat(r[1]);
|
|
}
|
|
} else if (isNaN(cv) === false) {
|
|
return parseFloat(cv)
|
|
} else { return 0; }
|
|
}
|
|
} else { return 0; }
|
|
};
|
|
/* @description: gets very inner height excluding borders and padding */
|
|
$.fn.veryInnerHeight = function () {
|
|
let c = (p) => $(this).cssValue(p);
|
|
return ($(this).innerHeight() - c('padding-top') - c('padding-bottom'));
|
|
};
|
|
/* @description: gets very inner width excluding borders and padding */
|
|
$.fn.veryInnerWidth = function () {
|
|
let c = (p) => $(this).cssValue(p);
|
|
return ($(this).innerWidth() - c('padding-left') - c('padding-right'));
|
|
};
|
|
$.fn.marginWidth = function() {
|
|
let c = (p) => $(this).cssValue(p);
|
|
return (c('margin-left') + c('margin-right'));
|
|
};
|
|
$.fn.marginHeight = function () {
|
|
let c = (p) => $(this).cssValue(p);
|
|
return (c('margin-top') + c('margin-bottom'));
|
|
};
|
|
|
|
$.inArrayRegEx = function (search, array, start) {
|
|
var regex = (($.type(search) === 'regexp') ? search : (new RegExp(search)));
|
|
if (!array) return -1;
|
|
start = start || 0;
|
|
for (var i = start; i < array.length; i++) {
|
|
if (regex.test(array[i])) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
/* @Desciption: Programmatically Lighten or Darken a hex color (or rgb, and blend colors)
|
|
* @author: Pimp Trizkit
|
|
* @source: internet http://stackoverflow.com/a/13542669
|
|
*
|
|
* usage:
|
|
* var color1 = "#FF343B";
|
|
* var color2 = "#343BFF";
|
|
* var color3 = "rgb(234,47,120)";
|
|
* var color4 = "rgb(120,99,248)";
|
|
* var shadedcolor1 = shadeBlend(0.75,color1);
|
|
* var shadedcolor3 = shadeBlend(-0.5,color3);
|
|
* var blendedcolor1 = shadeBlend(0.333,color1,color2);
|
|
* var blendedcolor34 = shadeBlend(-0.8,color3,color4); // Same as using 0.8
|
|
*/
|
|
$.shadeBlend = function (p, c0, c1) {
|
|
var n = p < 0 ? p * -1 : p, u = Math.round, w = parseInt;
|
|
var f, t;
|
|
if (c0.length > 7) {
|
|
f = c0.split(',');
|
|
t = (c1 ? c1 : p < 0 ? 'rgb(0,0,0)' : 'rgb(255,255,255)').split(',');
|
|
var R = w(f[0].slice(4)), G = w(f[1]), B = w(f[2]);
|
|
return 'rgb(' + (u((w(t[0].slice(4)) - R) * n) + R) + ',' + (u((w(t[1]) - G) * n) + G) + ',' + (u((w(t[2]) - B) * n) + B) + ')';
|
|
} else {
|
|
f = w(c0.slice(1), 16);
|
|
t = w((c1 ? c1 : p < 0 ? '#000000' : '#FFFFFF').slice(1), 16);
|
|
var R1 = f >> 16, G1 = f >> 8 & 0x00FF, B1 = f & 0x0000FF;
|
|
return '#' + (0x1000000 + (u(((t >> 16) - R1) * n) + R1) * 0x10000 + (u(((t >> 8 & 0x00FF) - G1) * n) + G1) * 0x100 + (u(((t & 0x0000FF) - B1) * n) + B1)).toString(16).slice(1);
|
|
}
|
|
};
|
|
$.fn.IN = function (complete) {
|
|
$(this).fadeIn(400, complete);
|
|
return $(this);
|
|
};
|
|
$.fn.OUT = function (complete) {
|
|
$(this).fadeOut(400, complete);
|
|
return $(this);
|
|
};
|
|
$.fn.tooltip = function (mouse, tree) {
|
|
var target = (typeof mouse === 'boolean' ? mouse : false) === true ? 'mouse' : false;
|
|
var cascade = typeof tree === 'boolean' ? tree : false;
|
|
var t = $(this);
|
|
t.each(function () {
|
|
var elem = cascade ? $(this).find('.tooltiptext') : $(this).children('.tooltiptext');
|
|
if ($(elem).length > 0) {
|
|
elem.each(function () {
|
|
var e = $(this), p = $(this).filter(':not(:empty)').parent();
|
|
p.qtip({
|
|
suppress: false,
|
|
content: {
|
|
text: e.clone()
|
|
},
|
|
position: {
|
|
target: target,
|
|
adjust: { x: 2, y: 2 },
|
|
viewport: true
|
|
},
|
|
events: {
|
|
hidden: $ocms.tooltip_hidden
|
|
}, show: { effect: false }, hide: { effect: false }
|
|
});
|
|
e.remove()
|
|
});
|
|
} else {
|
|
$(this).qtip({
|
|
position: {
|
|
target: target,
|
|
adjust: { x: 2, y: 2 },
|
|
viewport: true
|
|
},
|
|
events: {
|
|
hidden: $ocms.tooltip_hidden
|
|
}, effect: false
|
|
});
|
|
}
|
|
});
|
|
return t;
|
|
};
|
|
|
|
$.fn.rC = function (arg) {
|
|
return $(this).removeClass(arg);
|
|
};
|
|
$.fn.aC = function (arg) {
|
|
return $(this).addClass(arg);
|
|
};
|
|
$.fn.tC = function (arg, state) {
|
|
return $(this).toggleClass(arg, state);
|
|
};
|
|
})(jQuery);
|
|
function $lf(vis) {
|
|
var ts = typeof vis === 'undefined' ? null : ((typeof vis === 'number' && vis !== 1) || (typeof cl === 'boolean' && vis === false));
|
|
return $('#listframe').tC('hd', ts).is('.hd');
|
|
};
|
|
function $nuf(e) {
|
|
if (e) { e.stopPropagation(); }
|
|
if ($(this).is('.disabled')) {
|
|
return;
|
|
}
|
|
/* close any nav */
|
|
var f = function (nav) { nav.removeClass('vis').find('li.dropdown').removeClass('open').removeClass('vis').attr('aria-expanded', 'false'); }
|
|
var p = $(this).parent('li.dropdown');
|
|
if (p.length > 0) {
|
|
p.tC('open'), navs = p.is('.open') === true ? 'true' : 'false';
|
|
p.attr('aria-expanded', navs);
|
|
/* close any other branch */
|
|
var thisnav = p.closest('nav');
|
|
thisnav.find('li.dropdown').not(p.parentsUntil('nav')).not(p).removeClass('open').attr('aria-expanded', 'false');
|
|
if (p.is('.open') === false) {
|
|
p.find('li.dropdown').removeClass('open').attr('aria-expanded', 'false');
|
|
}
|
|
f($('nav').not(thisnav));
|
|
} else {
|
|
f($('nav'));
|
|
}
|
|
};
|
|
function $tbr() {
|
|
$lf(0);
|
|
return $('#topbar').ocmsmenu([]);
|
|
};
|
|
//function $sbr(empty) {
|
|
// return $('#sidebar').ocmsmenu([], empty);
|
|
//};
|
|
function $lfr() {
|
|
$('#sidebar').empty();
|
|
return $('#listframe').removeClass('fix').addClass('hd').empty();
|
|
};
|
|
function $cfr() {
|
|
$tbr();
|
|
return $('#contentframe').empty();
|
|
};
|
|
function jObj(jsstr, key) {
|
|
let jo = {};
|
|
if ((jsstr || '').substr(0, 1) === '{') {
|
|
try {
|
|
jo = JSON.parse(jsstr);
|
|
} catch (e) {
|
|
jo = {};
|
|
}
|
|
}
|
|
return jo[key] || '';
|
|
};
|
|
(function ($) {
|
|
$.fn.ocmsmenu = function (menu, empty) {
|
|
var tgt = $(this);
|
|
$ocms.menu.call(tgt, menu, empty);
|
|
return tgt;
|
|
};
|
|
$.fn.activatemenu = function () {
|
|
var tgt = $(this).filter('nav');
|
|
tgt.find('a').not('.on').addClass('on').click($nuf);
|
|
tgt.find('.nav-btn').not('.on').addClass('on').click(function (e) {
|
|
e.stopPropagation();
|
|
var t = $(this); $(t.attr('data-target')).tC(t.attr('data-toggle'));
|
|
});
|
|
return tgt;
|
|
};
|
|
})(jQuery);
|
|
function string(inp, vals) {
|
|
var ret = inp || '', rx;
|
|
$.each(vals || [], function (vi, vx) {
|
|
rx = new RegExp('\\{' + vi.toString() + '\\}', 'ig');
|
|
ret = ret.replace(rx, vx);
|
|
});
|
|
return ret;
|
|
};
|
|
function init_tooltip(mouse) {
|
|
var target = (typeof mouse === 'boolean' ? mouse : false) === true ? 'mouse' : false;
|
|
$('[title]').qtip({
|
|
position: {
|
|
target: target,
|
|
adjust: { x: 2, y: 2 },
|
|
viewport: true
|
|
},
|
|
events: {
|
|
hidden: $ocms.tooltip_hidden
|
|
}, effect: false
|
|
});
|
|
$('div.tooltiptext').each(function () {
|
|
var p = $(this).filter(':not(:empty)').parent();
|
|
p.qtip({
|
|
suppress: false,
|
|
content: {
|
|
text: $(this).clone()
|
|
},
|
|
position: {
|
|
target: target,
|
|
adjust: { x: 2, y: 2 },
|
|
viewport: true
|
|
},
|
|
events: {
|
|
hidden: $ocms.tooltip_hidden
|
|
}
|
|
});
|
|
});
|
|
}
|
|
class ObjectArray extends Array {
|
|
/**
|
|
* Get whether the Array is empty
|
|
* */
|
|
isEmpty() {
|
|
return this[0].length === 0;
|
|
}
|
|
|
|
// built-in methods will use this as the constructor
|
|
static get [Symbol.species]() {
|
|
return Array;
|
|
}
|
|
/**
|
|
* returns a new new array of items where function applied to currentvalue returns true
|
|
* @param {function(currentValue[, index[, array]])} fnc
|
|
*/
|
|
filter(fnc) {
|
|
if (typeof fnc === 'function') {
|
|
return new ObjectArray(this[0].filter(fnc));
|
|
} else {
|
|
return this;
|
|
}
|
|
}
|
|
/**
|
|
* removes items where function applied to currentvalue is true
|
|
* changes the ObjectArray itself and returns it
|
|
* @param {function(currentValue[, index[, array]])} fnc
|
|
*/
|
|
remove(fnc) {
|
|
if (typeof fnc === 'function') {
|
|
let i = this[0].findIndex(fnc);
|
|
while (i > -1) {
|
|
this[0].splice(i);
|
|
i = this[0].findIndex(fnc);
|
|
};
|
|
} else {
|
|
return this;
|
|
}
|
|
}
|
|
/**
|
|
* sorts the ObjectArray using the Array.sort function and returns it
|
|
* @param {function(element)} fnc
|
|
*/
|
|
sortBy(fnc) {
|
|
if (typeof fnc === 'function') {
|
|
this[0].sort(fnc);
|
|
}
|
|
return this;
|
|
}
|
|
/**
|
|
* sorts the ObjectArray using the Array.sort function and String.localeCompare function and returns it
|
|
* The compared strings are converted to upper case to make function case-insensitive
|
|
* undefined values are treated as empty strings
|
|
* @param {string} property
|
|
*/
|
|
sortString(property) {
|
|
this[0].sort((a, b) => {
|
|
let nameA = (a[property] || '').toString().toUpperCase(); // ignore upper and lowercase
|
|
let nameB = (b[property] || '').toString().toUpperCase(); // ignore upper and lowercase
|
|
console.debug(nameA.localeCompare(nameB));
|
|
return nameA.localeCompare(nameB);
|
|
});
|
|
return this;
|
|
}
|
|
/**
|
|
* sorts the ObjectArray using the Array.sort function and value comparison and returns it
|
|
* empty or non-numeric values are identified by isNaN and put to End of array
|
|
* @param {string} property
|
|
*/
|
|
sortNum(property) {
|
|
this[0].sort((a, b) => {
|
|
let nameA = a[property], nameB = b[property];
|
|
if ((isNaN(nameB) === true && isNaN(nameA) === false) || nameA < nameB) {
|
|
return -1;
|
|
} else if ((isNaN(nameB) === false && isNaN(nameA) === true) || nameA > nameB) {
|
|
return 1;
|
|
} else {
|
|
// names must be equal
|
|
return 0;
|
|
}
|
|
});
|
|
return this;
|
|
}
|
|
/**
|
|
* sums the value of the objects parameter, if value is valid number
|
|
* @param {string} property
|
|
*/
|
|
sum(property) {
|
|
return this[0].reduce((accumulator, currentValue) => accumulator + (isNaN(currentValue[property]) === true ? 0 : currentValue[property]), 0)
|
|
}
|
|
/**
|
|
* returns new object with array by named property value
|
|
* @param {string} property
|
|
*/
|
|
groupBy(property) {
|
|
return this[0].reduce(function (acc, obj) {
|
|
let key = obj[property];
|
|
if (!acc[key]) {
|
|
acc[key] = [];
|
|
}
|
|
acc[key].push(obj);
|
|
return acc;
|
|
}, {});
|
|
}
|
|
/**
|
|
*
|
|
* @param {function(value, index, array)} fnc
|
|
*/
|
|
each(fnc) {
|
|
if (typeof fnc === 'function') {
|
|
let stop = false;
|
|
this[0].forEach((value, index, array) =>{
|
|
if (stop === false) {
|
|
let r = fnc(value, index, array);
|
|
if (typeof r === 'boolean' && r === false) {
|
|
stop = true;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
get toArray() {
|
|
return this[0];
|
|
}
|
|
}
|
|
class NumArray extends Array {
|
|
sum() {
|
|
return this.reduce((accumulator, currentValue) => accumulator + currentValue);
|
|
};
|
|
first() {
|
|
return this[0];
|
|
};
|
|
last() {
|
|
return this[this.length - 1];
|
|
};
|
|
average() {
|
|
return this.sum() / this.length;
|
|
};
|
|
range() {
|
|
let self = this.map(x => x).sort(); /* do not change original */
|
|
return {
|
|
min: self[0],
|
|
max: self[this.length - 1]
|
|
}
|
|
};
|
|
|
|
// built-in methods will use this as the constructor
|
|
static get [Symbol.species]() {
|
|
return Array;
|
|
}
|
|
} |