All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jwic.jwic_core.js Maven / Gradle / Ivy

There is a newer version: 5.3.43
Show newest version
/*******************************************************************************
 * Copyright 2015 xWic group (http://www.xwic.de)
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 *  
 *******************************************************************************/

jQuery.noConflict();

/**
 * JWic defines the public API for JWic server/client communication.
 */
var JWic = {
	version :'5.0.0',
	debugMode : false,
	_logCount : 0,
	contextPath : "",
	cbSeq : 0,
		
	/**
	 * Indicates if the client is currently sending or waiting for an action
	 * request.
	 */
	isProcessing :false,
	
	commandQueue : [],
	/**
	 * The time in milliseconds before the please wait message appears.
	 */
	pleaseWaitDelayTime :500,
	
	lastResizeTime :0,

	/**
	 * List which contains all destroy functions for the existing controls.
	 */
	destroyList : [],

	/**
	 * List which contains an optional callback function per control that is
	 * invoked before a request is send to the server.
	 */
	beforeRequestCallbacks : {},
	
	/**
	 * List of functions that get invoked on each control that is updated.
	 */
	runAfterUpdate : [],
	
	/**
	 * Set to true while JWic tries to reconnect to the server.
	 */
	reconnectMode : false,
	
	/**
	 * Returns a jQuery encapsulated document element. The element is retrieved
	 * using document.getElementById and then extended with jQuery. This eliminates the
	 * need to escape the control ID when using jQuery's native $/jQuery function. 
	 */
	$ : function(id) {
		var elm = document.getElementById(id);
		if (elm) {
			return jQuery(elm);
		}
		return null;
	},
	
	/**
	 * Handle the response from an fireAction request.
	 */
	handleResponse : function(ajaxResponse, callBack) {
	    var util = JWic.util,
	        response = jQuery.parseJSON(ajaxResponse.responseText),
	        requiredJS = response.requiredJS || [],
            updateables = response.updateables || [],
            scriptQueue = response.scriptQueue || [],
            that = this;

	    callBack = callBack || util.identity;

        var refresh = function refresh(message){
            if(message){
                alert(message);
            }
            jwicform.elements['__ctrlid'].value = '';
            jwicform.elements['__action'].value = 'refresh';
            jwicform.submit();
        }

		if (ajaxResponse.status == 0 && ajaxResponse.responseText == "") {
			JWic.connectionLost();
			return;
		}

		if (response.exception) {
			refresh("A server side exception occurred: " + response.exception + "\nHit ok to refresh.");
			return;
		}

        if (response.requireRedraw) {
            refresh();
            return;
        }

		if (response.ticket === undefined) {
		    return;
		}
		jwicform.elements['__ticket'].value = response.ticket;

        var asyncScripts = jQuery.map(requiredJS, util.loadLibAsync);

        util.whenAll(asyncScripts).then(function(){
            jQuery.each(updateables, function(idx, elm) {
                JWic.updateControl(elm);
            });
        }).then(function(){
            jQuery.each(scriptQueue, function(idx, line) {
                try {
                    eval(line);
                } catch (e) {
                    JWic.log("Error executing script queue: " + e + " for line " + line);
                }
            });
        }).then(function(){
            that.endRequest();
            try {
                callBack();
            } catch (e) {
                JWic.log("callBack function failed: ", e);
            }
        });


	},

	/**
	 * When a request to the server fails, the connection may be lost. Display a window with this information
	 * and ask the user if he wants to retry or 
	 */
	connectionLost : function() {
		var dlg = JWic.$("_JWicDialog");
		dlg.html("
The connection to the server is lost, trying to reconnect" + " to the server. Please check your network connectivity.

The app will continue as soon as the connection got" + " re-established. You can force a reload of the content if your network is back but the page still doesnt load.
"); dlg.dialog({ dialogClass: "j-dialog-no-close", minWidth: 350, buttons:[ // { // text: "Restart Application", // click: function() { // jQuery(this).dialog("close"); // JWic.restartApp(); // } // } ], modal: true, title: "Connection Lost" }); JWic.reconnectMode = true; JWic.connectionTest(); }, /** * Make a 'connectionTest' request to the server. */ connectionTest : function() { var paramData = {}; paramData['_jConTest'] = '1'; paramData['_msid'] = document.forms['jwicform'].elements['_msid'].value; var url = document.location.href; var idx = url.indexOf('#'); if (idx != -1) { url = url.substring(0, idx); } jQuery.ajax({ url: url, type :'post', data : paramData, success : function(data, textStatus, jqXHR) { JWic.connectionTestSuccess(data, jqXHR);} , error : function(jqXHR, textStatus, errorThrown) { JWic.connectionTestFailed(jqXHR, textStatus, errorThrown); } }); }, connectionTestSuccess : function(data, jqXHR) { JWic.log("Connection Success"); if (data.sessionInitialized) { // the connection is available and the session is still available. if (JWic.reconnectMode) { var dlg = JWic.$("_JWicDialog"); dlg.dialog("close"); JWic.reconnectMode = false; JWic.ui.Notify.display("Connection re-established.."); } } else { // the connection is available again, but the session is no longer available. A restart is required. if (JWic.reconnectMode) { var dlg = JWic.$("_JWicDialog"); dlg.dialog("close"); JWic.reconnectMode = false; dlg.html("
The Server is available again, but the session on the server is no longer available. " + "Either the session has expired in the meantime or the server was restarted. The application " + "will now be reloaded.
"); dlg.dialog({ dialogClass: "j-dialog-no-close", buttons:[ { text: "Ok", icons: { primary: "ui-icon-arrowrefresh-1-w" }, click: function() { jQuery(this).dialog("close"); JWic.restartApp(); } } ], modal: true, title: "Reconnected" }); } } }, connectionTestFailed : function(jqXHR, textStatus, errorThrown) { JWic.log("Connection Failed - retrying"); window.setTimeout("JWic.connectionTest()", 1000); }, /** * Reload the current URL, removing any hashes */ restartApp : function() { var appUrl = window.location.href; var hash = appUrl.indexOf('#'); if (hash >= 0) { appUrl = appUrl.substring(0, hash); } // immediately show click blocker while reloading... JWic.isProcessing = true; JWic.showClickBlocker(true); JWic.showLongDelay(JWic.cbSeq); window.location.href = appUrl; }, /** * Update a control on the document. */ updateControl : function(elm, control) { control = control ? control : document.getElementById("ctrl_" + elm.key); var scripts = []; if (elm.scripts) { for ( var i = 0; i < elm.scripts.length; i++) { scripts.push({ key: elm.scripts[i].controlId, script: eval('(' + elm.scripts[i].script + ')') }); } } if (control) { // call beforeUpdate in scripts for ( var i = 0; i < scripts.length; i++) { if (scripts[i].script.beforeUpdate) { try { scripts[i].script.beforeUpdate(control); } catch (e) { JWic.log("Error in beforeUpdate: " + e + " (Control: " + elm.key + ")"); } } } var doReplace = true; for ( var i = 0; i < scripts.length; i++) { if (scripts[i].script.doUpdate && scripts[i].key === elm.key) { try { if (scripts[i].script.doUpdate(control)) { doReplace = false; break; } } catch (e) { JWic.log("Error in doUpdate: " + e + " (Control: " + elm.key + ")"); } } } if (doReplace) { // replace the DOM element with the // rendered snippit received // call destroy handler and remove them var deLst = JWic.destroyList; for ( var i = deLst.length - 1; i >= 0; i--) { if (deLst[i] && (deLst[i].key == elm.key || deLst[i].key.indexOf(elm.key + ".") === 0)) { JWic.log("Destroy: " + deLst[i].key + " because of " + elm.key); try { deLst[i].destroy(control); } catch (e) { JWic.log("Error in destroy: " + e + " (Control: " + deLst[i].key + ")"); } deLst.splice(i, 1); } } // remove any beforeUpdateCallbacks var allKeys = []; jQuery.each(JWic.beforeRequestCallbacks, function(key, value) { allKeys.push(key); }); jQuery.each(allKeys, function(key, val) { if (val.indexOf(elm.key) === 0) { delete JWic.beforeRequestCallbacks[val]; } }); // register destroy handler for ( var i = 0; i < scripts.length; i++) { if (scripts[i].script.destroy) { deLst.push( { key :scripts[i].key, destroy :scripts[i].script.destroy }); } } jQuery(control).replaceWith(elm.html); // call afterUpdate in scripts for ( var i = 0; i < scripts.length; i++) { if (scripts[i].script.afterUpdate) { try { scripts[i].script.afterUpdate(control); } catch (e) { JWic.log("Error in afterUpdate: " + e + " (Control/Container: " + elm.key + ")"); } } } for (var i = 0; i < JWic.runAfterUpdate.length; i++) { try { JWic.runAfterUpdate[i](control); } catch (e) { JWic.log("Error in runAfterUpdate #" + i + ": " + e); } } } } }, /** * Clears all inProcess flags and hides the please wait screen, if it is * visible. */ endRequest : function() { JWic.isProcessing = false; if (JWic.commandQueue.length > 0) { JWic._processNextAction() } JWic.showClickBlocker(false); }, /** * Shows or hides the block clicker, so the user cannot click other link * during the processing of the current click. */ showClickBlocker : function(showBlocker) { if (showBlocker && !JWic.isProcessing) { return; } var elem = jQuery("#click_blocker").css('background-image', "none"); var msg = jQuery("#click_blocker_message"); if (elem) { if (showBlocker) { JWic.cbSeq++; var $doc = jQuery(document); var docHeight = $doc.height(); var docWidth = $doc.width(); if (msg) { $win = jQuery(window); var nTop = (($win.height() - msg.height()) / 2) + $win.scrollTop(); var nLeft = (($win.width() - msg.width()) / 2) + $win.scrollLeft(); msg.css( { position : 'absolute', top: nTop + 'px', left: nLeft + 'px' } ); } } if (showBlocker) { elem.show(); elem.css({ 'height': docHeight-4, 'width' : '100%', 'top' : 0, 'left' : 0 }); if (msg) msg.show(); window.setTimeout("JWic.showLongDelay(" + JWic.cbSeq + ")", 1000); } else { elem.hide(); if (msg) msg.hide(); } } }, showLongDelay : function(seqNum) { if (JWic.isProcessing && JWic.cbSeq === seqNum) { var elem = jQuery("#click_blocker"); JWic.log("show long delay blocker") elem.css('background', "url('"+JWic.contextPath+"/jwic/gfx/overlay.png') repeat"); } }, /** * Returns informations about the window size and scrolling position. */ getWindowSize : function() { var myWidth = 0, myHeight = 0, scrollTop, scrollLeft; var type; var win =jQuery(document.body).css('overflow','hidden'); myWidth = win.innerWidth(); myHeight = jQuery(window).innerHeight(); scrollLeft = win.scrollTop(); scrollTop = win.scrollLeft(); win.css('overflow','auto'); return [ myWidth, myHeight, scrollLeft, scrollTop ]; }, /** * Send an action request to the server, including the form values. The * result contains the modified controls, which will then be updated on the * page. */ fireAction : function(senderControl, actionName, actionParameter, callBack) { JWic.commandQueue.push({ senderControl : senderControl, actionName : actionName, actionParameter : actionParameter, callBack : callBack }); if (!JWic.isProcessing) { JWic._processNextAction() } }, _processNextAction : function() { if (JWic.commandQueue.length == 0 || JWic.isProcessing) { return; } var cmd = JWic.commandQueue[0]; // take first in JWic.commandQueue.splice(0, 1); JWic.isProcessing = true; window.setTimeout(function(){ JWic.showClickBlocker(true); }, JWic.pleaseWaitDelayTime); if (!jwicform) { // This might occure if the page is refreshed due to a timeout JWic.log("jwicform not found - command skipped"); return; } jwicform.elements['__ctrlid'].value = cmd.senderControl; jwicform.elements['__action'].value = cmd.actionName; jwicform.elements['__acpara'].value = cmd.actionParameter; // collect system informations. var sysinfoXY = JWic.getWindowSize(); var sysinfo = sysinfoXY[0] + ";" + sysinfoXY[1] + ";" + sysinfoXY[2] + ";" + sysinfoXY[3]; if (jwicform.elements['__sysinfo']) { jwicform.elements['__sysinfo'].value = sysinfo; } jQuery.each(JWic.beforeRequestCallbacks, function (key, item) { try { item(); } catch (e) { JWic.log("Error in beforeRequestCallbacks: " + e + " key: " + key + ")"); } }); // check for file attachments for (var i = 0; i < jwicform.elements.length; i++) { var element = jwicform.elements[i]; if (element.type == "file" && element.value != "") { // if a file-upload control is on the page that has a file assigned, // a real submit is required to transfer the file to the server. // make sure that the encoding type is multipart, before the data is submitted. jQuery(jwicform).trigger("beforeSubmit"); jwicform.encoding = 'multipart/form-data'; jwicform.acceptcharset= 'UTF-8'; jwicform.submit(); return; } } jQuery(jwicform).trigger("beforeSerialization"); var paramData = jQuery(jwicform).serialize(); jQuery(jwicform).trigger("afterSerialization"); paramData+="&_ajaxreq=1"; paramData+="&_format=JSON"; var url = document.location.href; var idx = url.indexOf('#'); if (idx != -1) { url = url.substring(0, idx); } jQuery.ajax({ url: url, type :'post', dataType: 'json', data : paramData, success : function(data, textStatus, jqXHR) { JWic.handleResponse(jqXHR, cmd.callBack); }, error : function(jqXHR, textStatus, errorThrown) { if(jqXHR.status == 404 && jqXHR.statusText == "Not Found") { alert("The requested resource was not found on the server. Please try again."); } else if(jqXHR.status == 0 && textStatus == "error") { JWic.connectionLost(); } else { alert("An exception has occured processing the server response: " + errorThrown, "Error Notification."); } JWic.endRequest(); } }); }, /** * Opens a request to a specific control. The control must implement the * IResourceControl interface to reply to the request. */ resourceRequest: function(controlId, callBack, parameter) { var paramData = {}; if (jQuery.isPlainObject(parameter)) { jQuery.each(parameter, function(key, val){ paramData[key] = val; }); } else { paramData['parameter'] = parameter; } paramData['controlId'] = controlId; paramData['_resreq'] = '1'; paramData['_msid'] = document.forms['jwicform'].elements['_msid'].value; var url = document.location.href; var idx = url.indexOf('#'); if (idx != -1) { url = url.substring(0, idx); } jQuery.ajax({ url: url, type :'post', data : paramData, success : function(data, textStatus, jqXHR) { callBack(jqXHR); } , error : function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 404) { callBack(jqXHR); } else { if(jqXHR.status == 0 && textStatus == "error") { JWic.connectionLost(); } else { alert('resource request failed:' + jqXHR.status + " " + jqXHR.statusText); } } } }); }, /** * Restores the scrolling position of a scrollable container. This is * required if the container was updated and the old position must be * restored. */ restoreScrolling : function(ctrlId, paneId) { if (typeof paneId == "undefined") { paneId = "div_" + ctrlId; } var pane = document.getElementById(paneId); if (pane) { var top = jwicform.elements['fld_' + ctrlId + '.top'].value, left = jwicform.elements['fld_' + ctrlId + '.left'].value; pane.scrollTop = top; pane.scrollLeft = left; // log("Set scrolling for '" + paneId + "' to " + top + ", " + // left); } else { // log("WARNING: Can't fix scrolling for " + paneId); } }, /** * Add a new callback. */ addBeforeRequestCallback : function(controlId, callback) { JWic.beforeRequestCallbacks[controlId] = callback; }, log : function() { if (console !== undefined && console.log !== undefined) { console.log(Array.prototype.slice.call(arguments).join(' ')); } if (JWic.debugMode) { var elem = document.forms['jwicform'].elements['_debugLog']; elem.value = JWic._logCount + ":" + message + "\n" + elem.value; JWic._logCount++; } } }; JWic.util = (function($, JWic){ var createJWicActionHandler = function CreateJWicActionHandler(actionId){ return function JWicActionHandler(){ JWic.fireAction($(this).parent('span').data('id'), actionId); } } var loadLibAsync = (function(){ var cache = {}, first = document.getElementsByTagName('script')[0], parent = first.parentNode; return function _loadLibAsync(lib){ var promise = new jQuery.Deferred(), callBack = function scriptCallback(){ JWic.log('async loaded lib', lib); promise.resolve(lib); cache[lib] = true; }; if(cache[lib] === true){ promise.resolve(lib); JWic.log('lib:', lib, 'already loaded'); return promise; } var script = document.createElement('script'); script.type = "text/javascript"; script.src= JWic.contextPath + "/cp/" + lib; script.async = true; if(document.attachEvent !== undefined){ script.onreadystatechange = function(){ if ( this.readyState === 'loaded'){ callBack(); } } }else{ script.onload = callBack; } parent.insertBefore(script, first); JWic.log('async loading lib', lib); return promise; } }()); var whenAll = function whenAll(promises){ return jQuery.when.apply(jQuery, promises); }; var identity = function identity(x){ return x; } /** * */ var loadScripts = function loadScripts(libs, scripts, scriptEvalFunction){ scriptEvalFunction = scriptEvalFunction || identity; return whenAll(jQuery.map(libs,loadLibAsync)).then(function(){ for(var prop in scripts){ if(scripts.hasOwnProperty(prop)){ var script = scriptEvalFunction(scripts[prop]); if(script.afterUpdate){ script.afterUpdate(document.body); } if (script.destroy) { JWic.destroyList.push({ key : prop, destroy :script.destroy }); } } } return true; }); }; var body = jQuery('body'); body.hide(); //load the initial scripts in the page jQuery(document).ready(function(){ var scripts = JWic.initialScripts.scripts, libs = JWic.initialScripts.statics; loadScripts(libs, scripts).then(function(){ //show the body and do some cleanup body.show(); delete JWic.initialScripts; jQuery('script[data-name=initialScripts]').remove(); }) }); return { loadScripts : loadScripts, loadLibAsync : loadLibAsync, identity : identity, whenAll : whenAll, clearSelection : function() { if(document.selection && document.selection.empty) { try { document.selection.empty(); } catch(ex) {} // can happen in IE8 if nothing is selected } else if (window.getSelection) { var sel = window.getSelection(); if(sel && sel.removeAllRanges) { sel.removeAllRanges() ; } } }, removeElement: function(val, removeMe, seperator) { if (!seperator) seperator = ";"; var x = val.split(seperator); var n = ""; jQuery.each(x, function(key, elm) { if (elm != removeMe) { if (n.length != 0) { n += seperator; } n += elm; } }); return n; }, JQryEscape : function (str){ return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1'); }, /* * Converts simple date format compatible string into jQuery compatible date format */ convertToJqueryDateFormat : function (localFormatString){ //Year if(localFormatString.search(/y{3,}/g) >=0){ /* YYYY */ localFormatString = localFormatString.replace(/y{3,}/g, "yy"); }else if(localFormatString.search(/y{2}/g) >=0){ /* YY */ localFormatString = localFormatString.replace(/y{2}/g, "y"); } //Month if(localFormatString.search(/M{4,}/g) >=0){ /* MMMM */ localFormatString = localFormatString.replace(/M{4,}/g, "MM"); }else if(localFormatString.search(/M{3}/g) >=0){ /* MMM */ localFormatString = localFormatString.replace(/M{3}/g, "M"); }else if(localFormatString.search(/M{2}/g) >=0){ /* MM */ localFormatString = localFormatString.replace(/M{2}/g, "mm"); }else if(localFormatString.search(/M{1}/g) >=0){ /* M */ localFormatString = localFormatString.replace(/M{1}/g, "m"); } //Day if(localFormatString.search(/D{2,}/g) >=0){ /* DD */ localFormatString = localFormatString.replace(/D{2,}/g, "oo"); }else if(localFormatString.search(/D{1}/g) >=0){ /* D */ localFormatString = localFormatString.replace(/D{1}/g, "o"); } //Day of month if(localFormatString.search(/E{4,}/g) >=0){ /* EEEE */ localFormatString = localFormatString.replace(/E{4,}/g, "DD"); }else if(localFormatString.search(/E{2,3}/g) >=0){ /* EEE */ localFormatString = localFormatString.replace(/E{2,3}/g, "D"); } // Millisecond if(localFormatString.search(/S{1,}/g) >=0){ /* S */ localFormatString = localFormatString.replace(/S{1,}/g, "l"); } // AM-PM if(localFormatString.search(/a{1,}/g) >=0){ /* a */ localFormatString = localFormatString.replace(/a{1,}/g, "TT"); }else if(localFormatString.search(/a{2,}/g) >=0){ /* a */ localFormatString = localFormatString.replace(/a{2,}/g, "TT"); } JWic.log(localFormatString); return localFormatString; }, /** * Converts an array of elements of type 'A' into one single element of type 'A' based of of an operation * * Ex: [1,2,3,4] with the + operation would result in the number 10 * * var theNumber10 = JWic.util.reduce([1,2,3,4],function(a,b){ * return a+b; * }); * * * @param arr - the array to be reduced to 1 element * @param cb - the reducer function * @param [first] - the optional first element in the reduction (commonly the operation's neutral element ex: 0 for +, 1 for *, '' for str concat, or even f(x) = x for function composition), * if not passed the first elm in the array is used * @returns */ reduce : function reduce(arr,cb,first){ var i = 0, l = arr.length; if(first == null){ first = arr[0]; i = 1; } for(;i will be an array of those elements. * * * @param array * @param callback */ map : function map (array, callback){ var result = [], i, l; for(i=0,l = array.length;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy