Last active
November 14, 2016 12:15
-
-
Save vmandic/5ee0902057d3b8a84643a128aa444575 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Some common and useful extensions for vanilla.js, knockout.js and jquery.js. | |
if(ko && ko.extenders) { | |
ko.extenders.roundToDotQuater = function (target) { | |
if (mogy.options.roundDecimalsToQuaters) { | |
var result = ko.pureComputed({ | |
read: target, | |
write: function (newValue) { | |
target((Math.round(Math.round10(newValue, 2) * 4) / 4).toFixed(2)); | |
} | |
}).extend({ notify: "always" }); | |
result(target()); | |
return result; | |
} else { | |
return target; | |
} | |
}; | |
} | |
if(ko && ko.extenders) { | |
ko.extenders.numeric = function (target, precision) { | |
//create a writable computed observable to intercept writes to our observable | |
var result = ko.pureComputed({ | |
read: target, //always return the original observables value | |
write: function (newValue) { | |
var current = target(), | |
roundingMultiplier = Math.pow(10, precision), | |
newValueAsNum = isNaN(newValue) ? 0 : +newValue, | |
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier; | |
//only write if it changed | |
if (valueToWrite !== current) { | |
target(valueToWrite); | |
} else { | |
//if the rounded value is the same, but a different value was written, force a notification for the current field | |
if (newValue !== current) { | |
target.notifySubscribers(valueToWrite); | |
} | |
} | |
} | |
}).extend({ notify: "always" }); | |
//initialize with current value to make sure it is rounded appropriately | |
result(target()); | |
//return the new computed observable | |
return result; | |
}; | |
} | |
Array.prototype.getUnique = function () { | |
var u = {}, a = []; | |
for (var i = 0, l = this.length; i < l; ++i) { | |
if (u.hasOwnProperty(this[i])) { | |
continue; | |
} | |
a.push(this[i]); | |
u[this[i]] = 1; | |
} | |
return a; | |
} | |
if($ && ko && ko.bindingHandlers) { | |
ko.bindingHandlers.autocomplete = { | |
// jQuery autocomplete binding helper, maps the jq autocomplete feature to ko observable | |
init: function (element, params) { | |
$(element).autocomplete(params()); | |
}, | |
update: function (element, params) { | |
$(element).autocomplete("option", "source", params().source); | |
} | |
}; | |
} | |
// An extension method that can be plugged to an observable to find out the previous state of an observable. | |
// HOW TO/DEMO: http://jsfiddle.net/mbest/a24bnywz/6/ | |
if(ko && ko.subscribable) { | |
ko.subscribable.fn.subscribeChanged = function (callback) { | |
var savedValue = this.peek(); | |
return this.subscribe(function (latestValue) { | |
var oldValue = savedValue; | |
savedValue = latestValue; | |
callback(latestValue, oldValue); | |
}); | |
}; | |
} | |
(function () { | |
/** | |
* Decimal adjustment of a number. | |
* | |
* @param {String} type The type of adjustment. | |
* @param {Number} value The number. | |
* @param {Integer} exp The exponent (the 10 logarithm of the adjustment base). | |
* @returns {Number} The adjusted value. | |
*/ | |
function decimalAdjust(type, value, exp) { | |
// If the exp is undefined or zero... | |
if (typeof exp === 'undefined' || +exp === 0) { | |
return Math[type](value); | |
} | |
value = +value; | |
exp = +exp; | |
// If the value is not a number or the exp is not an integer... | |
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { | |
return NaN; | |
} | |
// Shift | |
value = value.toString().split('e'); | |
value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); | |
// Shift back | |
value = value.toString().split('e'); | |
return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)); | |
} | |
// Decimal round | |
if (!Math.round10) { | |
Math.round10 = function (value, exp) { | |
return decimalAdjust('round', value, exp * -1); | |
}; | |
} | |
// Decimal floor | |
if (!Math.floor10) { | |
Math.floor10 = function (value, exp) { | |
return decimalAdjust('floor', value, exp * -1); | |
}; | |
} | |
// Decimal ceil | |
if (!Math.ceil10) { | |
Math.ceil10 = function (value, exp) { | |
return decimalAdjust('ceil', value, exp * -1); | |
}; | |
} | |
})(); | |
//string format implementation | |
String.prototype.format = function () { | |
var args = arguments; | |
return this.replace(/{(\d+)}/g, function (match, number) { | |
return typeof args[number] != 'undefined' | |
? args[number] | |
: match | |
; | |
}); | |
}; | |
Array.prototype.move = function (from, to) { | |
//moves an element from one index to another in the array | |
this.splice(to, 0, this.splice(from, 1)[0]); | |
}; | |
Array.prototype.first = function (filterFunc) { | |
if (filterFunc) { | |
return this.filter(filterFunc)[0]; | |
} else { | |
return this ? this[0] : null; | |
} | |
}; | |
Array.prototype.last = function (filterFunc) { | |
if (filterFunc) { | |
var arr = this.filter(filterFunc); | |
return arr[arr.length - 1]; | |
} else { | |
if (this) { | |
return this[this.length - 1]; | |
} | |
return null; | |
} | |
}; | |
if (!Array.prototype.remove) { | |
(function () { | |
Array.prototype.remove = function (filter) { | |
var arr = this; | |
if (typeof filter == "function") { | |
var removedResults = []; | |
var arrResults = this.filter(filter); | |
if (arrResults.length > 0) { | |
arrResults.forEach(function (item) { | |
var index = arr.indexOf(item); | |
removedResults.push(arr.splice(index, 1)); | |
}); | |
return removedResults; | |
} else { | |
console.info("No results to be removed were found in the targeted array."); | |
return []; | |
} | |
} else if (typeof filter == "number") { | |
return arr.splice((filter - 1), 1); | |
} else { | |
throw new { | |
name: "Filter type invalid.", | |
message: "The provided filter type for Array.prototype.remove() is invalid. Please provide a filter function or element position number (not index!)." | |
} | |
} | |
} | |
})(); | |
} | |
// attach the .equals method to Array's prototype to call it on any array | |
Array.prototype.equals = function (array) { | |
// if the other array is a falsy value, return | |
if (!array) { | |
return false; | |
} | |
// compare lengths - can save a lot of time | |
if (this.length != array.length) { | |
return false; | |
} | |
for (var i = 0, l = this.length; i < l; i++) { | |
// Check if we have nested arrays | |
if (this[i] instanceof Array && array[i] instanceof Array) { | |
// recurse into the nested arrays | |
if (!this[i].equals(array[i])) { | |
return false; | |
} | |
} else if (this[i] !== array[i]) { | |
// Warning - two different object instances will never be equal: {x:20} != {x:20} | |
return false; | |
} | |
} | |
return true; | |
}; | |
if (!String.prototype.startsWith) { | |
(function () { | |
'use strict'; // needed to support `apply`/`call` with `undefined`/`null` | |
var defineProperty = (function () { | |
// IE 8 only supports `Object.defineProperty` on DOM elements | |
try { | |
var object = {}; | |
var $defineProperty = Object.defineProperty; | |
var result = $defineProperty(object, object, object) && $defineProperty; | |
} catch (error) { } | |
return result; | |
}()); | |
var toString = {}.toString; | |
var startsWith = function (search) { | |
if (this == null) { | |
throw TypeError(); | |
} | |
var string = String(this); | |
if (search && toString.call(search) == '[object RegExp]') { | |
throw TypeError(); | |
} | |
var stringLength = string.length; | |
var searchString = String(search); | |
var searchLength = searchString.length; | |
var position = arguments.length > 1 ? arguments[1] : undefined; | |
// `ToInteger` | |
var pos = position ? Number(position) : 0; | |
if (pos != pos) { // better `isNaN` | |
pos = 0; | |
} | |
var start = Math.min(Math.max(pos, 0), stringLength); | |
// Avoid the `indexOf` call if no match is possible | |
if (searchLength + start > stringLength) { | |
return false; | |
} | |
var index = -1; | |
while (++index < searchLength) { | |
if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
if (defineProperty) { | |
defineProperty(String.prototype, 'startsWith', { | |
'value': startsWith, | |
'configurable': true, | |
'writable': true | |
}); | |
} else { | |
String.prototype.startsWith = startsWith; | |
} | |
}()); | |
} | |
if (!String.prototype.endsWith) { | |
(function () { | |
'use strict'; // needed to support `apply`/`call` with `undefined`/`null` | |
var defineProperty = (function () { | |
// IE 8 only supports `Object.defineProperty` on DOM elements | |
try { | |
var object = {}; | |
var $defineProperty = Object.defineProperty; | |
var result = $defineProperty(object, object, object) && $defineProperty; | |
} catch (error) { } | |
return result; | |
}()); | |
var toString = {}.toString; | |
var endsWith = function (search) { | |
if (this == null) { | |
throw TypeError(); | |
} | |
var string = String(this); | |
if (search && toString.call(search) == '[object RegExp]') { | |
throw TypeError(); | |
} | |
var stringLength = string.length; | |
var searchString = String(search); | |
var searchLength = searchString.length; | |
var pos = stringLength; | |
if (arguments.length > 1) { | |
var position = arguments[1]; | |
if (position !== undefined) { | |
// `ToInteger` | |
pos = position ? Number(position) : 0; | |
if (pos !== pos) { // better `isNaN` | |
pos = 0; | |
} | |
} | |
} | |
var end = Math.min(Math.max(pos, 0), stringLength); | |
var start = end - searchLength; | |
if (start < 0) { | |
return false; | |
} | |
var index = -1; | |
while (++index < searchLength) { | |
if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
if (defineProperty) { | |
defineProperty(String.prototype, 'endsWith', { | |
'value': endsWith, | |
'configurable': true, | |
'writable': true | |
}); | |
} else { | |
String.prototype.endsWith = endsWith; | |
} | |
}()); | |
} | |
if (!String.prototype.contains) { | |
String.prototype.contains = function () { | |
return String.prototype.indexOf.apply(this, arguments) !== -1; | |
}; | |
} | |
if (!String.prototype.replaceAll) { | |
String.prototype.replaceAll = function (search, replacement) { | |
var target = this; | |
return target.split(search).join(replacement); | |
}; | |
} | |
if (!String.prototype.padLeft) { | |
String.prototype.padLeft = function (width, z) { | |
var n = this; | |
z = z || '0'; | |
n = n + ''; | |
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; | |
} | |
} | |
if (!String.prototype.padRight) { | |
String.prototype.padRight = function (width, z) { | |
var n = this; | |
z = z || '0'; | |
n = n + ''; | |
return n.length >= width ? n : n + new Array(width - n.length + 1).join(z); | |
} | |
} | |
// Refreshes the currently saved jquery variable by using the existing selector. | |
if($ && $.fn){ | |
$.fn.refresh = function () { | |
var elems = $(this.selector); | |
this.splice(0, this.length); | |
this.push.apply(this, elems); | |
return this; | |
}; | |
} | |
// Retrieves a value from the current query string for a given string key. | |
function getQueryStringParameterByName(name) { | |
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); | |
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), | |
results = regex.exec(location.search); | |
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); | |
} | |
function parseBool(str) { | |
if (str != null | |
&& str != undefined | |
&& typeof str === 'string' | |
&& str.toLowerCase() == 'true') { | |
return true; | |
} | |
if (typeof str == "boolean") return str; | |
return (parseInt(str) > 0); | |
} | |
if(ko && ko.mapping) { | |
function cloneObservable(obsObj) { | |
return ko.mapping.fromJS(ko.mapping.toJS(obsObj)); | |
} | |
} | |
function ObjectToArray(__o) { | |
return Object.keys(__o) | |
.filter(function (__k) { | |
return ((typeof __o[__k]) === "object"); | |
}) | |
.map(function (__k) { | |
return __o[__k]; | |
}); | |
} | |
// a and b are javascript Date objects | |
function getDiffInDaysBetweenDates(a, b) { | |
var _MS_PER_DAY = 1000 * 60 * 60 * 24; | |
// Discard the time and time-zone information. | |
var utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()); | |
var utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()); | |
return Math.floor((utc2 - utc1) / _MS_PER_DAY); | |
} | |
function removeZero(e) { | |
try { | |
if (Number(e.target.value) == 0) { | |
e.target.value = ""; | |
}; | |
} catch (ex) { | |
e.target.value = 0; | |
} | |
}; | |
function addZero(e) { | |
try { | |
if (!e.target.value || String(e.target.value).trim() === "" || Number(e.target.value) <= 0) { | |
e.target.value = 0; | |
} | |
} catch (ex) { | |
e.target.value = 0; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some common and useful extensions for vanilla.js, knockout.js and jquery.js.