if(!javaxt) var javaxt={}; if(!javaxt.dhtml) javaxt.dhtml={}; //****************************************************************************** //** Utils //*****************************************************************************/ /** * Common functions and utilities used by the webcontrols * ******************************************************************************/ javaxt.dhtml.utils = { //************************************************************************** //** get //************************************************************************** /** Used to execute an HTTP GET request. Example:
    get(url + "?filter=" + encodeURIComponent(filter), {
        success: function(text){
            var arr = JSON.parse(text).records;
        },
        failure: function(request){
            alert(request.status);
        }
    });
   
* @param url Required. * @param config Optional. Common config settings include a "success" * callback function, "failure" callback function, and "payload". Note that * if a payload is given, an HTTP POST request will be executed. See the * http() method for a full range of options. */ get: function(url, config){ if (!config) config = {}; if (config.payload!=null){ //convert to post request var payload = config.payload; delete config.payload; return javaxt.dhtml.utils.post(url, payload, config); } var settings = { method: "GET", payload: null }; javaxt.dhtml.utils.merge(settings, config); return javaxt.dhtml.utils.http(url, settings); }, //************************************************************************** //** post //************************************************************************** /** Used to execute an HTTP POST request. */ post: function(url, payload, config){ var settings; if (payload.payload){ settings = payload; settings.method = "POST"; } else{ var settings = { method: "POST", payload: payload }; javaxt.dhtml.utils.merge(settings, config); } return javaxt.dhtml.utils.http(url, settings); }, //************************************************************************** //** delete //************************************************************************** /** Used to execute an HTTP DELETE request. */ delete: function(url, config){ if (!config) config = {}; config.method = "DELETE"; return javaxt.dhtml.utils.http(url, config); }, //************************************************************************** //** http //************************************************************************** /** Used to execute an HTTP request. */ http: function(url, config){ if (!config) config = { method: "GET" }; var cache = false; //no caching by default! if (config.cache){ if (config.cache==true) cache = true; } if (!cache){ if (url.indexOf("?")==-1) url += "?"; url += "&_=" + new Date().getTime(); } var method = config.method; var success = config.success; var scope = config.scope; var async = true; if (config.async){ if (config.async!=false) async = true; } var failure = config.failure; if (typeof failure === "undefined") failure = function(request){ if (request.status!==0){ alert(request); } }; var request = new XMLHttpRequest(); if (config.username && config.password){ request.open(method, url, async, config.username, config.password); request.setRequestHeader("Authorization", "Basic " + btoa(config.username + ":" + config.password)); //<-- Needed to add this sometime in mid 2018... } else{ request.open(method, url, async); } if (!cache) request.setRequestHeader("Cache-Control", "no-cache, no-transform"); if (config.contentType){ //Example: 'application/x-www-form-urlencoded' request.setRequestHeader("Content-Type", config.contentType); } request.onreadystatechange = function(){ if (request.readyState === 4) { if (request.status>=200 && request.status<300){ if (success) success.apply(scope, [request.responseText, request.responseXML, request.responseURL, request]); } else{ if (failure) failure.apply(scope, [request]); } if (config.finally) config.finally.apply(scope, [request]); } }; if (config.payload){ var payload = config.payload; //Stringify the payload as needed if (javaxt.dhtml.utils.isArray(payload)){ payload = JSON.stringify(payload); } else{ if (payload != null && typeof payload == 'object' && !(payload instanceof FormData)){ payload = JSON.stringify(payload); } } request.send(payload); } else request.send(); return request; }, //************************************************************************** //** getParameter //************************************************************************** /** Returns the value of a given parameter name in a URL querystring * @param name Parameter name * @param url URL (e.g. window.location.href) */ getParameter: function(name, url){ name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); if (!url) url = window.location.href; var regexS = "[\\?&]"+name+"=([^&#]*)"; var regex = new RegExp( regexS ); var results = regex.exec(url); if (results == null) return ""; else return results[1]; }, //************************************************************************** //** merge //************************************************************************** /** Used to merge properties from one json object into another. * @credit https://github.com/stevenleadbeater/JSONT/blob/master/JSONT.js */ merge: function(settings, defaults) { var isElement = javaxt.dhtml.utils.isElement; var merge = function(settings, defaults) { if (settings==null) return; //Check if the settings is an array. Do not merge arrays! if (javaxt.dhtml.utils.isArray(settings)){ return; } for (var p in defaults) { if (defaults.hasOwnProperty(p) && typeof settings[p] !== "undefined") { if (p!=0){ //<--Added this as a bug fix if (isElement(settings[p]) || isElement(defaults[p])){ //do nothing... } else{ merge(settings[p], defaults[p]); } } } else { settings[p] = defaults[p]; } } }; merge(settings, defaults); return settings; }, //************************************************************************** //** clone //************************************************************************** /** Used to clone a json object */ clone: function(obj){ return javaxt.dhtml.utils.merge({}, obj); }, //************************************************************************** //** isDirty //************************************************************************** /** Returns true if the given json object differs from the original. */ isDirty: function(obj, org){ var isEmpty = javaxt.dhtml.utils.isEmpty; var a = isEmpty(obj); var b = isEmpty(org); if ((a==true && b==false) || (b==true && a==false)) return true; var d = javaxt.dhtml.utils.diff(obj, org); return !isEmpty(d); }, //************************************************************************** //** diff //************************************************************************** /** Used to compare 2 json objects. Returns a json object with differences. * @credit https://stackoverflow.com/a/13389935/ */ diff: function(obj1, obj2){ var isEmpty = javaxt.dhtml.utils.isEmpty; var merge = javaxt.dhtml.utils.merge; var diff = function(obj1, obj2){ var ret = {},rett; for (var i in obj2) { rett = {}; if (typeof obj2[i] === 'object'){ if (obj1.hasOwnProperty(i)){ rett = diff(obj1[i], obj2[i]); if (!isEmpty(rett) ){ ret[i]= rett; } } else{ ret[i] = obj2[i]; } } else{ if (!obj1 || !obj1.hasOwnProperty(i) || obj2[i] !== obj1[i]) { ret[i] = obj2[i]; } } } return ret; }; var d1 = diff(obj1, obj2); var d2 = diff(obj2, obj1); return merge(d1,d2); }, //************************************************************************** //** isEmpty //************************************************************************** /** Returns true if the given json object has no key/value pairs. */ isEmpty: function(obj){ return JSON.stringify(obj) === "{}"; }, //************************************************************************** //** isArray //************************************************************************** /** Used to check whether a given object is an array. Note that this check * does not use the "instanceof Array" approach because of issues with * frames. */ isArray: function(obj){ return (Object.prototype.toString.call(obj)==='[object Array]'); }, //************************************************************************** //** isString //************************************************************************** /** Return true if a given object is a string. */ isString: function(obj){ return (typeof obj === "string"); // || obj instanceof String) }, //************************************************************************** //** isNumber //************************************************************************** /** Return true if a given object is a number or can be parsed into a number. */ isNumber: function(n) { if (typeof n === "number") return true; if (typeof n !== "string") n = ""+n; return !isNaN(parseFloat(n)) && !isNaN(n - 0); }, //************************************************************************** //** isDate //************************************************************************** /** Return true if a given object can be parsed into a date. Returns false * if the object is a number (e.g. "3", "1.2") */ isDate: function(d) { //Don't pass numbers to Date.parse if (typeof d === "string" || typeof d === "number"){ var n = (d+"").replace(/[^-+0-9,.]+/g,""); if (d===n){ return false; } } return !isNaN(Date.parse(d)); }, //************************************************************************** //** isElement //************************************************************************** /** Return true if a given object is a DOM element. */ isElement: function(obj){ if (obj==null || typeof obj === 'undefined') return false; var b = (obj instanceof Element); //should work with 99% of the time //Special case for Firefox for DOM elements created in an iFrame (e.g. //JavaXT themes demo) if (!b && (navigator.userAgent.indexOf("Firefox") > -1)){ //If the object resembles a node, maybe it is a node? Not foolproof //but better than nothing... b = (typeof obj == "object" && "nodeType" in obj && obj.nodeType === 1 && obj.cloneNode); } return b; }, //************************************************************************** //** setStyle //************************************************************************** /** Used to set the style for a given element, replacing whatever style was * there before. * @param el DOM element. * @param style If a string is provided, assumes that the string represents * a CSS class name update "class" attribute of given element. If a JSON * object is provided, will assign the key/value pairs to the "style" * attribute of the node. */ setStyle: function(el, style){ if (el===null || el===0) return; if (style===null) return; //Special case for iScroll if (typeof IScroll !== 'undefined'){ if (el instanceof IScroll){ var indicators = el.indicators; if (indicators){ var indicatorClass = "iScrollIndicator"; if (style.indicator) indicatorClass = style.indicator; for (var i=0; i