Files
pecklist/wwwroot/js/app.utilB.js
2018-06-28 23:08:13 +00:00

334 lines
11 KiB
JavaScript

/**
* app.utilB.js
* JavaScript browser utilities
*
*/
/*jslint browser : true, continue : true,
devel : true, indent : 2, maxerr : 50,
newcap : true, nomen : true, plusplus : true,
regexp : true, sloppy : true, vars : false,
white : true
*/
/*global $, app, getComputedStyle */
app.utilB = (function () {
'use strict';
//---------------- BEGIN MODULE SCOPE VARIABLES --------------
var
configMap = {
regex_encode_html: /[&"'><]/g,
regex_encode_noamp: /["'><]/g,
html_encode_map: {
'&': '&#38;',
'"': '&#34;',
"'": '&#39;',
'>': '&#62;',
'<': '&#60;'
}
},
decodeHtml, encodeHtml, getEmSize, getApiUrl, getUrlParams, formData, objectifyFormDataArray,
getMediaSize, prepareObjectForClient, fixDatesToStrings,
epochToShortDate, epochToLocalShortDate, epochToLocalShortDateTime, getCurrentDateTimeAsEpoch,
genListColumn,
genListColumnNoLink, autoComplete, prepareObjectDatesForServer,
fixStringToServerDate;
configMap.encode_noamp_map = $.extend({}, configMap.html_encode_map);
delete configMap.encode_noamp_map['&'];
//----------------- END MODULE SCOPE VARIABLES ---------------
//------------------- BEGIN UTILITY METHODS ------------------
// Begin decodeHtml
// Decodes HTML entities in a browser-friendly way
// See http://stackoverflow.com/questions/1912501/\
// unescape-html-entities-in-javascript
//
decodeHtml = function (str) {
return $('<div/>').html(str || '').text();
};
// End decodeHtml
// Begin encodeHtml
// This is single pass encoder for html entities and handles
// an arbitrary number of characters
//
encodeHtml = function (input_arg_str, exclude_amp) {
var
input_str = String(input_arg_str),
regex, lookup_map;
if (exclude_amp) {
lookup_map = configMap.encode_noamp_map;
regex = configMap.regex_encode_noamp;
} else {
lookup_map = configMap.html_encode_map;
regex = configMap.regex_encode_html;
}
return input_str.replace(regex,
function (match, name) {
return lookup_map[match] || '';
}
);
};
// End encodeHtml
// Begin getEmSize
// returns size of ems in pixels
//
getEmSize = function (elem) {
return Number(
getComputedStyle(elem, '').fontSize.match(/\d*\.?\d*/)[0]
);
};
// End getEmSize
//Begin getApiUrl
//returns url for api methods by parsing current window location url
//
getApiUrl = function () {
var u = window.location.href.replace(window.location.hash, "").replace('index.html', '') + "api/";
//is it a dev local url?
if (u.indexOf("localhost:8080") != -1) {
u = u.replace("8080", "8081");
}
// End getApiUrl
//fix for random recurrence of extraneous ? on iPhone when using api
//(Cannot post to http://gl-gztw.rhcloud.com/?api/list (404))
u = u.replace("?", "");
return u;
}
// Begin formData
// Get or set all form fields
//
formData = function (data) {
//fix dates into strings
prepareObjectForClient(data);
var inps = $(":input").get();
if (typeof data != "object") {
// return all data
data = {};
$.each(inps, function () {
if (this.name && (this.checked || /select|textarea/i.test(this.nodeName) || /text|hidden|password/i.test(this.type))) {
data[this.name] = $(this).val();
}
});
return data;
} else {
$.each(inps, function () {
if (this.name && data[this.name]) {
if (this.type == "checkbox" || this.type == "radio") {
$(this).prop("checked", (data[this.name]));
} else {
$(this).val(data[this.name]);
}
} else if (this.type == "checkbox") {
$(this).prop("checked", false);
}
});
return $(this);
}
};
// End formdata
// Begin getMediaSize
// Retrieves results of css media query in hidden pseudo element
// :after body element
//objectifyFormDataArray
getMediaSize = function () {
return window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/\"/g, '');
};
// End getMediaSize
//Begin objectifyFormDataArray
//takes name value form input pairs in array and turns into a keyed object
//suitable for sending as json object
//
objectifyFormDataArray = function (arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
if (arr[i] !== undefined) {
rv[arr[i].name] = arr[i].value.trim();//case 3205 added trim
}
return prepareObjectDatesForServer(rv);
}
//Prepare an object for server needed format before submission
//called by objectifyFormDataArray
prepareObjectDatesForServer = function (obj) {
if (Array.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
fixStringToServerDate(obj[i]);
}
} else {
fixStringToServerDate(obj);
}
return obj;
}
//
//Turn string date fields from client into server compatible format (Unix epoch like this: 1498262400 1499904000)
fixStringToServerDate = function (obj) {
var keys = Object.keys(obj);
keys.forEach(function (key) {
if (key.endsWith('Date') || key.startsWith('dt')) {
var value = obj[key];
if (value == null) {
obj[key] = '';
} else {
//this is the sample format we will see: 2017-07-13
//TODO: is this assuming UTC?
obj[key] = moment.utc(value, "YYYY-MM-DD").unix();
}
}
});
}
//This function exists to change the properties of the passed in object
//to values compatible with jquery form filling functions (mostly dates to strings for now)
//
prepareObjectForClient = function (obj) {
if (Array.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
fixDatesToStrings(obj[i]);
}
} else {
fixDatesToStrings(obj);
}
return obj;
}
//
//Turn date fields of object coming from db into stringified values for consumption by client
//turn null dates into empty strings and iso date values into strings in iso format
fixDatesToStrings = function (obj) {
var keys = Object.keys(obj);
keys.forEach(function (key) {
if (key.endsWith('Date') || key.startsWith('dt')) {
var value = obj[key];
if (value == null) {
obj[key] = '';
} else {
//Now with sqlite they come and go as unix epoch seconds
//needs to be yyyy-MM-dd
obj[key] = moment.utc(new Date(value * 1000)).format("YYYY-MM-DD");
}
}
});
}
//
//Turn date values coming in from server into displayable short date format
//used to display dates in various lists (where the source epoch is already localized)
epochToShortDate = function (epoch) {
if (epoch == null || epoch == 0) return '';
return moment.utc(new Date(epoch * 1000)).format("YYYY-MM-DD");
}
//
//LOCAL VERSION: Turn date values coming in from server into displayable short date format
//used to display dates in various lists where the source epoch is in UTC
epochToLocalShortDate = function (epoch) {
if (epoch == null || epoch == 0) return '';
var utdate = moment.utc(new Date(epoch * 1000));
var localdate = moment(utdate).local();
return localdate.format("YYYY-MM-DD");
}
//LOCAL VERSION: Turn date values coming in from server into displayable short date AND TIME format
//used to display dates in various lists where the source epoch is in UTC
epochToLocalShortDateTime = function (epoch) {
if (epoch == null || epoch == 0) return '';
var utdate = moment.utc(new Date(epoch * 1000));
var localdate = moment(utdate).local();
return localdate.format("YYYY-MM-DD LT");
}
//////////////////////////
//Get current date and time as a utc unix epoch
getCurrentDateTimeAsEpoch = function () {
return moment().utc().unix();
}
// Begin genListColumn
// This function is used to demarcate 'columns' of fields in basic list forms by wrapping each column field in html
//
genListColumn = function (val) {
return '<span class="gz-list-column">' + val + '</span>'
};
// End genListColumn
// Begin genListColumnNoLink
// This function is used to demarcate and style 'columns' of fields in basic list forms by wrapping each column field in html
// that are not link columns
genListColumnNoLink = function (val) {
return '<span class="gz-list-column-nolink">' + val + '</span>'
};
// End genListColumn
// Begin autoComplete
// This function is used to attach an autocomplete method to an input
//
autoComplete = function (controlId, acGetToken) {
$('#' + controlId).autocomplete({
serviceUrl: app.shell.stateMap.apiUrl + 'autocomplete',
params: {
acget: acGetToken
},
ajaxSettings: {
headers: app.api.getAuthHeaderObject()
}
});
};
// End autoComplete
// export methods
return {
decodeHtml: decodeHtml,
encodeHtml: encodeHtml,
getEmSize: getEmSize,
getApiUrl: getApiUrl,
getUrlParams: getUrlParams,
formData: formData,
getMediaSize: getMediaSize,
objectifyFormDataArray: objectifyFormDataArray,
epochToShortDate: epochToShortDate,
epochToLocalShortDate: epochToLocalShortDate,
epochToLocalShortDateTime: epochToLocalShortDateTime,
getCurrentDateTimeAsEpoch: getCurrentDateTimeAsEpoch,
genListColumn: genListColumn,
genListColumnNoLink: genListColumnNoLink,
autoComplete: autoComplete
};
//------------------- END PUBLIC METHODS ---------------------
}());