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
javaxt.dhtml.utils.confirm({
title: "Quit Game?",
text: "Are you sure you want to quit the game?",
leftButton: {
label: "Yes",
value: true
},
rightButton: {
label: "No",
value: false
},
callback: function(answer){
if (answer===true) console.log("quit game");
else console.log("continue game");
}
});
@param msg String with question/prompt or a JSON config like the example
above. If passing a string, a default config is used which can be
overridden using the optional "config" parameter.
@param config JSON config like the example above. Additional config options
are available. See the javaxt.dhtml.Window config for more information.
This parameter is optional.
*/
confirm: function(msg, config){
var win = javaxt.dhtml.utils.Confirm;
if (win && win.isOpen()) return;
if (!(typeof(msg) === 'string' || msg instanceof String)){
config = msg;
}
if (!config) config = {};
javaxt.dhtml.utils.merge(config, {
title: "Confirm",
text: msg
});
//Create new window as needed
if (!win){
var createElement = javaxt.dhtml.utils.createElement;
var merge = javaxt.dhtml.utils.merge;
var buttonDiv = createElement("div", "button-div");
var createButton = function(label, result){
var input = createElement("input", buttonDiv, "form-button");
input.type = "button";
input.onclick = function(){
win.result = this.result;
win.close();
};
input.setLabel = function(label){
if (label) this.name = this.value = label;
};
input.setValue = function(b){
if (b===true || b===false) this.result = b;
};
input.update = function(config){
if (config){
this.setLabel(config.label);
this.setValue(config.value);
}
};
input.setLabel(label);
input.setValue(result);
return input;
};
merge(config, {
width: 450,
height: 150,
valign: "top",
modal: true,
footer: buttonDiv,
style: merge(
{ body: "window-body confirm-body" },
javaxt.dhtml.style.default.window
)
});
win = new javaxt.dhtml.Window(document.body, config);
javaxt.dhtml.utils.Confirm = win;
win.leftButton = createButton("OK", true);
win.rightButton = createButton("Cancel", false);
}
win.setTitle(config.title);
win.setContent(config.text.replace("\n",""));
win.leftButton.update(config.leftButton);
win.rightButton.update(config.rightButton);
win.result = false;
win.onClose = function(){
var callback = config.callback;
if (callback) callback.apply(win, [win.result]);
};
win.show();
return win;
}
};