utils.js | |
---|---|
var PDP = (function( pdp ) {
'use strict'; | |
UtilsAn assortment of helper methods and polyfills. | var utils = {}; |
Error visualization | utils.showError = function( errorText ) {
$('#error').text( errorText ).delay( 20000 ).fadeOut();
}; |
takes a variable name and returns a nice title ex. state_name becomes State | utils.varToTitle = function( varName ) {
var nameParts = varName.split('_'),
varTitle;
nameParts = nameParts.reverse(); |
a varName can have both 'name' and an int on the end | if ( isNaN(nameParts[0]) === false ) {
nameParts.splice(0, 1);
}
if ( nameParts[0] === 'name' ) {
nameParts.splice(0, 1);
}
if ( nameParts[0] === 'year' ) {
nameParts.splice(1, 2);
}
varTitle = nameParts.reverse().join(' ');
varTitle = varTitle.charAt(0).toUpperCase() + varTitle.slice(1);
return varTitle;
}; |
When given a number of bytes, this'll return a string with proper units. | utils.getPrettyFilesize = function( bytes ) {
if (bytes>=1073741824) {
bytes = ( bytes/1073741824 ).toFixed( 1 ) + ' GB';
} else if ( bytes>=1048576 ) {
bytes = ( bytes/1048576 ).toFixed( 1 ) + ' MB';
} else if ( bytes >= 1024 ) {
bytes = ( bytes/1024 ).toFixed( 0 ) + ' KB';
} else if ( bytes > 1 ) {
bytes = bytes + ' bytes';
} else if ( bytes == 1 ) {
bytes = bytes + ' byte';
} else {
bytes = '0 byte';
}
return bytes;
}; |
Return the hash parameters from the current URL. source | utils.getHashParams = function() {
var hashParams = {};
var e,
a = /\+/g, // Regex for replacing addition symbol with a space
r = /([^!&;=<>]+)(!?[=><]?)([^&;]*)/g,
d = function (s) { return decodeURIComponent(s.replace(a, ' ')); },
q = window.location.hash.substring(1).replace(/^!\/?/, '');
while (e = r.exec(q)) {
hashParams[d(e[1])] = {
values: d(e[3]),
comparator: d(e[2])
};
}
return hashParams;
}; |
Sanitize strings | utils.sanitize = function( string ) {
var tagBody = '(?:[^"\'>]|"[^"]*"|\'[^\']*\')*',
tagOrComment = new RegExp('<(?:!--(?:(?:-*[^->])*--+|-?)|script\\b' + tagBody + '>[\\s\\S]*?</script\\s*|style\\b' + tagBody + '>[\\s\\S]*?</style\\s*|/?[a-z]' + tagBody + ')>', 'gi');
function removeTags( html ) {
var oldHtml;
do {
oldHtml = html;
html = html.replace(tagOrComment, '');
} while (html !== oldHtml);
return html.replace(/</g, '<');
}
return removeTags( string );
}; |
Add commas to a number to make it pretty. | utils.commify = function( num ) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};
utils.isBlank = function (str) {
return (!str || /^\s*$/.test(str));
};
utils.emptyObject = function (obj) {
if (_.isObject(obj)) {
return !_.some(obj, function(val, key) {
return !pdp.utils.isBlank(val);
});
}
};
utils.nonEmptyValues = function (obj) {
if (!_.isObject(obj)) {
return [];
}
return _.filter(obj, function(val, key) {
return !pdp.utils.isBlank(val);
});
}; |
localStorage polyfill from https://gist.github.com/juliocesar/926500. Basically just creates an object in memory. | if ( !('localStorage' in window) ) {
window.localStorage = {
_data : {},
setItem : function(id, val) { return this._data[id] = String(val); },
getItem : function(id) { return this._data.hasOwnProperty(id) ? this._data[id] : undefined; },
removeItem : function(id) { return delete this._data[id]; },
clear : function() { return this._data = {}; }
};
} |
Cache AJAX requests in localStorage. | utils.getJSON = function( url ) {
var supportsLocalStorage = 'localStorage' in window,
keyPrefix = 'cfpb',
storageKey = keyPrefix + ':' + url.substring( url.indexOf('?') + 1 );
function getJSON( url ) {
var deferred = url.indexOf('jsonp') !== -1 ? $.jsonp({ url: url }) : $.getJSON( url );
deferred.done(function(data) {
|
if the request returns a status of 'computing' results are not ready and should not be cached | if (data && data.computing) {
return;
}
try {
localStorage.setItem( storageKey, JSON.stringify(data) );
} catch( e ) {
clearStorage();
} |
This is a safety to prevent the polyfill object from growing too huge. @TODO: Make this less lame. | if ( window.localStorage.length > 100 ) {
clearStorage();
}
});
return deferred;
}
function getStorage( url ) {
var storageDfd = new $.Deferred(),
storedData = localStorage.getItem( storageKey ),
promise;
if (!storedData) {
return getJSON( url );
}
setTimeout( function() {
storageDfd.resolveWith( null, [ JSON.parse(storedData) ] );
});
promise = storageDfd.promise();
promise.status = 200;
promise.statusText = 'success';
return promise;
}
function clearStorage() {
_.keys( localStorage ).forEach( function( key ){
if ( key.indexOf( keyPrefix ) !== -1 ) {
localStorage.removeItem(key);
}
});
}
window.clearStorage = clearStorage; |
Both functions return a promise, so no matter which function gets called, the API is the same. | return supportsLocalStorage ? getStorage( url ) : getJSON( url );
}; |
Pass a keypress event and its default action will be prevented if a non-numeric key was pressed. Numbers, commas, tab, delete, backspace, meta, A (for selecting all), V (for pasting) and arrow keys are allowed to be pressed. | utils.requireNumeric = function( e ) {
var key = e.which,
allowedKeys = [ 8, 9, 16, 17, 18, 36, 37, 38, 39, 40, 46, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 65, 86, 91, 93, 96, 97, 98, 99, 100, 101, 102,
103, 104, 105, 188, 189, 224 ];
if ( allowedKeys.indexOf( key ) === -1 ) {
e.preventDefault();
$( this ).tooltip( { title: 'Numbers only, please!', trigger: 'manual' } );
$( this ).tooltip( 'show' );
setTimeout( function(){
$( this ).tooltip('destroy');
}.bind( this ), 3000);
}
}; |
A | if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== 'function') { |
closest thing possible to the ECMAScript 5 internal IsCallable function | throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
FNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof FNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
};
FNOP.prototype = this.prototype;
fBound.prototype = new FNOP();
return fBound;
};
} |
A | String.prototype.splice = function( idx, rem, s ) {
return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
}; |
A | if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
if (this === null) {
throw new TypeError();
}
var n, k, t = Object(this),
len = t.length >>> 0;
if (len === 0) {
return -1;
}
n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n !== 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
for (k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
$.fn.initTooltips = function( options ){
var settings = $.extend({
placement: 'top',
container: false
}, options );
return this.find('.help').tooltip({
placement: settings.placement,
container: settings.container,
title: function getTooltipTitle(){
return $( this ).attr('title') || $( this ).next('.help-text').html();
}
});
};
pdp.utils = utils;
return pdp;
}( PDP || {} ));
|