/* PureJavascript version 3.7 */
/*
* PureJavacript, APIServer.js
*
* Copyright 2014 - 2020, CrossAdaptive
*
* License LGPL v2
*/
APIServer = Resolve;
APIServer.IsSubdomain = true;
function Resolve( host )
{
if ( host === undefined ) host = "api";
var base_domain = Resolve.ExtractBaseDomain( location.hostname );
var dom = "";
var http_port = Resolve.httpPort ? Resolve.httpPort : "80";
var https_port = Resolve.httpsPort ? Resolve.httpsPort : "443";
https_port = Resolve.IsLocalAPIServer() ? "8443" : https_port;
switch ( location.protocol )
{
case "http:":
dom = location.protocol + "//" + host + base_domain + ":" + http_port;
break;
case "https:":
dom = location.protocol + "//" + host + base_domain + ":" + https_port;
break;
}
return dom;
}
Resolve.ExtractBaseDomain
=
function( domain )
{
var base_domain = "";
var bits = domain.split( "-" );
if ( 1 == bits.length )
{
base_domain = bits[0];
}
else
{
base_domain = bits[1];
}
// If base_domain == 'example.com'
if ( Resolve.IsRegisteredDomain( base_domain ) )
{
// Then return '.example.com'
base_domain = "." + base_domain;
}
else
if ( APIServer.IsSubdomain )
{
// Then return '.myapp.example.com'
base_domain = "." + base_domain;
}
else // If base_domain == 'myapp.example.com'
{
// Then return '-myapp.example.com'
base_domain = "-" + base_domain;
}
return base_domain;
}
Resolve.IsLocalAPIServer
=
function()
{
return (-1 !== location.hostname.indexOf( ".local" )) || StringEndsWith( location.hostname, ".test" );
}
Resolve.IsRegisteredDomain
=
function( domain )
{
// First remove '.local' if it is on domain.
domain = domain.replace( ".local", "" );
// Could be:
//
// 1) example returns false
// 2) example.com returns true
// 3) example.com.au returns true
// 4) mydomain.example.com returns false
// 5) mydomain.example.com.au returns false
var bits = domain.split( "." );
switch ( bits.length )
{
case 1:
// Is an invalid domain so return false.
return false;
case 2:
// Is a registered domain if last bit is a TLD.
return Resolve.IsTopLevelDomain( bits[1] );
case 3:
// Is a registered domain if last bit is a TLD.
return Resolve.IsSecondLevelDomainOf( bits[1], bits[2] );
default:
// Any with more will not be registered domain.
return false;
}
}
Resolve.IsTopLevelDomain
=
function( tld )
{
switch( tld )
{
case "com":
case "net":
case "online":
case "org":
case "xyz":
return true;
default:
return false;
}
}
Resolve.IsSecondLevelDomainOf
=
function( sld, tld )
{
switch( tld )
{
case "au":
switch ( sld )
{
case "com":
case "net":
case "org":
case "info":
return true;
default:
return false;
}
break;
default:
return false;
}
}
/*
* PureJavacript, Auth.js
*
* Copyright 2014 - 2017, CrossAdaptive
*
* License LGPL v2
*/
Auth = {}
Auth.Login = Auth_Login;
Auth.Login.LocalStorage = Auth_Login_LocalStorage;
Auth.Logout = Auth_Logout;
Auth.LogoutAndReload = Auth_LogoutAndReload;
function Auth_Login( event )
{
Submit( event, Auth.Login.Handler );
}
function Auth_Login_LocalStorage( event )
{
Submit( event, Auth.Login.LocalStorageHandler );
}
function Auth_Logout( logout_api_url )
{
Auth.UnsetIDTypeCookie();
Auth.UnsetSessionIDTypeCookie();
Auth.UnsetCookie( "email" );
if ( logout_api_url )
{
Call( logout_api_url, new Array(), Auth.Logout.Handler );
}
else
{
Call( "/api/auth/logout/", new Array(), Auth.Logout.Handler );
}
if ( DataStorage.Local.HasItem( "sessionid" ) )
{
var storage = DataStorage.Local;
storage.RemoveItem( "idtype" );
storage.RemoveItem( "accessid" );
storage.RemoveItem( "email" );
storage.RemoveItem( "given" );
storage.RemoveItem( "group_code" );
storage.RemoveItem( "sessionid" );
storage.RemoveItem( "Authorization" );
}
UnsetCookie( "accessid" );
}
function Auth_LogoutAndReload( logout_api_url )
{
Auth.UnsetIDTypeCookie();
Auth.UnsetSessionIDTypeCookie();
Auth.UnsetCookie( "accessid" );
Auth.UnsetCookie( "email" );
Auth.UnsetCookie( "group_code" );
if ( logout_api_url )
{
Call( logout_api_url, new Array(), Auth.LogoutAndReload.Handler );
}
else
{
Call( "/auth/logout/", new Array(), Auth.LogoutAndReload.Handler );
}
}
Auth.Login.Handler
=
function ( responseText )
{
var json = JSON.parse( responseText );
if ( json.idtype )
{
Auth.Login.Handler.Orig( responseText );
}
else
{
Auth.Login.Handler.New( responseText );
}
}
Auth.Login.Handler.Orig
=
function ( responseText )
{
if ( "" != responseText )
{
var obj = JSON.parse( responseText );
if ( obj && obj.idtype )
{
Auth.SetIDTypeCookie( obj.idtype );
//Auth.SetSessionIDTypeCookie( obj.sessionid );
Auth.SetCookie( "email", obj.email, 1 );
Auth.SetCookie( "group_code", obj.group_code, 1 );
Redirect( obj.idtype ); // External Call
}
else
{
if ( obj["error"] == "INVALID_CREDENTIALS" )
{
var errorText = "Invalid username or password.";
}
else
{
var errorText = "Error logging in, please try again.";
}
var loginErrorDiv = document.getElementById( 'login-error' );
if ( loginErrorDiv )
{
loginErrorDiv.innerHTML = "";
loginErrorDiv.innerHTML = errorText;
}
else
{
alert( errorText );
}
}
}
else
{
Auth.Logout();
}
}
Auth.Login.Handler.New
=
function( responseText )
{
if ( "" != responseText )
{
var json = JSON.parse( responseText );
if ( "ERROR" == json.status )
{
switch ( json.error.split( " " )[0] )
{
case "INVALID_USER":
case "INVALID_PASSWORD":
case "INVALID_CREDENTIALS":
alert( "Invalid username or password." );
break;
case "INVALID_LOGINS":
alert( "Too many invalid logins have occurred. To reset your invalid login count, please reset your password." );
break;
default:
alert( "An unexpected error occurred, please try again later." );
}
}
else if ( json.results && (1 !== json.results.length) )
{
alert( "Session was not returned as expected, please try again later." );
}
else
{
var obj = json.results[0];
if ( obj && obj.idtype )
{
Auth.SetCookie( "accessid", obj.accessid, 1 );
//Auth.SetIDTypeCookie( obj.idtype );
//Auth.SetCookie( "Authorization", "", 1 );
//Auth.SetCookie( "email", obj.email, 1 );
//Auth.SetCookie( "given", obj.given_name, 1 );
//Auth.SetCookie( "group_code", obj.group_code, 1 );
var redirect_path = obj.redirect_path ? obj.redirect_path : "/";
var redirect_url = location.protocol + "//" + location.host + redirect_path;
location.assign( redirect_url );
}
}
}
}
Auth.Logout.Handler
=
function ( responseText )
{
location.assign( location.protocol + "//" + location.hostname + "/" );
}
Auth.LogoutAndReload.Handler
=
function ( responseText )
{
location.reload();
}
Auth.SetIDTypeCookie
=
function( idtype )
{
Auth.SetCookie( "idtype", idtype, 1 );
}
Auth.SetSessionIDTypeCookie
=
function( sid )
{
Auth.SetCookie( "sessionid", sid, 1 );
}
Auth.UnsetCookie
=
function ( cname )
{
document.cookie = cname + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}
Auth.UnsetIDTypeCookie
=
function ()
{
document.cookie = "idtype=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}
Auth.UnsetSessionIDTypeCookie
=
function ()
{
document.cookie = "sessionid=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}
Auth.SetCookie
=
function( cname, cvalue, exdays )
{
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + ";path=/;secure;SameSite=strict";
}
Auth.Login.LocalStorageHandler
=
function ( responseText )
{
var json = JSON.parse( responseText );
if ( "" != responseText )
{
var json = JSON.parse( responseText );
if ( "ERROR" == json.status )
{
switch ( json.error.split( " " )[0] )
{
case "INVALID_USER":
case "INVALID_PASSWORD":
case "INVALID_CREDENTIALS":
alert( "Invalid username or password." );
break;
case "INVALID_LOGINS":
alert( "Too many invalid logins have occurred. To reset your invalid login count, please reset your password." );
break;
default:
alert( "An unexpected error occurred, please try again later." );
}
}
else if ( json.results && (1 !== json.results.length) )
{
alert( "Session was not returned as expected, please try again later." );
}
else
{
var obj = json.results[0];
if ( obj && obj.idtype )
{
var storage = DataStorage.Local;
storage.SetItem( "sessionid", obj.sessionid );
Auth.SetCookie( "accessid", obj.accessid, 1 );
var redirect_path = obj.redirect_path ? obj.redirect_path : "/";
var redirect_url = location.protocol + "//" + location.host + redirect_path;
location.assign( redirect_url );
}
}
}
}
/*
* PureJavacript, Base64.js
*
* Copyright 2014 - 2017, CrossAdaptive
*
* License LGPL v2
*/
Base64 = {}
Base64.Encode = Base64Encode;
Base64.Decode = Base64Decode;
function Base64Encode( data )
{
return btoa( data );
}
function Base64Decode( base64 )
{
return atob( base64 );
}
/*
* PureJavacript, CSVFile.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function CSVFile( file_content )
{
this.headers = new Array();
this.rows = new Array();
this.parseContent( file_content );
}
CSVFile.prototype.getValueFor
=
function( row, labels )
{
var value = "";
var n = labels.length;
for ( var i=0; i < n; i++ )
{
var value = this.getValue( row, labels[i] );
if ( "" != value ) break;
}
if ( undefined == value ) value = "";
return value;
}
CSVFile.prototype.getValue
=
function( row, label )
{
var value = "";
var column = -1;
var n = this.headers.length;
for ( var i=0; i < n; i++ )
{
var text1 = label.toLowerCase().trim();
var text2 = this.headers[i].toLowerCase().trim();
if ( text1 == text2 )
{
column = i; break;
}
}
if ( -1 != column )
{
var array = this.rows[row];
value = array[column];
}
return value;
}
CSVFile.prototype.getNrOfRows
=
function()
{
return this.rows.length;
}
CSVFile.prototype.CSVLineRE = new RegExp('("[\\w ,]+" ?|[\\w ]*), ?("[\\w ,]+" ?|[\\w ]*)$');
CSVFile.prototype.parseContent
=
function( file_content )
{
var line_reader = new CSVFile.LineReader( file_content, 100000 );
var line = line_reader.readLine();
if ( false !== line )
{
var trimmed = line.trim(); //trims CRs from Mac apps such as Numbers.
//if (!this.CSVLineRE.test(trimmed)) throw "Header of file does not match expected Excel/LibreOffice CSV format."
this.headers = CSVFile.SplitAndTrim( trimmed );
while ( (false !== (line = line_reader.readLine())) )
{
var fields = CSVFile.SplitAndTrim( line );
if ( "" != fields.join( "" ) )
{
this.rows.push( fields );
}
}
}
}
CSVFile.SplitAndTrim
=
function( line )
{
var line = line.replace( /^/, '' );
var array = new Array();
var bits = CSVFile.SplitWhileRespectingQuotes( line, "," );
var n = bits.length;
for ( var i=0; i < n; i++ )
{
var field = bits[i];
field = field.trim();
if ( "" != field )
{
var x = field.length - 1;
if ( '"' == field.charAt( x ) ) field = field.substring( 0, x );
if ( '"' == field.charAt( 0 ) ) field = field.substring( 1 );
field = field.trim();
}
array.push( field );
}
return array;
}
CSVFile.SplitWhileRespectingQuotes
=
function( line, delimiter )
{
var array = Array();
var out = true;
var s = 0;
var n = line.length;
for ( var i=0; i < n; i++ )
{
switch ( line.charAt( i ) )
{
case '"':
out = !out;
break;
case delimiter:
if ( out )
{
array.push( line.substring( s, i ) );
s = i + 1;
}
break;
}
}
if ( s < n )
{
array.push( line.substring( s, n ) );
}
return array;
}
CSVFile.LineReader
=
function( file_content, limit )
{
this.content = CSVFileLineReaderUnicodeStrip( file_content );
this.pos = 0;
this.lines = 0;
this.limit = limit;
}
CSVFile.LineReader.prototype.readLine
=
function()
{
var line = false;
var loop = true;
var in_quote = false;
if ( ++this.lines < this.limit )
{
if ( this.pos < this.content.length )
{
line = "";
while ( this.pos < this.content.length )
{
var ch = this.content[this.pos++];
if ( 127 < ch )
{
// ignore
}
else
if ( '"' == ch )
{
in_quote = !in_quote;
line += ch;
}
else
if ( '\n' == ch )
{
if ( in_quote ) line += ch;
else break;
}
else if ( '\r' == ch )
{
if ( in_quote ) line += ch;
else
{
if ( '\n' == this.content[this.pos] )
{
this.pos++;
}
break;
}
}
else
{
line += ch;
}
}
}
}
return line;
}
CSVFile.LineReader.prototype.unidecode
=
CSVFileLineReaderUnicodeStrip;
function CSVFileLineReaderUnicodeStrip( content )
{
content = CSVFile.LineReader.prototype.unirecode( content );
var str = "";
var n = content.length;
var i = 0;
while ( i < n )
{
var ch = content.charCodeAt(i);
if ( (ch == (0xFC | ch)) && (i+5 < n) ) // 6 byte unicode
{
i += 6;
}
else
if ( (ch == (0xF8 | ch)) && (i+4 < n) ) // 5 byte unicode
{
i += 5;
}
else
if ( (ch == (0xF0 | ch)) && (i+3 < n) ) // 4 byte unicode
{
i += 4;
}
else
if ( (ch == (0xE0 | ch)) && (i+2 < n) ) // 3 byte unicode
{
var tmp1 = utf8_to_unicode( content.substring( i, i + 3 ) );
var tmp2 = UTF8Codepoint( content.substring( i, i + 3 ) );
var ent = CodepointToEntity( tmp2 );
str += ent;
i += 3;
}
else
if ( (ch == (0xC0 | ch)) && (i+1 < n) ) // 2 byte unicode
{
i += 2;
}
else
if ( (ch == (0xC0 | ch)) && (i+1 < n) ) // 2 byte unicode
{
i += 2;
}
else
if ( (ch == (0x80 | ch)) ) // extra byte
{
console.log( "Warning detected invalid unicode" );
i += 1;
}
else
{
str += content[i]; // ascii character
i++;
}
}
return str;
}
CSVFile.LineReader.prototype.unirecode
=
CSVFileLineReaderUnicodeRecode;
/*
* Based on:
* https://stackoverflow.com/questions/17267329/converting-unicode-character-to-string-format
*/
function CSVFileLineReaderUnicodeRecode( content )
{
return content.replace( /\\u[\dA-F]{3}/gi, Unirecode );
}
function Unirecode( match )
{
return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16));
}
function MyUnicode2HTML( content, start, end )
{
var entity = "";
for ( var i = start; i < end; i++ )
{
var char_code = content.charCodeAt( i );
var hex = char_code.toString( 16 );
entity += hex;
}
entity += ";";
return entity;
}
function utf8_to_unicode( str )
{
var unicode = new Array();
var values = new Array();
var looking_for = 0;
var n = str.length;
for ( var i=0; i < n; i++ )
{
var val = str.charCodeAt( i );
if ( val < 128 )
{
unicode.push( val );
}
else
{
if ( values.length == 0 )
{
looking_for = (val < 224) ? 2 : 3;
}
values.push( val );
if ( values.length == looking_for )
{
var number = 0;
if ( looking_for == 3 )
{
number = ((values[0] % 16) * 4096)
+ ((values[1] % 64) * 64)
+ ((values[2] % 64) * 1);
}
else
{
number = ((values[0] % 32) * 64)
+ ((values[1] % 64) * 1);
}
unicode.push( number );
values = new Array();
looking_for = 1;
} // if
} // if
} // for
return unicode[0];
}
function UTF8Codepoint( utf8 )
{
var codepoint = 0;
var val = utf8.charCodeAt( 0 );
if ( val < 128 )
{
codepoint = val;
}
else
{
var values = new Array();
var n = utf8.length;
var looking_for = (val < 224) ? 2 : 3;
values.push( val );
for ( var i=1; i < n; i++ )
{
val = utf8.charCodeAt( i );
values.push( val );
}
if ( values.length == looking_for )
{
switch( looking_for )
{
case 3:
codepoint = ((values[0] % 16) * 4096)
+ ((values[1] % 64) * 64)
+ ((values[2] % 64) * 1);
break;
case 2:
codepoint = ((values[0] % 32) * 64)
+ ((values[1] % 64) * 1);
break;
}
}
}
return codepoint;
}
function CodepointToEntity( codepoint )
{
var entity = "" + codepoint.toString( 16 ) + ";";
return entity;
}
/*
* PureJavacript, Call.js
*
* Copyright 2014 - 2017, CrossAdaptive
*
* License LGPL v2
*/
function Call( endpoint, parameters, custom_handler )
{
parameters['wab_requesting_url'] = location.protocol + "//" + location.host + location.pathname;
if ( DataStorage.Local.HasItem( "sessionid" ) )
{
parameters['sid'] = DataStorage.Local.GetItem( "sessionid" );
}
if ( document.body.hasAttribute( "data-csrf" ) )
{
var csrf = document.body.getAttribute( "data-csrf" );
if ( "NONE" != csrf ) parameters['wab_csrf_token'] = csrf;
}
var search = endpoint.indexOf( "?" );
if ( -1 !== search )
{
var override_parameters = GetSearchValues.CreateDictionary( endpoint.substring( search ) );
for ( index in override_parameters )
{
parameters[index] = override_parameters[index];
}
}
var command = Call.EncodeToString( parameters );
var handler = (custom_handler) ? custom_handler : Call.DoNothing;
if ( "http" != endpoint.substr( 0, 4 ) )
{
switch ( endpoint.substr( 0, 3 ) )
{
case "/ap":
case "/au":
endpoint = Resolve( "api" ) + endpoint;
break;
case "/fn":
endpoint = Resolve( "fn" ) + endpoint;
break;
}
}
if ( 'async' in parameters && ("true" === parameters['async']) )
{
Call.Post( endpoint, command, null, 0, 0 );
handler( null );
}
else
{
Call.Post( endpoint, command, handler, 0, 0 );
}
}
Call.Post
=
function ( endpoint, command, handler, timeout, timeouts )
{
var httpRequest = Call.CreateXMLHttpRequest( "POST", endpoint, command, handler, timeout, timeouts );
httpRequest.send( command );
}
Call.Get
=
function ( endpoint, command, handler, timeout, timeouts )
{
var httpRequest = Call.CreateXMLHttpRequest( "GET", endpoint, command, handler, timeout, timeouts );
httpRequest.send( command );
}
Call.CreateXMLHttpRequest
=
function( method, endpoint, command, handler, timeout, timeouts )
{
var httpRequest = new XMLHttpRequest();
httpRequest.open( method, endpoint, true );
httpRequest.timeout = timeout;
httpRequest.timeouts = timeouts;
httpRequest.myEndpoint = endpoint;
httpRequest.myCommand = command;
httpRequest.myResponseHandler = handler;
httpRequest.withCredentials = ("GET" != method) ? true : false;
httpRequest.onreadystatechange
=
function()
{
Call.OnReadyStateChange( httpRequest, endpoint, handler );
}
httpRequest.ontimeout
=
function()
{
alert( "Giving up! Connection to the API server has timed out. Try again later." );
}
httpRequest.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
return httpRequest;
}
Call.OnReadyStateChange
=
function( self, endpoint, handler )
{
var status = self.status;
switch ( self.readyState )
{
case 0:
case 1:
case 2:
case 3:
break;
case 4:
switch ( self.status )
{
case 200:
console.log( "Called: " + endpoint );
if ( handler ) handler( self.responseText );
break;
case 404:
console.log( "Invalid API endpoint: " + endpoint );
break;
case 501:
console.log( "Required SQL Stored Procedure Not Implemented" );
break;
case 503:
console.log( "Sorry, the API server is currently unavailable. Please try again later. (503)" );
break;
case 0:
console.log( "The network timed out... (0)" );
break;
default:
console.log( "Got status: " + status );
}
break;
default:
console.log( "Unexpected httpRequest ready state: " + self.readyState );
}
}
Call.EncodeToString
=
function( parameters )
{
var string = "";
var sep = "";
for ( member in parameters )
{
if ( "" != member )
{
string += sep;
string += encodeURIComponent( member );
string += "=";
string += encodeURIComponent( parameters[member] );
sep = "&";
}
}
return string;
}
Call.DoNothing
=
function ()
{}
/*
* PureJavacript, Class.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Class = {}
Class.AddClass = AddClass;
Class.RemoveClass = RemoveClass;
function AddClass( e, className )
{
if ( ! Class.Contains( e, className ) )
{
if ( "" == e.className )
{
e.className = className;
}
else
{
e.className += " " + className;
}
}
}
function RemoveClass( e, className )
{
if ( Class.Contains( e, className ) )
{
e.className = Class.Remove( e.className, className );
}
}
Class.Remove
=
function( hay, needle )
{
var ret = hay.replace( needle, "" ).trim();
while ( -1 != ret.indexOf( " " ) )
{
ret = ret.replace( " ", " " );
}
return ret;
}
Class.Contains
=
function( e, className )
{
//
// AddClass.Contains( { className="cls active" }, "active' );
//
// var st = 10 - 6;
//
// 0123456789
// cls active
// 01234
var contains = false;
if ( e && e.className && className )
{
var st = (e.className.length - className.length) - 1;
if ( className == e.className )
{
contains = true;
}
else
if ( 0 <= st )
{
if ( -1 != e.className.indexOf( " " + className + " " ) )
{
contains = true;
}
else
if ( 0 == e.className.indexOf( className + " " ) )
{
contains = true;
}
else
if ( st == e.className.indexOf( " " + className ) )
{
contains = true;
}
}
}
return contains;
}
/*
* PureJavacript, Convert.js
*
* Copyright 2022, CrossAdaptive
*
* License LGPL v2
*/
Convert = {}
Convert.ResponseTo = ConvertResponseTo;
function ConvertResponseTo( type, response ) // return [byte]
{
var ret = [];
switch ( type )
{
case "application/json":
ret.push( JSON.stringify( response ) );
break;
case "text/csv":
ret.push( ConvertResponseTo.ToCSV( response.results ) );
break;
}
return ret;
}
ConvertResponseTo.ToCSV
=
function( results )
{
var csv = "";
var n = results.length;
var first = results[0];
var order = [];
// Write the headers to csv
for ( const [key, value] of Object.entries(first) )
{
csv += '"' + HTMLEntities.Decode( key ) + '"' + ",";
order.push( key );
}
csv += '\n';
// Write each tuple as csv rows
for ( var i=0; i < n; i++ )
{
var row = results[i];
for ( key in order )
{
value = row[order[key]];
if ( value )
{
csv += '"' + HTMLEntities.Decode( value ).replace( /"/g, '""' ) + '"' + ",";
}
else
{
csv += '"' + value + '"' + ",";
}
}
csv += '\n';
}
return csv;
}
/*
* PureJavacript, Cookie.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Cookie = {}
Cookie.Get = GetCookie
Cookie.Set = SetCookie
Cookie.Unset = UnsetCookie
function GetCookie( search )
{
var key = "";
var val = "";
if ( "" != search )
{
var bits = document.cookie.split( ";" );
var n = bits.length;
for ( var i=0; i < n; i++ )
{
var keyval = bits[i].split( "=" );
if ( (2 == keyval.length) && (keyval[0].trim() == search) )
{
val = keyval[1].trim();
break;
}
}
}
return val;
}
function SetCookie( path, cname, cvalue, exdays )
{
var p = ("" != path) ? path : "/";
var d = new Date(); d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = (0 != exdays) ? "expires="+d.toUTCString() + ";" : "";
var cookie = cname + "=" + cvalue + "; " + expires + " " + "path=" + p + ";secure;SameSite=strict";
document.cookie = cookie;
}
function UnsetCookie( name )
{
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}
function SetIDTypeCookie( idtype )
{
SetCookie( "/", "idtype", idtype, 1 );
}
function SetSessionIDTypeCookie( sid )
{
SetCookie( "/", "sessionid", sid, 1 );
}
function UnsetIDTypeCookie()
{
document.cookie = "idtype=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}
function UnsetSessionIDTypeCookie()
{
document.cookie = "sessionid=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
}
function SetSelectCookieFilter( event )
{
var select = event.target;
var path = location.pathname;
var name = select.name;
var value = select.options[select.selectedIndex].value;
SetCookie( path, name, value, 0 );
location.reload();
}
/*
* PureJavacript, DataStorage.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
DataStorage = {}
DataStorage.Local = {}
DataStorage.Session = {}
DataStorage.Exists
=
function()
{
return typeof( Storage ) !== "undefined";
}
DataStorage.Local.SetItem
=
function( key, value )
{
var success = false;
if ( typeof( Storage ) !== "undefined" )
{
if ( value && "" != value )
{
window.localStorage.setItem( key, value );
success = (window.localStorage.key == value);
}
}
return success;
}
DataStorage.Local.GetItem
=
function( key )
{
var value = null;
if ( DataStorage.Exists() )
{
value = window.localStorage.getItem( key );
}
return value;
}
DataStorage.Local.RemoveItem
=
function( key )
{
var success = false;
if ( typeof( Storage ) !== "undefined" )
{
window.localStorage.removeItem( key );
success = (window.localStorage.key == null);
}
return success;
}
DataStorage.Local.HasItem
=
function( key )
{
var success = false;
if ( typeof( Storage ) !== "undefined" )
{
success = window.localStorage.hasOwnProperty( key );
}
return success;
}
DataStorage.Session.SetItem
=
function( key, value )
{
var success = false;
if ( typeof( Storage ) !== "undefined" )
{
if ( value && "" != value )
{
window.sessionStorage.setItem( key, value );
success = (window.sessionStorage.key == value);
}
}
return success;
}
DataStorage.Session.GetItem
=
function( key )
{
var value = null;
if ( DataStorage.Exists() )
{
value = window.sessionStorage.getItem( key );
}
return value;
}
DataStorage.Session.RemoveItem
=
function( key )
{
var success = false;
if ( typeof( Storage ) !== "undefined" )
{
window.sessionStorage.removeItem( key );
success = (window.sessionStorage.key == null);
}
return success;
}
DataStorage.Session.HasItem
=
function( key )
{
var success = false;
if ( typeof( Storage ) !== "undefined" )
{
success = window.sessionStorage.hasOwnProperty( key );
}
return success;
}
/*
* PureJavacript, Datalist.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function Datalist( elements )
{
var n = elements.length;
for ( var i=0;i < n; i++ )
{
var e = elements[i];
if ( Class.Contains( e, "datalist" ) ) Datalist.Setup( e );
e.addEventListener( "keydown", Datalist.KeyHandler );
}
}
Datalist.Setup
=
function( datalist )
{
//datalist.autocomplete = "off";
if ( datalist.hasAttribute( "data-kind" ) )
{
var kind = datalist.getAttribute( "data-kind" );
var parameters = GetSearchValues();
parameters.kinds = kind;
Call( "/api/multiselect/", parameters, function( responseText ) { Datalist.SetupListItems( datalist, responseText ); } );
}
else
{
Datalist.SetupFunctions( datalist );
}
datalist.handler
=
function( event )
{
// Empty default handler.
}
}
Datalist.SetupListItems
=
function( datalist, responseText )
{
var json = JSON.parse( responseText );
var kind = datalist.getAttribute( "data-kind" );
if ( "" != kind )
{
datalist.setAttribute( "data-kind", "" );
var id = datalist.getAttribute( "id" );
var ul = document.createElement( "UL" );
ul.className = "datalist_list";
ul.setAttribute( "id", id + "-div" );
ul.style.display = "none";
datalist.parentNode.insertBefore( ul, datalist.nextSibling );
datalist.sublist = ul;
//datalist.cascade = onchange;
datalist.onchange = null;
if ( "OK" == json.status )
{
var n = json.results.length;
for ( var i=0; i < n; i++ )
{
var tuple = json.results[i];
if ( tuple.name == kind )
{
var m = tuple.tuples.length;
/* Uncomment for a list of options that the search term is a prefix of.
for ( var j=0; j < m; j++ )
{
var li = document.createElement( "LI" );
li.innerHTML = tuple.tuples[j].text;
li.dataListItemType = "prefixed";
ul.appendChild( li );
}
*/
for ( var j=0; j < m; j++ )
{
var li = document.createElement( "LI" );
li.innerHTML = tuple.tuples[j].text;
li.dataListItemType = "contains";
ul.appendChild( li );
}
break;
}
}
}
Datalist.SetupFunctions( datalist, ul );
}
}
Datalist.SetupFunctions
=
function( datalist, ul )
{
var list_items = datalist.sublist.getElementsByTagName( "LI" );
var n = list_items.length;
for ( var i=0; i < n; i++ )
{
var li = list_items[i];
li.onmouseover = Datalist.OnMouseOver;
li.onmouseout = Datalist.OnMouseOut;
li.onclick = Datalist.OnClick;
}
datalist.oninput = function() { Datalist.OnInput ( event, datalist ); };
datalist.onfocusout = function() { Datalist.OnFocusOut( event, datalist ); };
ul.onfocusout = function() { Datalist.OnFocusOut( event, datalist ); };
}
Datalist.OutsideClick
=
function( event )
{
console.log( event );
Datalist.HideDatalists( document.getElementsByTagName( "UL" ) );
}
Datalist.OnInput
=
function( event, datalist )
{
var div = datalist.sublist;
if ( ! div.ignoreFocus )
{
div.style.display = "block";
document.addEventListener( "click", Datalist.OutsideClick );
var filter = event.target.value;
var list_items = div.getElementsByTagName( "LI" );
var n = list_items.length;
for ( var i=0; i < n; i++ )
{
var li = list_items[i];
var lcl = li.innerHTML.toLowerCase();
var lcf = filter.toLowerCase();
switch ( li.dataListItemType )
{
case "prefixed":
// Case insensitive starts With
if ( 0 != lcl.indexOf( lcf ) )
{
li.style.display = "none";
}
else
{
li.style.display = "block";
}
break;
case "contains":
// Case insensitive matching
if ( -1 == lcl.indexOf( lcf ) )
{
li.style.display = "none";
}
else
{
li.style.display = "block";
}
break;
}
}
}
else
{
div.ignoreFocus = false;
}
}
Datalist.OnMouse
=
function( event, selected )
{
var datalist_list = event.target.parentNode;
var list_items = datalist_list.getElementsByTagName( "LI" );
var n = list_items.length;
for ( var i=0; i < n; i++ )
{
var li = list_items[i];
RemoveClass( li, "selected" );
}
if ( selected ) AddClass( event.target, "selected" );
}
Datalist.OnMouseOver = function( event ) { Datalist.OnMouse( event, true ); }
Datalist.OnMouseOut = function( event ) { Datalist.OnMouse( event, false ); }
Datalist.OnClick
=
function( event )
{
var li = event.target;
var datalist_list = li.parentNode;
var datalist = datalist_list.previousSibling;
if ( datalist )
{
datalist.value = li.innerHTML.trim().replace( "&", "&" );
datalist.setCustomValidity( "" );
datalist_list.style.display = "none";
datalist_list.ignoreFocus = true;
if ( datalist.form.hasAttribute( "data-change-url" ) )
{
var evt = new Object();
evt.target = datalist;
Save( evt );
}
else
{
datalist.handler( datalist );
}
}
document.removeEventListener( "click", Datalist.OutsideClick );
event.stopPropagation();
}
Datalist.OnFocusOut
=
function( event, datalist )
{
var list_items = datalist.sublist.getElementsByTagName( "LI" );
var hide = true;
var n = list_items.length;
for ( var i=0; i < n; i++ )
{
var li = list_items[i];
if ( Class.Contains( li, "selected" ) )
{
hide = false;
break;
}
}
if ( hide ) Datalist.HideDatalists( document.getElementsByTagName( "UL" ) );
}
Datalist.KeyHandler
=
function( evt )
{
evt = evt || window.event;
var isTab = ( 9 == evt.keyCode);
var isEnter = (13 == evt.keyCode);
var isEscape = (27 == evt.keyCode);
var isUp = (38 == evt.keyCode);
var isDown = (40 == evt.keyCode);
if ( isTab )
{
Datalist.HideDatalists( document.getElementsByTagName( "UL" ) );
}
else
if ( isEnter )
{
Datalist.ClickCurrentSelection();
evt.preventDefault();
}
else
if ( isEscape )
{
Datalist.HideDatalists( document.getElementsByTagName( "UL" ) );
}
else
if ( isUp )
{
Datalist.MoveCurrentSelection( -1 );
}
else
if ( isDown )
{
Datalist.MoveCurrentSelection( 1 );
}
}
Datalist.HideDatalists
=
function( elements )
{
var n = elements.length;
for ( var i=0; i < n; i++ )
{
var e = elements[i];
if ( Class.Contains( e, "datalist_list" ) )
{
e.style.display = "none";
e.scrollTop = 0;
Datalist.UnselectItems( e );
}
}
document.removeEventListener( "click", Datalist.OutsideClick );
}
Datalist.UnselectItems
=
function( datalist_list )
{
var elements = datalist_list.getElementsByTagName( "LI" );
var n = elements.length;
for ( var i=0; i < n; i++ )
{
var e = elements[i];
RemoveClass( e, "selected" );
}
}
Datalist.MoveCurrentSelection
=
function( delta )
{
var datalist = Datalist.FindActiveDatalist();
var elements = datalist.getElementsByTagName( "LI" );
var n = elements.length;
var i = -1;
var p = null;
var s = null;
for ( i=0; i < n; i++ )
{
var e = elements[i];
if ( Class.Contains( e, "selected" ) )
{
p = e;
break;
}
}
if ( (-1 == delta) && (i != n) )
{
for ( var j=i-1; j >= 0; j-- )
{
var e = elements[j];
if ( null !== e.offsetParent )
{
s = e;
AddClass ( e, "selected" );
RemoveClass( p, "selected" );
break;
}
}
}
else
if ( 1 == delta )
{
if ( i == n ) i = -1;
for ( var j=i+1; j < n; j++ )
{
var e = elements[j];
if ( null !== e.offsetParent )
{
s = e;
AddClass ( e, "selected" );
RemoveClass( p, "selected" );
break;
}
}
}
if ( s )
{
console.log( "offsetTop: " + s.offsetTop );
if ( (1 == delta) && (s.offsetTop > 439) )
{
s.offsetParent.scrollTop += s.scrollHeight + 1;
}
}
}
Datalist.ClickCurrentSelection
=
function()
{
var datalist = Datalist.FindActiveDatalist();
if ( datalist )
{
var elements = datalist.getElementsByTagName( "LI" );
var n = elements.length;
var i = -1;
for ( i=0; i < n; i++ )
{
var e = elements[i];
if ( Class.Contains( e, "selected" ) )
{
e.click();
break;
}
}
}
}
Datalist.FindActiveDatalist
=
function()
{
var ret = null;
var elements = document.getElementsByTagName( "UL" );
var n = elements.length;
for ( var i=0; i < n; i++ )
{
var e = elements[i];
if ( Class.Contains( e, "datalist_list" ) && (null != e.offsetParent) )
{
ret = e;
break;
}
}
return ret;
}
/*
* PureJavacript, Datetime.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Datetime = {}
Datetime.IsValid = DateIsValid
Datetime.ToYMD = YMDDate
function DateIsValid( $datetime )
{
var is_date = false;
switch ( $datetime )
{
case null:
case "NULL":
case "null":
case "":
case "0":
case "0000-00-00":
case "0000-00-00 00:00:00":
break;
default:
is_date = true;
}
return is_date;
}
function YMDDate( date_string )
{
var ymd_date = null;
var ymd = new Array();
date_string = date_string.replace( /%2F/g, "/" );
if ( -1 !== date_string.indexOf( "/" ) )
{
var parts = date_string.split( "/" );
switch ( parts.length )
{
case 3:
ymd[0] = (2 == parts[2].length) ? "20" + parts[2] : parts[2];
ymd[1] = parts[1];
ymd[2] = parts[0];
break;
case 2:
ymd[0] = new Date().getFullYear();
ymd[1] = parts[1];
ymd[2] = parts[0];
}
}
else
if ( -1 !== date_string.indexOf( "-" ) )
{
ymd = date_string.split( "-" );
}
if ( 3 == ymd.length )
{
if ( (3 == ymd.length) && (4 == ymd[0].length) && (2 == ymd[1].length) && (2 == ymd[2].length) )
{
var year = parseInt( ymd[0] );
var month = parseInt( ymd[1] );
var day = parseInt( ymd[2] );
if ( YMDDate.IsMonth( month ) && YMDDate.IsDayOfMonth( day, month ) )
{
ymd_date = ymd.join( '-' );
}
}
}
return ymd_date;
}
YMDDate.IsMonth
=
function( month )
{
return (1 <= month) && (month <= 12);
}
YMDDate.IsDayOfMonth
=
function( day, month )
{
switch ( month )
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return (1 <= day) && (day <= 31);
case 4:
case 6:
case 9:
case 11:
return (1 <= day) && (day <= 30);
case 2:
return (1 <= day) && (day <= 29);
default:
return false;
}
}
/*
* PureJavacript, Element.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Elements = {}
Elements.Toggle = Toggle
Elements.Show = Toggle.Show
Elements.Hide = Toggle.Hide
Elements.ShowHide = ShowHide;
Elements.HideShow = null;
Elements.SetFnSetup = null;
Elements.SetFnSubmit = null;
Elements.SetFnHandler = null;
function Toggle( id )
{
var ret = null;
var e = document.getElementById( id );
if ( e )
{
if ( null === e.offsetParent )
{
ret = Toggle.Show( e );
}
else
{
ret = Toggle.Hide( e );
}
}
return ret;
}
Toggle.Show
=
function ( e, display )
{
if ( ! display )
{
switch ( e.tagName )
{
case "TABLE":
e.style.display = "table";
break;
case "TR":
e.style.display = "table-row-group";
break;
case "TH":
e.style.display = "table-cell";
break;
case "TD":
e.style.display = "table-cell";
break;
default:
e.style.display = "block";
}
}
else
{
e.style.display = display;
}
e.style.visibility = "visible";
return true;
}
Toggle.Hide
=
function ( e )
{
e.style.display = "none";
e.style.visibility = "hidden";
return false;
}
Elements.HideShow
=
function ( cls, id, display )
{
var elements = document.getElementsByClassName( cls );
var e = document.getElementById( id );
var n = elements.length;
for ( var i=0; i < n; i++ )
{
Toggle.Hide( elements[i] );
Class.RemoveClass( elements[i], "active" );
}
if ( e )
{
Toggle.Show( e, display );
Class.AddClass( e, "active" );
}
return false;
}
function ShowHide( id, show_id, hide_id )
{
var self = document.getElementById( id );
var show_e = document.getElementById( show_id );
var hide_e = document.getElementById( hide_id );
if ( show_e && hide_e )
{
Toggle.Hide( hide_e );
Toggle.Show( show_e );
}
if ( self )
{
ShowHide.MakePeersInactive( self );
ShowHide.MakeActive( self );
}
}
ShowHide.MakePeersInactive
=
function( e )
{
if ( e.parentNode && e.parentNode.parentNode )
{
var children = e.parentNode.parentNode.getElementsByTagName( "A" );
var n = children.length;
for ( var i=0; i < n; i++ )
{
var child = children[i];
ShowHide.MakeInactive( child );
}
}
}
ShowHide.MakeActive
=
function( e )
{
Class.AddClass( e, "active" );
}
ShowHide.MakeInactive
=
function( e )
{
Class.RemoveClass( e, "active" );
}
Elements.SetFnSetup
=
function( id, fn )
{
var e = document.getElementById( id );
if ( e )
{
e.setup = fn;
}
}
Elements.SetFnSubmit
=
function( id, fn )
{
var e = document.getElementById( id );
if ( e )
{
e.addEventListener( 'submit', fn );
}
}
Elements.SetFnHandler
=
function( id, fn )
{
var e = document.getElementById( id );
if ( e )
{
e.handler = fn;
}
}
/*
* PureJavacript, Enum.js
*
* Copyright 2017, CrossAdaptive
*/
function Enum( values )
{
var e = {}
var n = values.length;
for ( var i=0; i < n; i++ )
{
var name = values[i]
e[name] = name;
}
return e;
}
/*
* PureJavacript, Filter.js
*
* Copyright 2017, CrossAdaptive
*/
//Filter = {}
function Filter( id, tag_name, pattern )
{
var element = document.getElementById( id );
if ( !element )
{
alert( "Filter: could not find target element: " + id );
}
else
{
var terms = pattern.split( ' ' );
var elements = element.getElementsByTagName( tag_name );
var n = elements.length;
for ( var i=0; i < n; i++ )
{
var e = elements[i];
var title = e.getAttribute( "title" );
var html = e.innerHTML;
Toggle.Show( e );
for ( index in terms )
{
var term = terms[index];
if ( ! Filter.ElementContainsText( e, term ) )
{
Toggle.Hide( e )
break;
}
}
}
}
}
Filter.ElementContainsText
=
function( e, t )
{
var contains = false;
if ( e.children && (0 < e.children.length) )
{
for ( index in e.children )
{
var child = e.children[index];
if ( (contains = Filter.ElementContainsText( child, t )) )
{
break;
}
}
}
else
if ( Filter.StringContainsText( e.title, t ) )
{
contains = true;
}
else
if ( Filter.StringContainsText( e.innerHTML, t ) )
{
contains = true;
}
return contains;
}
Filter.StringContainsText
=
function( s, t )
{
var contains = false;
if ( s )
{
if ( "" == t )
{
contains = true;
}
else
{
var lc_s = s.toLowerCase();
var lc_t = t.toLowerCase();
contains = (-1 != lc_s.indexOf( lc_t ));
}
}
return contains;
}
Filter.TableBody
=
function( tbody_id, form )
{
// 1) Retrieve values frorm any selects/inputs in forms.
var values = Filter.TableBody.RequiredValues( form ); // Returns text array.
// 2) Iterate through tables rows and show/hide matching/unmatching rows.
var tbody = document.getElementById( tbody_id );
var rows = tbody.getElementsByTagName( "TR" );
var n = rows.length;
for ( var i=0; i < n; i++ )
{
var tr = rows[i];
if ( -1 == tr.className.indexOf( "hidden" ) )
{
tr.style.display = Filter.TableBody.ContainsAll( tr, values ) ? "table-row" : "none";
}
}
}
Filter.TableBody.RequiredValues
=
function( form )
{
var values = new Array();
var n = form.elements.length;
for ( var i = 0; i < n; i++ )
{
var input = form.elements[i];
switch ( input.tagName )
{
case "SELECT":
var option = input.options[input.selectedIndex];
var text = option.text.toLowerCase();
if ( option.value && ("" != text) )
{
values.push( text );
}
break;
case "INPUT":
if ( "" != input.value )
{
var bits = input.value.split( " " );
for ( index in bits )
{
values.push( bits[index].toLowerCase() );
}
}
break;
}
}
return values;
}
Filter.TableBody.ContainsAll
=
function( tr, values )
{
// Returns true only if tr contains all values in passed array.
var contains = true;
var n = values.length;
for ( var i=0; i < n; i++ )
{
if (-1 === tr.innerHTML.toLowerCase().indexOf( values[i] ))
{
contains = false;
break;
}
}
return contains;
}
/*
* PureJavacript, Forms.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Forms = {}
Forms.Changed = purejavascript_Forms_Changed
Forms.GetValues = GetFormValues
Forms.InsertResponseValues = InsertResponseValues
Forms.InsertValues = InsertFormValues
Forms.Save = Save
Forms.SelectAll = SelectAll
Forms.Submit = Submit
Forms.SubmitTableValues = SubmitTableValues
Forms.Validate = Validate
Forms.ValidateForm = ValidateForm
Forms.Validate.Submit = Validate.Submit
function purejavascript_Forms_Changed( event )
{
var input = event.target;
var form = input.form;
var submit = form.querySelector( "BUTTON[type='submit']" );
if ( submit )
{
submit.disabled = false;
}
}
Forms.DisableAll
=
function( form )
{
var len = form.elements.length;
for ( var i=0; i < len; i++ )
{
form.elements[i].disabled = true;
}
}
function GetFormValues( form )
{
var object = new Object;
if ( form && form.elements )
{
var n = form.elements.length;
for ( var i=0; i < n; i++ )
{
var e = form.elements[i];
var key = e.name;
var value = e.value;
if ( e.hasAttribute( "data-date-format" ) )
{
value = GetFormValues.ConvertDateToMySQLDateFormatFrom( value, e.getAttribute( "data-date-format" ) );
}
switch ( e.type )
{
case "checkbox":
if ( ! e.disabled && e.checked )
{
value = e.checked ? value : "";
}
else
{
value = "";
}
break;
case "radio":
var v = value;
if ( ! e.checked )
{
key = null;
value = null;
object[v] = 0;
}
else
{
object[v] = 1;
}
break;
case "hidden":
if ( "" != e.hasAttribute( "data-table" ) )
{
value = GetFormValues.ConvertTableToJSON( e.getAttribute( "data-table" ) );
}
break;
}
switch ( e.tagName )
{
case "BUTTON":
value = e.innerHTML.trim();
break;
}
if ( key && value )
{
if ( GetFormValues.IsTimeComponent( key ) )
{
key = GetFormValues.GetTimePrefix( key );
value = GetFormValues.ExtractTime( form, key );
}
if ( object[key] )
{
object[key] += ("," + value);
}
else
{
object[key] = value;
}
}
}
}
else
{
console.log( "GetFormValues: null form passed!" );
}
return object;
}
function InsertResponseValues( formID, keyName, responseText )
{
var status = false;
if ( ! responseText )
{
alert( "Error, no content returned." );
}
else
{
var parameters = GetSearchValues();
if ( (null == keyName) || ("" != parameters[keyName]) )
{
var json = JSON.parse( responseText );
var form = document.getElementById( formID );
form.autocomplete = "off";
if ( json && form && ("OK" == json.status) && (1 == json.results.length) )
{
var tuple = json.results[0];
form.disabled = ("1" === tuple["form_disabled"]);
InsertFormValues( form, tuple );
status = true;
var submit = form.querySelector( "BUTTON[type='submit']" );
if ( submit )
{
submit.disabled = true;
}
for ( index in form.elements )
{
var input = form.elements[index];
if ( input.addEventListener )
{
switch ( input.tagName )
{
case "SELECT":
input.addEventListener( "change", Forms.Changed );
break;
case "INPUT":
switch ( input.type )
{
case "checkbox":
case "radio":
case "file":
input.addEventListener( "change", Forms.Changed );
break;
default:
input.addEventListener( "change", Forms.Changed );
input.addEventListener( "keyup", Forms.Changed );
}
if( "checkbox" == input.type )
{
if ( input.setup )
{
input.setup( { "target": input } );
}
}
break;
case "TEXTAREA":
input.addEventListener( "keyup", Forms.Changed );
break;
default:
break;
}
}
if ( ! input.disabled ) input.disabled = form.disabled;
if ( input.className )
{
if ( -1 !== input.className.indexOf( "do_not_disable" ) )
{
input.disabled = false;
}
}
}
var buttons = form.querySelectorAll( "BUTTON.validate" );
var n = buttons.length;
if ( 0 < n )
{
if ( Forms.ValidateForm( form ) )
{
for ( var i=0; i < n; i++ )
{
buttons[i].disabled = false;
}
}
else
{
for ( var i=0; i < n; i++ )
{
buttons[i].disabled = true;
}
}
}
}
}
}
return status;
}
function InsertFormValues( form, object )
{
for ( var member in object )
{
if ( form[member] )
{
var input = form[member]; // May return one item or node list.
var value = DecodeHTMLEntities( object[member] );
if ( ("SELECT" != input.tagName) && input.length )
{
var n = input.length;
for ( var i=0; i < n; i++ )
{
if ( "radio" == input[i].type )
{
if ( value == input[i].value )
{
input[i].checked = true;
}
}
}
}
else
if ( input && value )
{
if ( "INPUT" == input.tagName )
{
var ph = input.placeholder;
if ( "checkbox" == input.type )
{
input.checked = (("0" == value) || ("" == value)) ? false : true;
}
else
if ( "radio" == input.type )
{
if ( value == input.value )
{
input.checked = true;
}
}
else
{
input.value = value;
if ( input.hasAttribute( "data-cascade" ) )
{
Selects.DoCascade( input );
}
}
input.placeholder = "";
input.placeholder = ph;
}
else
if ( "SELECT" == input.tagName )
{
if ( input.setValue )
{
input.setValue( value );
}
else
{
input.value = value;
}
input.setAttribute( "data-value", value );
}
else
if ( "TEXTAREA" == input.tagName )
{
value = value.replace( /
/g, "\n" );
input.innerHTML = value;
if ( input.onchange )
{
var evt = new Object();
evt.target = input;
input.onchange( evt );
}
}
}
}
}
for ( var index in form.elements )
{
var input = form.elements[index];
if ( input.getAttribute )
{
if ( "true" == input.getAttribute( "data-required" ) )
{
switch( input.type )
{
case "radio":
if ( input.checked )
{
input.className += " desired";
}
break;
default:
if ( "" == input.value.trim() )
{
input.className += " desired";
}
}
}
if ( "true" == input.getAttribute( "data-confirmation" ) )
{
if ( "No" == input.value.trim() )
{
var target_id = input.getAttribute( "data-target" );
if ( target_id )
{
var target = document.getElementById( target_id );
if ( target )
{
target.className += " desired";
}
}
}
}
}
}
}
function Save( event, handler )
{
var element = event.target;
var form = event.target.form;
var parameters = GetFormValues( form );
var url = form.getAttribute( "data-change-url" );
if ( ! parameters.hasOwnProperty( "USER" ) )
{
// parameters.USER = Session.USER;
}
switch ( element.type )
{
case 'checkbox':
parameters.name = element.name;
parameters.value = element.checked ? "1" : "0";
break;
case 'select-one':
case 'text':
default:
parameters.name = element.name;
parameters.value = element.value;
}
if ( element.hasAttribute( "id" ) )
{
parameters.target_id = element.getAttribute( "id" );
}
Call( Resolve() + url, parameters, handler ? handler : Save.Handler );
}
Save.Handler
=
function( responseText )
{
console.log( responseText );
}
function SelectAll( event, form_id )
{
var input = event.target;
var form = document.getElementById( form_id );
if ( form )
{
var inputs = form.querySelectorAll( "INPUT[type=checkbox]" );
var n = inputs.length;
for ( var i=0; i < n; i++ )
{
inputs[i].checked = input.checked;
}
}
}
function Submit( event, custom_handler )
{
var form = event.target;
var submits = form.querySelectorAll( "BUTTON[type=submit]" );
var n = submits.length;
//
// Too many unintended consequences.
//
//for ( var i=0; i < n; i++ )
//{
// submits[i].disabled = true;
//}
var handler = custom_handler ? custom_handler : Submit.SubmitDefaultHandler;
var parameters = GetFormValues( form );
var submit = form.elements['submit'];
if ( submit && submit.value && ("delete" == submit.value.toLowerCase()) )
{
if ( form && form.hasAttribute( "data-delete-url" ) )
{
var url = form.getAttribute( "data-delete-url" );
var handler = form.handler ? form.handler : handler;
Call( url, parameters, handler );
}
}
else
if ( form && form.hasAttribute( "data-url" ) )
{
var url = form.getAttribute( "data-url" );
var handler = form.handler ? form.handler : handler;
Call( url, parameters, handler );
}
else
if ( form.hasAttribute( "data-submit-url" ) )
{
var url = form.getAttribute( "data-submit-url" );
var handler = form.handler ? form.handler : handler;
Call( url, parameters, handler );
}
return false;
}
Submit.SubmitDefaultHandler
=
function( responseText )
{
var json = JSON.parse( responseText );
if ( "OK" == json.status )
{
Locations.Up();
}
}
Submit.SubmitReloadHandler
=
function( responseText )
{
var json = JSON.parse( responseText );
if ( "OK" == json.status )
{
location.reload();
}
else
{
alert( "Error: " + json.error )
}
}
function SubmitTableValues( event, verify )
{
var form = event.target;
var target_id = form.getAttribute( "data-target" );
var table = document.getElementById( target_id );
var endpoint = table.getAttribute( "data-url" );
var parameters = Forms.GetValues( form );
var submit = form.querySelectorAll( "BUTTON" );
var n = submit.length;
for ( var i=0; i < n; i++ )
{
submit[i].disabled = true;
}
if ( ! verify )
{
verify
=
function( tr )
{
return true;
}
}
if ( table && table.rows && (1 < table.rows.length) )
{
var i = SubmitTableValues.NextVerifiedRow( table, verify, 0 );
if ( i )
{
SubmitTableValues.DoCall( endpoint, parameters, table, i, verify );
}
else
{
alert( "Finished submitting table values." );
}
}
else
{
Call( "/auth/session/", new Object(), SubmitTableValues.Finish );
}
return false;
}
SubmitTableValues.NextVerifiedRow
=
function( table, verify, i )
{
var j = false;
var progress_id = table.getAttribute( "data-progress" );
var progress = progress_id ? document.getElementById( progress_id ) : null;
var loop = true;
while ( table.rows[++i] )
{
if ( progress )
{
progress.style.width = (i / table.rows.length) * 100 + "%";
}
if ( verify( table.rows[i] ) )
{
j = i;
break;
}
}
if ( progress && ! table.rows[i] )
{
progress.style.width = "100%";
}
if ( progress && (i == table.rows.length) )
{
progress.style.background = "green";
}
return j;
}
SubmitTableValues.Handler
=
function( responseText, parameters, table, i, verify )
{
var endpoint = table.getAttribute( "data-url" );
var json = "";
try
{
json = JSON.parse( responseText );
}
catch ( err )
{
console.log( responseText );
}
SubmitTableValues.MarkupRow( json, table, i );
var i = SubmitTableValues.NextVerifiedRow( table, verify, i );
if ( false !== i )
{
SubmitTableValues.DoCall( endpoint, parameters, table, i, verify );
}
else
{
var progress_id = table.getAttribute( "data-progress" );
if ( progress_id )
{
var progress = document.getElementById( progress_id );
progress.style.width = "100%";
}
Call( "/auth/session/", new Object(), SubmitTableValues.Finish );
}
}
SubmitTableValues.DoCall
=
function( endpoint, parameters, table, i, verify )
{
var combined_parameters = SubmitTableValues.ConvertTRToParameters( parameters, table.rows[i] );
Call
(
endpoint,
combined_parameters,
function ( responseText )
{
var table_copy = table;
var i_copy = i;
var v_copy = verify;
SubmitTableValues.Handler( responseText, parameters, table_copy, i_copy, v_copy );
}
);
}
SubmitTableValues.MarkupRow
=
function( json, table, i )
{
if ( "OK" == json.status )
{
table.rows[i].classList.add( "import_ok" );
table.rows[i].style.background = "green";
table.rows[i].style.color = "white";
}
else
if ( "EXISTS" == json.error )
{
table.rows[i].classList.add( "import_exists" );
table.rows[i].style.background = "#888";
table.rows[i].style.color = "#ddd";
}
else
{
table.rows[i].classList.add( "import_error" );
table.rows[i].style.background = "red";
table.rows[i].style.color = "white";
}
}
SubmitTableValues.ConvertTRToParameters
=
function( parameters, tr )
{
var ret = SubmitTableValues.ConvertTRToParameters.Clone( parameters );
var n = tr.cells.length;
for ( var i=0; i < n; i++ )
{
if ( "TD" == tr.cells[i].tagName )
{
var key = tr.cells[i].getAttribute( "data-name" );
var val = tr.cells[i].innerHTML;
if ( key && val )
{
ret[key] = val;
}
}
}
return ret;
}
SubmitTableValues.ConvertTRToParameters.Clone
=
function( obj )
{
var ret = {};
for ( var name in obj )
{
var value = obj[name];
ret[name] = obj[name];
}
return ret;
}
SubmitTableValues.Finish
=
function( responseText )
{
alert( "Finished submitting table values." );
}
function Validate( event, handler )
{
var valid = true;
var form = event.target;
var n = form.elements.length;
var del = (form.elements['submit'] && ('delete' == form.elements['submit'].value));
if ( ! del )
{
valid = Forms.ValidateForm( form );
/*
form.checkValidity();
for ( var i=0; i < n; i++ )
{
var element = form.elements[i];
if ( element.hasAttribute( "required" ) )
{
var type = element.type;
var name = element.name;
var value = element.value;
var validated = element.validity.valid;
Validate.AddClass( element, "checked" );
if ( (false === validated) || (('hidden' == type) && (0 == value)) )
{
valid = false;
}
else
{
}
}
}
*/
}
if ( valid && handler )
{
handler( event );
}
else
{
alert( "Please complete the form before submitting." );
}
return false;
}
function ValidateForm( form )
{
var valid = true;
var n = form.elements.length;
form.checkValidity();
for ( var i=0; i < n; i++ )
{
var element = form.elements[i];
if ( element.hasAttribute( "required" ) )
{
var type = element.type;
var name = element.name;
var value = element.value.trim();
var validated = element.validity.valid;
Validate.AddClass( element, "checked" );
if ( "" == value )
{
valid = false;
}
else
if ( (false === validated) || (('hidden' == type) && (0 == value)) )
{
valid = false;
}
}
}
return valid;
}
Validate.Submit
=
function( event )
{
event.preventDefault();
Forms.Validate( event, Forms.Submit );
}
function WordLimit( elements )
{
var n = elements.length;
for ( var i=0; i < n; i++ )
{
var e = elements[i];
if ( ("TEXTAREA" == e.tagName) && e.hasAttribute( "data-limit" ) )
{
e.oninput = WordLimit.OnInput;
}
}
}
WordLimit.OnInput
=
function( event )
{
var textarea = event.target;
var limit = textarea.getAttribute( "data-limit" );
var target_id = textarea.getAttribute( "data-target" );
var target = target_id ? document.getElementById( target_id ) : null;
var last_char = WordLimit.LastChar ( textarea.value );
var words = WordLimit.CountWords( textarea.value );
var truncated = false;
if ( limit < words )
{
textarea.value = WordLimit.TruncateTextToWords( textarea.value, limit );
words = WordLimit.CountWords( textarea.value );
truncated = true;
}
if ( truncated )
{
switch ( last_char )
{
case " ":
case "\n":
alert( "Warning, your have reached the word limit!" );
}
}
if ( target ) target.innerHTML = (words) + " words";
}
WordLimit.CountWords
=
function( value )
{
return value.split( " " ).length;
}
WordLimit.TruncateTextToWords
=
function( value, limit )
{
var words = 0;
var i = -1;
while ( -1 != (i = WordLimit.NextWhitespace( value, i + 1 )) )
{
words++;
if ( limit < words ) break;
}
if ( -1 == i ) i = value.length;
return value.substring( 0, i );
}
WordLimit.LastChar
=
function( value )
{
return value.length ? value.substring( value.length - 1, value.length ) : null;
}
WordLimit.NextWhitespace
=
function( value, i )
{
var s = value.indexOf( " ", i );
var n = value.indexOf( "\n", i );
var r = -1;
if ( (-1 != s) && (-1 != n) )
{
r = Math.min( s, n );
}
else
if ( -1 != s )
{
r = s;
}
else
if ( -1 != n )
{
r = n;
}
return r;
}
GetFormValues.ConvertTableToJSON
=
function( table_id )
{
var tuples = new Array();
var table = document.getElementById( table_id );
if ( table )
{
var rows = table.getElementsByTagName( "TR" );
var n = rows.length;
for ( var i=0; i < n; i++ )
{
var tuple = new Object();
var row = rows[i];
var fields = row.getElementsByTagName( "TD" );
var m = fields.length;
for ( var j=0; j < m; j++ )
{
var field = fields[j];
if ( field.hasAttribute( "data-name" ) )
{
var key = field.getAttribute( "data-name" );
var value = field.innerHTML.trim();
tuple[key] = value;
}
}
tuples.push( tuple );
}
}
return JSON.stringify( tuples );
}
GetFormValues.IsTimeComponent
=
function( name )
{
return (-1 !== name.indexOf( "_hour" ));
}
GetFormValues.GetTimePrefix
=
function( name )
{
var index = name.indexOf( "_hour" );
return name.substring( 0, index );
}
GetFormValues.ExtractTime
=
function( form, key )
{
var ret = "";
var key_hour = key + "_hour";
var key_minutes = key + "_minutes";
var key_seconds = key + "_seconds";
ret += form.elements[key_hour] ? form.elements[key_hour ].value : "00";
ret += ":";
ret += form.elements[key_minutes] ? form.elements[key_minutes].value : "00";
ret += ":";
ret += form.elements[key_seconds] ? form.elements[key_seconds].value : "00";
return ret;
}
GetFormValues.ConvertDateToMySQLDateFormatFrom
=
function( date_value, date_format )
{
var converted = "0000-00-00";
var delimiter = (-1 != date_value.indexOf( "/" )) ? "/" : "-";
var bits = date_value.split( delimiter );
if ( 3 == bits.length )
{
var yy = "";
var mm = "";
var dd = "";
switch ( date_format )
{
case "DD-MM-YY":
case "DD/MM/YY":
case "DD-MM-YYYY":
case "DD/MM/YYYY":
dd = bits[0];
mm = bits[1];
yy = bits[2];
break;
case "MM-DD-YY":
case "MM/DD/YY":
case "MM-DD-YYYY":
case "MM/DD/YYYY":
mm = bits[0];
dd = bits[1];
yy = bits[2];
break;
case "YY-MM-DD":
case "YYYY-MM-DD":
default:
yy = bits[0];
mm = bits[1];
dd = bits[2];
}
var year = parseInt( yy )
if ( !isNaN( year ) && (year < 100) )
{
yy = (year < 50) ? 2000 + year : 1900 + year;
}
converted = "" + yy + "-" + GetFormValues.ZeroPad( mm ) + "-" + GetFormValues.ZeroPad( dd );
}
return converted;
}
GetFormValues.ZeroPad
=
function( value )
{
var val = parseInt( value );
if ( isNaN( val ) )
{
return "00";
}
else
{
return (val <= 9) ? "0" + val : "" + val;
}
}
Validate.HasClass
=
function ( element, cls )
{
var classes = element.className;
return (-1 != classes.indexOf( cls ));
}
Validate.AddClass
=
function ( element, cls )
{
if ( element && cls )
{
var classes = element.className;
if ( -1 == classes.indexOf( cls ) )
{
element.className += (" " + cls);
}
}
}
Validate.RemoveClass
=
function ( element, cls )
{
var classes = element.className;
var f = 0;
var n = cls.length;
if ( (-1 != classes.indexOf( " " + cls )) || (-1 != classes.indexOf( cls + " " )) || (-1 != classes.indexOf( cls )) )
{
var f = classes.indexOf( cls );
if ( (0 < f) && (' ' == classes[f - 1]) ) f--;
element.className = classes.substring( 0, f ) + classes.substring( f + n + 1 );
}
}
/*
* PureJavacript, Geocode.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function Geocode( latitude, longitude, handler )
{
var GOOGLE_URL = "https://maps.googleapis.com";
var parameters = new Object();
parameters.latlng = latitude + "," + longitude;
/*
* https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=API_KEY
*/
Call( GOOGLE_URL, "/maps/api/geocode/json/", parameters, handler );
}
/*
* PureJavacript, HTMLEntities.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
HTMLEntities = {}
HTMLEntities.Encode = HTMLEntitiesEncode
HTMLEntities.Decode = DecodeHTMLEntities
/*
* The following implementations were copied from the following opensource implementations:
*
* http://locutus.io/php/strings/htmlentities/
* http://locutus.io/php/strings/get_html_translation_table/index.html
*/
function HTMLEntitiesEncode( string, quoteStyle, charset, doubleEncode )
{
// discuss at: http://locutus.io/php/htmlentities/
// original by: Kevin van Zonneveld (http://kvz.io)
// revised by: Kevin van Zonneveld (http://kvz.io)
// revised by: Kevin van Zonneveld (http://kvz.io)
// improved by: nobbler
// improved by: Jack
// improved by: RafaĆ Kukawski (http://blog.kukawski.pl)
// improved by: Dj (http://locutus.io/php/htmlentities:425#comment_134018)
// bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// input by: Ratheous
// note 1: function is compatible with PHP 5.2 and older
// example 1: htmlentities('Kevin & van Zonneveld')
// returns 1: 'Kevin & van Zonneveld'
// example 2: htmlentities("foo'bar","ENT_QUOTES")
// returns 2: 'foo'bar'
var hashMap = HTMLEntitiesEncode.GetHTMLTranslationTable( 'HTML_ENTITIES', quoteStyle )
string = string === null ? '' : string + ''
if ( !hashMap )
{
return false
}
if ( quoteStyle && quoteStyle === 'ENT_QUOTES' )
{
hashMap["'"] = '''
}
doubleEncode = doubleEncode === null || !!doubleEncode
var regex = new RegExp('&(?:#\\d+|#x[\\da-f]+|[a-zA-Z][\\da-z]*);|[' + Object.keys(hashMap).join('').replace(/([()[\]{}\-.*+?^$|\/\\])/g, '\\$1') + ']','g')
return string.replace( regex,
function ( ent )
{
if ( ent.length > 1 )
{
return doubleEncode ? hashMap['&'] + ent.substr(1) : ent
}
return hashMap[ent]
}
)
}
function DecodeHTMLEntities( htmlEncodedString )
{
var ret = htmlEncodedString;
if ( "string" == typeof htmlEncodedString )
{
var bits = htmlEncodedString.split( '&' );
var n = bits.length;
if ( 1 < n )
{
for ( var i=0; i < n; i++ )
{
var s = bits[i].indexOf( ";" );
if ( -1 != s )
{
var bit = bits[i];
var bob = bit.substring( 0, s + 1 );
switch ( bob )
{
case "amp;":
bits[i] = "&" + bit.substring( s + 1, bit.length );
break;
case "quot;":
bits[i] = "\"" + bit.substring( s + 1, bit.length );
break;
case "rsquo;":
bits[i] = "\'" + bit.substring( s + 1, bit.length );
break;
case "apos;":
bits[i] = "\'" + bit.substring( s + 1, bit.length );
break;
case "lt;":
bits[i] = "<" + bit.substring( s + 1, bit.length );
break;
case "gt;":
bits[i] = ">" + bit.substring( s + 1, bit.length );
break;
default:
bits[i] = DecodeHTMLEntities.DecodeEntity( bob ) + bit.substring( s + 1, bit.length );
}
}
}
ret = bits.join( "" );
}
}
return ret;
}
HTMLEntitiesEncode.GetHTMLTranslationTable
=
function( table, quoteStyle )
{
// eslint-disable-line camelcase
// discuss at: http://locutus.io/php/get_html_translation_table/
// original by: Philip Peterson
// revised by: Kevin van Zonneveld (http://kvz.io)
// bugfixed by: noname
// bugfixed by: Alex
// bugfixed by: Marco
// bugfixed by: madipta
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: T.Wild
// improved by: KELAN
// improved by: Brett Zamir (http://brett-zamir.me)
// input by: Frank Forte
// input by: Ratheous
// note 1: It has been decided that we're not going to add global
// note 1: dependencies to Locutus, meaning the constants are not
// note 1: real constants, but strings instead. Integers are also supported if someone
// note 1: chooses to create the constants themselves.
// example 1: get_html_translation_table('HTML_SPECIALCHARS')
// returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'}
var entities = {}
var hashMap = {}
var decimal
var constMappingTable = {}
var constMappingQuoteStyle = {}
var useTable = {}
var useQuoteStyle = {}
// Translate arguments
constMappingTable[0] = 'HTML_SPECIALCHARS'
constMappingTable[1] = 'HTML_ENTITIES'
constMappingQuoteStyle[0] = 'ENT_NOQUOTES'
constMappingQuoteStyle[2] = 'ENT_COMPAT'
constMappingQuoteStyle[3] = 'ENT_QUOTES'
useTable = !isNaN(table)
? constMappingTable[table]
: table
? table.toUpperCase()
: 'HTML_SPECIALCHARS'
useQuoteStyle = !isNaN(quoteStyle)
? constMappingQuoteStyle[quoteStyle]
: quoteStyle
? quoteStyle.toUpperCase()
: 'ENT_COMPAT'
if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
throw new Error('Table: ' + useTable + ' not supported')
}
entities['38'] = '&'
if (useTable === 'HTML_ENTITIES')
{
entities['160'] = ' '
entities['161'] = '¡'
entities['162'] = '¢'
entities['163'] = '£'
entities['164'] = '¤'
entities['165'] = '¥'
entities['166'] = '¦'
entities['167'] = '§'
entities['168'] = '¨'
entities['169'] = '©'
entities['170'] = 'ª'
entities['171'] = '«'
entities['172'] = '¬'
entities['173'] = ''
entities['174'] = '®'
entities['175'] = '¯'
entities['176'] = '°'
entities['177'] = '±'
entities['178'] = '²'
entities['179'] = '³'
entities['180'] = '´'
entities['181'] = 'µ'
entities['182'] = '¶'
entities['183'] = '·'
entities['184'] = '¸'
entities['185'] = '¹'
entities['186'] = 'º'
entities['187'] = '»'
entities['188'] = '¼'
entities['189'] = '½'
entities['190'] = '¾'
entities['191'] = '¿'
entities['192'] = 'À'
entities['193'] = 'Á'
entities['194'] = 'Â'
entities['195'] = 'Ã'
entities['196'] = 'Ä'
entities['197'] = 'Å'
entities['198'] = 'Æ'
entities['199'] = 'Ç'
entities['200'] = 'È'
entities['201'] = 'É'
entities['202'] = 'Ê'
entities['203'] = 'Ë'
entities['204'] = 'Ì'
entities['205'] = 'Í'
entities['206'] = 'Î'
entities['207'] = 'Ï'
entities['208'] = 'Ð'
entities['209'] = 'Ñ'
entities['210'] = 'Ò'
entities['211'] = 'Ó'
entities['212'] = 'Ô'
entities['213'] = 'Õ'
entities['214'] = 'Ö'
entities['215'] = '×'
entities['216'] = 'Ø'
entities['217'] = 'Ù'
entities['218'] = 'Ú'
entities['219'] = 'Û'
entities['220'] = 'Ü'
entities['221'] = 'Ý'
entities['222'] = 'Þ'
entities['223'] = 'ß'
entities['224'] = 'à'
entities['225'] = 'á'
entities['226'] = 'â'
entities['227'] = 'ã'
entities['228'] = 'ä'
entities['229'] = 'å'
entities['230'] = 'æ'
entities['231'] = 'ç'
entities['232'] = 'è'
entities['233'] = 'é'
entities['234'] = 'ê'
entities['235'] = 'ë'
entities['236'] = 'ì'
entities['237'] = 'í'
entities['238'] = 'î'
entities['239'] = 'ï'
entities['240'] = 'ð'
entities['241'] = 'ñ'
entities['242'] = 'ò'
entities['243'] = 'ó'
entities['244'] = 'ô'
entities['245'] = 'õ'
entities['246'] = 'ö'
entities['247'] = '÷'
entities['248'] = 'ø'
entities['249'] = 'ù'
entities['250'] = 'ú'
entities['251'] = 'û'
entities['252'] = 'ü'
entities['253'] = 'ý'
entities['254'] = 'þ'
entities['255'] = 'ÿ'
}
if (useQuoteStyle !== 'ENT_NOQUOTES')
{
entities['34'] = '"'
}
if (useQuoteStyle === 'ENT_QUOTES')
{
entities['39'] = '''
}
entities['60'] = '<'
entities['62'] = '>'
// ascii decimals to real symbols
for (decimal in entities)
{
if (entities.hasOwnProperty(decimal))
{
hashMap[String.fromCharCode(decimal)] = entities[decimal]
}
}
return hashMap
}
DecodeHTMLEntities.DecodeEntity
=
function( entity )
{
var ret = entity;
if ( 0 == entity.indexOf( "#" ) )
{
var entity2 = entity.substring( 1, entity.length );
var e = entity2.indexOf( ";" );
if ( (entity2.length - 1) == e )
{
var entity3 = entity2.substring( 0, entity2.length - 1 );
var dec = parseInt( entity3 );
if ( NaN !== dec )
{
ret = String.fromCharCode( dec );
}
}
}
return ret;
}
/*
* PureJavacript, Helper.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function GetTuple( obj )
{
var tuple = null;
if ( obj instanceof Array )
{
for ( index in obj )
{
tuple = GetTuple( obj[index] );
break;
}
}
else
{
tuple = obj;
}
return tuple;
}
function LimitOffsetParameters( json )
{
var parameters = null;
var offset = ("" != json.offset) ? parseInt( json.offset ) : 0;
var limit = ("" != json.limit ) ? parseInt( json.limit ) : 0;
if ( limit )
{
parameters = new Object();
parameters.limit = limit;
parameters.offset = limit + offset;
}
return parameters;
}
function Object_Get( $object, $member )
{
if ( $object.hasOwnProperty( $member ) )
{
return decodeURI( $object[$member] );
}
else
{
return "";
}
}
function Replace( text, array, recode = false )
{
for ( var member in array )
{
var key = "%" + member + "%";
var value = recode ? Recode( array[member] ) : array[member];
while ( -1 != text.indexOf( key ) )
{
text = text.replace( key, value );
}
}
return text;
}
function Recode( html_entity_encoded_text )
{
var decoded = DecodeHTMLEntity( html_entity_encoded_text );
var encoded = encodeURIComponent( decoded );
return encoded;
}
function DecodeHTMLEntity( html_entity_encoded_text )
{
var ret = html_entity_encoded_text;
var type = typeof html_entity_encoded_text;
if ( "string" == type )
{
// Based on:
// https://stackoverflow.com/a/29824550
//
ret = html_entity_encoded_text.replace(/(\d+);/g, function( match, dec ) { return String.fromCharCode(dec); } );
}
return ret;
}
/*
* PureJavacript, InputFile.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function InputFile( file_id, progress_handler, onload_handler, onerror_handler )
{
return new InputFile.Class( file_id, progress_handler, onload_handler, onerror_handler );
}
InputFile.Class
=
function ( file_id, progress_handler, onload_handler, onerror_handler )
{
this.reader = new FileReader();
this.reader.onprogress = progress_handler ? progress_handler : InputFile.OnProgress;
this.reader.onloadend = onload_handler ? onload_handler : InputFile.OnLoad;
this.reader.onerror = onerror_handler ? onerror_handler : InputFile.OnError;
this.count = 0;
var input = document.getElementById( file_id );
var file = input.files[0];
switch ( input.files[0].type.split( "/" )[1] )
{
case "png":
this.fileType = "png";
break;
case "jpg":
case "jpeg":
this.fileType = "jpg";
break;
case "csv":
this.fileType = "csv";
break;
default:
this.fileType = "";
}
/*
* Kludge to allow IE browsers to call 'readAsBinaryString', see:
* https://stackoverflow.com/questions/31391207/javascript-readasbinarystring-function-on-e11
*/
if ( FileReader.prototype.readAsBase64 === undefined )
{
FileReader.prototype.readAsBase64
=
function( file_input )
{
this.readAsArrayBuffer( file_input );
}
}
this.reader.onload
=
function( e )
{
var binary = "";
var bytes = new Uint8Array( this.result );
var length = bytes.byteLength;
for ( var i=0; i < length; i++ )
{
binary += String.fromCharCode( bytes[i] )
}
this.resultAsBase64 = Base64.Encode( binary );
}
this.reader.readAsBase64( file );
}
InputFile.Class.prototype.getCount
=
function()
{
return this.count;
}
InputFile.OnProgress
=
function()
{
console.log( "InputFile: default onprogress handler" );
}
InputFile.OnLoad
=
function()
{
console.log( "InputFile: default onload handler" );
}
InputFile.OnError
=
function()
{
console.log( "InputFile: default onerror handler" );
}
/*
* PureJavacript, Is.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Is = {}
Is.Date = IsDate
Is.Prefix = IsPrefix
function IsDate( $datetime )
{
var is_date = false;
switch ( $datetime )
{
case null:
case "NULL":
case "null":
case "":
case "0":
case "0000-00-00":
case "0000-00-00 00:00:00":
break;
default:
is_date = true;
}
return is_date;
}
function IsPrefix( string, prefix )
{
return (0 == string.indexOf( prefix ));
}
/*
* PureJavacript, Links.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Links = {}
Links.Activate = LinksActivate
Links.Complete = LinksComplete
function LinksActivate( links, href, top_level_links )
{
var n = links.length;
if ( !top_level_links ) top_level_links = [];
for ( var i=0; i < n; i++ )
{
var link = links[i];
if ( link.href )
{
if ( link.href == href )
{
link.className += ("" == link.className) ? "active" : " active";
}
//
// If href = '/dashboard/some/directory/',
// and link.href = '/dashboard/some/',
//
// then it should have the class 'subactive' added,
// indicating that the link is a parent directory of the current page
// unless it is a 'top_level' link.
//
var is_prefix = LinksActivate.IsPrefix( href, link.href );
var is_dashboard = LinksActivate.IsDashboard( link.href );
var is_tll = LinksActivate.TopLevelLinksContainsPrefixOfCurrentPage( top_level_links, href );
if ( is_prefix && !(is_dashboard && is_tll) )
{
link.className += ("" == link.className) ? "subactive" : " subactive";
}
}
}
}
LinksActivate.IsPrefix
=
function( string, prefix )
{
return (0 === string.indexOf( prefix ));
}
LinksActivate.IsDashboard
=
function( href )
{
return (href == location.protocol + "//" + location.hostname + "/dashboard/" );
}
LinksActivate.TopLevelLinksContainsPrefixOfCurrentPage
=
function( top_level_links, current_page )
{
var r = false;
var n = top_level_links.length;
for ( var i=0; i < n; i++ )
{
if ( IsPrefix( current_page, top_level_links[i] ) )
{
r = true;
break;
}
}
return r;
}
LinksActivate.IsRootHref
=
function( href )
{
return ((location.protocol + '//') == href);
}
function LinksComplete( links, tuple )
{
var n = links.length;
for ( var i=0; i < n; i++ )
{
var link = links[i];
if ( link.href )
{
link.href = Replace( link.href, tuple, true );
}
link.innerHTML = Replace( link.innerHTML, tuple );
}
}
/*
* PureJavacript, Load.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Load = {}
Load.ImageFile = LoadInputFromImageFile
Load.Table = LoadTableFromFile
function LoadInputFromImageFile( targetID, fileID, holderID )
{
var target = document.getElementById( targetID );
var file = document.getElementById( fileID );
if ( target && file )
{
file.imageFile = new InputFile( fileID, null, function() { LoadInputFromImageFileHandler( targetID, fileID, holderID ); }, null );
}
}
function LoadInputFromImageFileHandler( targetID, fileID, holderID )
{
var target = document.getElementById( targetID );
var file = document.getElementById( fileID );
var holder = document.getElementById( holderID );
var base64 = file.imageFile.reader.resultAsBase64;
var ext = file.imageFile.fileType;
var url64 = "data:image/" + ext + ";base64," + base64;
target.value = url64.replace( '=', '' );
if ( holder )
{
holder.style.background = "white url(" + url64 + ") no-repeat center center";
holder.style.backgroundSize = "cover";
Class.RemoveClass( holder, "hidden" );
}
}
function LoadTableFromFile( event )
{
var table_id = event.target.getAttribute( "data-target-id" );
var table = document.getElementById( table_id );
if ( table )
{
var id = event.target.id;
LoadTableFromFile.table = table;
LoadTableFromFile.file = InputFile( id, null, LoadTableFromFile.OnLoad, null );
}
}
LoadTableFromFile.OnLoad
=
function()
{
if ( ! LoadTableFromFile.file )
{
console.log( "Unexpectedly, could not find file!" );
}
//else
//if ( "csv" != LoadTableFromFile.file.fileType )
//{
// alert( "Please add a CSV (Comman Seperated Value) file - file of type " + LoadTableFromFile.file.fileType + " selecteed" );
//
// location.reload();
//}
else
{
var table = LoadTableFromFile.table;
var content = Base64.Decode( LoadTableFromFile.file.reader.resultAsBase64 );
var csv_file = new CSVFile( content );
var col_specs = LoadTableFromFile.ExtractColumnSpecs( LoadTableFromFile.table );
var tbody = table.tBodies[0];
var rows = csv_file.getNrOfRows();
if ( 0 < rows )
{
tbody.innerHTML = "";
for ( var row=0; row < rows; row++ )
{
var tr = document.createElement( "TR" );
var n = col_specs.length;
for ( var i=0; i < n; i++ )
{
// Weirdness alert !!!
// When assigning from 'value' into 'td.innerHTML' Safari (and possibly other browsers)
// will html entity encode characters such as ampersands that are in 'value'.
// To ensure that this always happens, 'td.innerHTML' is then passed to the function
// 'HTMLEntitiesEncode', which will encode any entities that were not automatically
// converted by the browser. Note, the fourth parameter of 'HTMLEntitiesEncode' is
// false, which prevents already encoded entities from being re-encoded.
// Therefore, this kind of makes it impossible to use this Load.Table mechanism
// to load values that contain html entities that need to be preserved, i.e.
// & should be converted to '&', 'a', 'm', 'p', ';'.
var spec = col_specs[i];
var td = document.createElement( "TD" );
var value = csv_file.getValueFor( row, spec.source_names );
td.innerHTML = value;
td.innerHTML = HTMLEntitiesEncode( td.innerHTML, 'ENT_QUOTES', 'UTF8', false );
td.setAttribute( "data-name", spec.field );
tr.appendChild( td );
}
tbody.appendChild( tr );
}
}
}
}
LoadTableFromFile.ExtractColumnSpecs
=
function( table )
{
var col_specs = new Array();
var th_elements = table.getElementsByTagName( "TH" );
var n = th_elements.length;
for ( var i=0; i < n; i++ )
{
var th = th_elements[i];
var field = th.getAttribute( "data-field" );
var source_names = th.getAttribute( "data-source-names" );
var col_spec = new Object();
col_spec['field'] = field;
col_spec['source_names'] = source_names.split( "," );
col_specs.push( col_spec );
}
return col_specs;
}
/*
* PureJavacript, Locations.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Locations = {}
Locations.SearchValues = GetSearchValues
Locations.SearchValue = GetSearchValue
Locations.Up = Up
Locations.TwoUp = TwoUp
Locations.CreateDownFn = CreateDownFn
Locations.Down = Down
Locations.Reload = Reload
function GetSearchValues()
{
return GetSearchValues.CreateDictionary( window.location.search );
}
GetSearchValues.CreateDictionary
=
function( url_search_parameters )
{
var object = new Object;
var bits = url_search_parameters.substring( 1 ).split( "&" );
var n = bits.length;
for ( var i=0; i < n; i++ )
{
var keyvalue = bits[i].split( "=" );
if ( 2 == keyvalue.length )
{
var key = "";
var val = "";
try
{
key = decodeURIComponent( keyvalue[0] );
val = decodeURIComponent( keyvalue[1] );
}
catch ( err )
{}
if ( (null != key) && (null != val) ) object[key] = val;
}
}
return object;
}
function GetSearchValue( name )
{
var parameters = GetSearchValues();
return parameters[name] ? parameters[name] : "";
}
function Up( search_parameters )
{
var loc = location.protocol + "//" + location.host;
var bits = location.pathname.split( "/" );
var path = "";
switch ( bits.length )
{
case 0: // ""
case 1: // Can't happen
path = "/";
break;
case 2: // "/"
path = "/";
break;
default:
bits = ("" == bits[bits.length - 1]) ? bits.slice( 0, -2 ) : bits.slice( 0, -1 );
path = bits.join( "/" ) + "/";
}
loc += path;
if ( null == search_parameters )
{
loc += location.search;
}
else
{
loc += "?";
for ( key in search_parameters )
{
loc += search_parameters[key] + "=" + Recode( GetSearchValue( search_parameters[key] ) ) + "&";
}
loc = loc.substring( 0, loc.length - 1 );
}
location.assign( loc );
}
function TwoUp( search_parameters )
{
var loc = location.protocol + "//" + location.host;
var bits = location.pathname.split( "/" );
var path = "";
switch ( bits.length )
{
case 0: // ""
case 1: // Can't happen
path = "/";
break;
case 2: // "/"
path = "/";
break;
default:
bits = ("" == bits[bits.length - 1]) ? bits.slice( 0, -3 ) : bits.slice( 0, -2 );
path = bits.join( "/" ) + "/";
}
loc += path;
if ( null == search_parameters )
{
loc += location.search;
}
else
{
loc += "?";
for ( key in search_parameters )
{
loc += search_parameters[key] + "=" + Recode( GetSearchValue( search_parameters[key] ) ) + "&";
}
loc = loc.substring( 0, loc.length - 1 );
}
location.assign( loc );
}
function CreateDownFn( pathname, search )
{
return function()
{
Down( pathname, search );
}
}
function Down( pathname, search )
{
var loc = location.protocol + "//" + location.host + location.pathname + pathname + search;
if ( -1 !== loc.indexOf( '=%' ) )
{
var parameters = Locations.SearchValues();
loc = Replace( loc, parameters );
}
location.assign( loc );
}
function Reload( ignored )
{
location.reload();
}
/*
* PureJavacript, Menu.js
*
* Copyright 2014 - 2019, CrossAdaptive
*/
function Menu( id )
{
var element = document.getElementById( id );
var display = element.getAttribute( "data-display" );
if ( !display )
{
display = "block";
}
if ( element.style.display && (display == element.style.display) )
{
element.style.display = "none";
document.removeEventListener( "keyup", Menu.EscHandler );
}
else
{
element.style.display = display;
document.addEventListener( "keyup", function( event ) { Menu.EscHandler( event, id ) } );
}
}
Menu.EscHandler
=
function( event, id )
{
if ( 27 === event.keyCode )
{
var element = document.getElementById( id );
element.style.display = "none";
document.removeEventListener( "keyup", Menu.EscHandler );
}
}
/*
* PureJavacript, Modal.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
Modal = {}
Modal.Close = CloseModals;
Modal.Toggle = ToggleModal;
function CloseModals()
{
var modal_bg = document.getElementById( "modal-bg" );
var divs = document.getElementsByTagName( "DIV" );
var n = divs.length;
for ( var i=0; i < n; i++ )
{
if ( "modal" == divs[i].className )
{
var modal = divs[i];
modal.style.display = "none";
}
}
if ( modal_bg ) modal_bg.style.display = "none";
}
function ToggleModal( modal_id )
{
var modal = document.getElementById( modal_id );
var modal_bg = document.getElementById( "modal-bg" );
if ( modal )
{
switch ( modal.style.display )
{
case "block":
modal.style.display = "none";
modal_bg.style.display = "none";
break;
case "none":
default:
modal_bg.style.display = "block";
modal.style.visibility = "hidden";
modal.style.display = "block";
var width = modal.offsetWidth;
width = width / 2;
width = 1 - width;
modal.style.marginLeft = width + "px";
modal.style.visibility = "visible";
}
}
}
/*
* PureJavacript, Selects.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function Selects( resolver )
{
Selects.resolver = resolver;
Selects.setup();
}
Selects.setup
=
function()
{
var kinds = Array();
var selects = document.getElementsByTagName( "SELECT" );
if ( selects )
{
var n = selects.length;
for ( var i=0; i < n; i++ )
{
var select = selects[i];
select.setValue = Selects.setValue;
var id = select.hasAttribute( "id" ) ? select.getAttribute( "id" ) + ":" : "";
var kind = select.getAttribute( "data-kind" );
if ( kind )
{
var cupid = id + kind;
kinds.push( cupid );
}
}
}
if ( kinds.length )
{
Selects.Multiselect( Selects.ArrayToString( kinds ), "", Selects.setup.handler );
}
}
Selects.setup.handler
=
function( responseText )
{
var obj = typeof responseText === 'string' || responseText instanceof String ? JSON.parse( responseText ) : responseText;
if ( obj && obj.results )
{
var lists = Array();
var n = obj.results.length;
for ( var i=0; i < n; i++ )
{
var list = obj.results[i];
var name = list.name;
var tuples = list.tuples;
lists[name] = tuples;
}
Selects.setup.init( lists );
}
}
Selects.setup.init
=
function( lists )
{
var selects = document.getElementsByTagName( "SELECT" );
if ( selects )
{
var n = selects.length;
for ( var i=0; i < n; i++ )
{
var select = selects[i];
var id = select.hasAttribute( "id" ) ? select.getAttribute( "id" ) + ":" : "";
var kind = select.getAttribute( "data-kind" );
if ( kind && lists.hasOwnProperty( id + kind ) )
{
Selects.setup.addOptions( select, lists );
}
}
for ( var i=0; i < n; i++ )
{
var select = selects[i];
var id = select.hasAttribute( "id" ) ? select.getAttribute( "id" ) + ":" : "";
var kind = select.getAttribute( "data-kind" );
select.addEventListener( "change", Selects.SetSelected );
if ( kind && lists.hasOwnProperty( id + kind ) )
{
if ( select.hasAttribute( "data-cascade" ) )
{
select.addEventListener( "change", Selects.Cascade );
if ( select.hasAttribute( "data-value" ) )
{
Selects.DoCascade( select );
}
}
}
}
}
}
Selects.setup.addOptions
=
function( select, lists )
{
var id = select.hasAttribute( "id" ) ? select.getAttribute( "id" ) + ":" : "";
var kind = select.getAttribute( "data-kind" );
var type = select.getAttribute( "data-select-type" );
var tuples = lists[id + kind];
if ( tuples )
{
select.options.length = 0;
var offset = 0;
var selected = 0;
var label = select.getAttribute( "data-label" ) ? select.getAttribute( "data-label" ) : select.getAttribute( "placeholder" );
if ( label )
{
select.options[0] = new Option( label, '' );
offset++;
}
//if ( ! select.disabled )
{
var data_value = select.getAttribute( "data-value" );
var data_text = select.getAttribute( "data-text" );
var n = tuples.length;
for ( var i=0; i < n; i++ )
{
var disabled = false;
var name = tuples[i].name;
var text = DecodeHTMLEntities( tuples[i].text );
text = text ? text : "";
if ( 0 == name.indexOf( "!" ) )
{
disabled = true;
name = name.substring( 1 );
}
if ( name == data_value ) selected = i+offset;
if ( -1 !== text.indexOf( data_text ) ) selected = i+offset;
if ( name != text )
{
select.options[i+offset] = new Option( text, name );
}
else
{
select.options[i+offset] = new Option( text );
}
select.options[i+offset].disabled = disabled;
}
select.selectedIndex = selected;
}
if ( ("progressive" == type) && (0 < selected) )
{
for ( var i=selected - 1; i >= 0; i-- )
{
select.options[i].disabled = true;
}
}
}
}
Selects.lookupOptions
=
function( id, kind, value )
{
var select = document.getElementById( id );
if ( select )
{
var n = select.length;
if ( 0 < n )
{
for ( var i=0; i < n; i++ )
{
if ( select.options[i].value == value )
{
select.selectedIndex = i;
break;
}
}
}
else
{
select.setAttribute( "data-value", value );
}
}
}
Selects.Cascade
=
function( event )
{
Selects.DoCascade( event.target );
}
Selects.DoCascade
=
function( select )
{
var value = select.value;
var targets = select.getAttribute( "data-cascade" );
if ( targets )
{
var bits = targets.split( "," );
var n = bits.length;
for ( var i=0; i < n; i++ )
{
var target = bits[i];
if ( target )
{
Selects.Reload( target, value );
}
}
select.addEventListener( "change", Selects.Cascade );
//select.onchange = Selects.Cascade;
}
}
Selects.Reload
=
function( target, value )
{
var select = document.getElementById( target );
if ( select )
{
if ( "SELECT" == select.tagName )
{
var kind = select.getAttribute( "data-kind" );
Selects.Multiselect( target + ":" + kind, value, Selects.setup.handler );
//if ( value ) select.disabled = false;
}
else
{
if ( select.reload )
{
select.reload( value );
}
}
}
}
Selects.Multiselect
=
function( kinds, value, handler )
{
var search = GetSearchValues();
var parameters = new Object();
parameters.kinds = kinds;
parameters.filter = value ? value : search.filter ? search.filter : "";
parameters.json = JSON.stringify( search );
var api_host = Selects.resolver();
Call( api_host + "/api/multiselect/", parameters, handler );
}
Selects.SetValue
=
function( id, value )
{
var select = document.getElementById( id );
select.setValue( value );
}
Selects.setValue
=
function( value )
{
if ( this )
{
var n = this.length;
if ( 0 < n )
{
for ( var i=0; i < n; i++ )
{
if ( this.options[i].value == value )
{
this.selectedIndex = i;
break;
}
}
Selects.DoCascade( this );
}
else
{
this.setAttribute( "data-value", value );
}
Selects.SetSelectedClass( this );
}
}
Selects.SetSelected
=
function( event )
{
var select = event.target;
Selects.SetSelectedClass( select );
}
Selects.SetSelectedClass
=
function( select )
{
if ( 0 == select.selectedIndex )
{
Class.RemoveClass( select, "selected" );
} else {
Class.AddClass ( select, "selected" );
}
}
Selects.ArrayToString
=
function( array )
{
var string = "";
var sep = "";
for ( var i in array )
{
string += sep + array[i];
sep = ",";
}
return string;
}
/*
* PureJavacript, Session.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function Session( Redirect )
{
Session.Redirect = Redirect;
Call( "/api/auth/session/", {}, Session.Switch );
}
Session.Switch
=
function( responseText )
{
Session.Handler( responseText );
if ( 'function' === typeof Session.CustomHandler )
{
Session.CustomHandler( responseText );
}
if ( Session.Redirect )
{
Session.Redirect( Session.idtype );
}
}
Session.Handler
=
function ( responseText )
{
var idtype = "";
Session.idtype = "";
if ( -1 != responseText.indexOf( "UNAUTHENTICATED" ) )
{
Session.status = "UNAUTHENTICATED";
}
else
if ( -1 != responseText.indexOf( "INVALID_SESSION" ) )
{
Session.status = "INVALID_SESSION";
}
else
if ( "" != responseText )
{
var obj = JSON.parse( responseText );
if ( obj && obj.idtype )
{
Session.email = obj.email;
Session.idtype = obj.idtype;
Session.given_name = obj.given_name;
Session.family_name = obj.family_name;
Session.user_hash = obj.user_hash;
Session.read_only = obj.read_only;
Session.status = "AUTHENTICATED";
idtype = Session.idtype;
}
else
if ( obj && obj.results && (1 == obj.results.length) && obj.results[0].idtype )
{
var obj = obj.results[0];
Session.email = obj.email;
Session.idtype = obj.idtype;
Session.given_name = obj.given_name;
Session.family_name = obj.family_name;
Session.user_hash = obj.user_hash;
Session.read_only = obj.read_only;
Session.status = "AUTHENTICATED";
idtype = Session.idtype;
}
else
if ( obj && obj.error )
{
Session.status = obj["error"];
}
}
//Redirect( idtype );
}
/*
* PureJavacript, Setup.js
*
* Copyright 2014 - 2017, CrossAdaptive
*/
function Setup()
{
Setup.Elements( document.getElementsByTagName( "DIV" ) );
Setup.Elements( document.getElementsByTagName( "FORM" ) );
Setup.Elements( document.getElementsByTagName( "TBODY" ) );
}
Setup.CreateTableSetupFn
=
function( id, nr_columns, clear )
{
var path = "";
var search = "";
if ( undefined === clear ) clear = false;
return Setup.CreateTableSetupWithDownFn( id, nr_columns, path, search, clear );
}
Setup.CreateTableSetupWithDownFn
=
function( id, nr_columns, path, search, clear )
{
if ( undefined === clear ) clear = false;
/*
* The returned function parses the JSON formatted response text and creates a table row template for each result tuple.
* These are added to the tbody corresponding to 'id' - 'nr_of_columns' is used if no result tuples are returned.
*/
var fn
=
function( responseText )
{
var json = typeof responseText === 'string' || responseText instanceof String ? JSON.parse( responseText ) : responseText;
var tbody = document.getElementById( id );
if ( tbody && ("OK" == json.status) )
{
var htm = Setup.CreateTableSetupFn.RetrieveTemplate( id );
var htm2 = Setup.CreateTableSetupFn.RetrieveTemplate( id + "-tally" );
var htm3 = Setup.CreateTableSetupFn.RetrieveTemplate( id + "-summary" );
if ( ! htm )
{
alert( "Table '" + id + "' is missing a row template with the id: '" + id + "-template'" );
}
else
{
var n = json.results.length;
var offset = parseInt( tbody.getAttribute( "data-offset" ) );
offset = isNaN( offset ) ? 0 : offset;
var limit = parseInt( tbody.getAttribute( "data-limit" ) );
limit = isNaN( limit ) ? 0 : limit;
if ( (0 == n) && (0 == offset) )
{
var tr = document.createElement( "TR" );
tr.innerHTML = "