diff --git a/phpgwapi/inc/class.egw_json.inc.php b/phpgwapi/inc/class.egw_json.inc.php
index a40d50b329..758653240c 100644
--- a/phpgwapi/inc/class.egw_json.inc.php
+++ b/phpgwapi/inc/class.egw_json.inc.php
@@ -184,9 +184,10 @@ class egw_json_response
*/
public function sendResult()
{
- $this->sendHeader();
+ $inst = self::get();
- echo $this->getJSON();
+ $inst->sendHeader();
+ echo $inst->getJSON();
}
/**
@@ -202,7 +203,7 @@ class egw_json_response
*/
protected function addGeneric($key, $data)
{
- $this->responseArray[] = array(
+ self::get()->responseArray[] = array(
'type' => $key,
'data' => $data,
);
@@ -218,10 +219,11 @@ class egw_json_response
public function data($data)
{
/* Only allow adding the data response once */
- if (!$this->hasData)
+ $inst = self::get();
+ if (!$inst->hasData)
{
- $this->addGeneric('data', $data);
- $this->hasData = true;
+ $inst->addGeneric('data', $data);
+ $inst->hasData = true;
}
else
{
@@ -317,6 +319,8 @@ class egw_json_response
* Redirect to given url
*
* @param string $url
+ * @param boolean $global specifies whether to redirect the whole framework
+ * or only the current application
*/
public function redirect($url, $global = false)
{
@@ -330,6 +334,43 @@ class egw_json_response
}
}
+ /**
+ * Displays an error message on the client
+ */
+ public function error($msg)
+ {
+ if (is_string($msg))
+ {
+ $this->addGeneric('error', $msg);
+ }
+ }
+
+ /**
+ * Includes the given CSS file. Every url can only be included once.
+ *
+ * @param string $url specifies the url to the css file to include
+ */
+ public function includeCSS($url)
+ {
+ if (is_string($url))
+ {
+ $this->addGeneric('css', $url);
+ }
+ }
+
+ /**
+ * Includes the given JS file. Every url can only be included once.
+ *
+ * @param string $url specifies the url to the css file to include
+ */
+ public function includeScript($url)
+ {
+ if (is_string($url))
+ {
+ self::get()->addGeneric('js', $url);
+ }
+ }
+
/**
* Returns the actual JSON code generated by calling the above "add" function.
*
@@ -337,8 +378,10 @@ class egw_json_response
*/
public function getJSON()
{
+ $inst = self::get();
+
/* Wrap the result array into a parent "response" Object */
- $res = array('response' => $this->responseArray);
+ $res = array('response' => $inst->responseArray);
return json_encode($res); //PHP5.3+, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
}
@@ -348,7 +391,9 @@ class egw_json_response
*/
public function __destruct()
{
- $this->sendResult();
+ //Only send the response if this instance is the singleton instance
+ if ($this == self::get())
+ $this->sendResult();
}
}
@@ -382,7 +427,17 @@ class egw_json_response
$args = func_get_args();
$func = array_shift($args);
- $this->script("window['".$func."'].apply(window, ".json_encode($args).");");
+ $this->script("try{window['".$func."'].apply(window, ".json_encode($args).");} catch(e) {_egw_json_debug_log(e);}");
+ }
+
+ public function addIncludeCSS($url)
+ {
+ $this->includeCSS($url);
+ }
+
+ public function addIncludeScript($url)
+ {
+ $this->includeScript($url);
}
public function getXML()
diff --git a/phpgwapi/js/egw_json.js b/phpgwapi/js/egw_json.js
index 7cee892ca6..a479dabf64 100644
--- a/phpgwapi/js/egw_json.js
+++ b/phpgwapi/js/egw_json.js
@@ -116,15 +116,24 @@ function egw_json_encode(input)
}
-/* The constructor of the egw_json_request class.
+/**
+ * Some variables needed to store which JS and CSS files have already be included
+ */
+var egw_json_files = {};
+
+/** The constructor of the egw_json_request class.
* @param string _menuaction the menuaction function which should be called and which handles the actual request
* @param array _parameters which should be passed to the menuaction function.
-*/
-function egw_json_request(_menuaction, _parameters)
+ */
+function egw_json_request(_menuaction, _parameters, _context)
{
//Copy the supplied parameters
this.menuaction = _menuaction;
+ this.context = window.document;
+ if (typeof _context != 'undefined')
+ this.context = _context;
+
if (typeof _parameters != 'undefined')
{
this.parameters = _parameters;
@@ -187,7 +196,9 @@ egw_json_request.prototype.sendRequest = function(_async, _callback, _sender)
data: request_obj,
dataType: 'json',
type: 'POST',
- success: this.handleResponse});
+ success: this.handleResponse,
+ error: function(_xmlhttp,_err) { alert('Ajax request to '+this.url+'?menuaction='+this.menuaction+' failed: '+_err); }
+ });
}
egw_json_request.prototype.alertFunc = function(_message, _details)
@@ -195,14 +206,24 @@ egw_json_request.prototype.alertFunc = function(_message, _details)
alert(_message);
}
-function _egw_json_debug_log(_msg)
+function _egw_json_debug_log(_msg, _e)
{
if (typeof console != "undefined" && typeof console.log != "undefined")
{
- console.log(_msg);
+ console.log(_msg, _e);
}
}
+/* Displays an json error message */
+egw_json_request.prototype.jsonError = function(_msg, _e)
+{
+ var msg = 'EGW JSON Error: '._msg;
+
+ //Log and show the error message
+ _egw_json_bebug_log(msg, _e);
+ this.alertHandler(msg);
+}
+
/* Internal function which handles the response from the server */
egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRequest)
{
@@ -211,93 +232,152 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
var hasResponse = false;
for (var i = 0; i < data.response.length; i++)
{
- var res = data.response[i];
-
- switch (data.response[i].type)
+ try
{
- case 'alert':
- //Check whether all needed parameters have been passed and call the alertHandler function
- if ((typeof res.data.message != 'undefined') &&
- (typeof res.data.details != 'undefined'))
- {
- this.alertHandler(
- res.data.message,
- res.data.details)
- hasResponse = true;
- }
- break;
- case 'assign':
- //Check whether all needed parameters have been passed and call the alertHandler function
- if ((typeof res.data.id != 'undefined') &&
- (typeof res.data.key != 'undefined') &&
- (typeof res.data.value != 'undefined'))
- {
- var obj = document.getElementById(res.data.id);
- if (obj)
+ var res = data.response[i];
+
+ switch (data.response[i].type)
+ {
+ case 'alert':
+ //Check whether all needed parameters have been passed and call the alertHandler function
+ if ((typeof res.data.message != 'undefined') &&
+ (typeof res.data.details != 'undefined'))
+ {
+ this.alertHandler(
+ res.data.message,
+ res.data.details)
+ hasResponse = true;
+ } else
+ throw 'Invalid parameters';
+ break;
+ case 'assign':
+ //Check whether all needed parameters have been passed and call the alertHandler function
+ if ((typeof res.data.id != 'undefined') &&
+ (typeof res.data.key != 'undefined') &&
+ (typeof res.data.value != 'undefined'))
+ {
+ var obj = document.getElementById(res.data.id);
+ if (obj)
+ {
+ obj[res.data.key] = res.data.value;
+ hasResponse = true;
+ }
+ } else
+ throw 'Invalid parameters';
+ break;
+ case 'data':
+ //Callback the caller in order to allow him to handle the data
+ if (this.callback)
{
- obj[res.data.key] = res.data.value;
+ this.callback.call(this.sender, res.data);
hasResponse = true;
}
- }
- break;
- case 'data':
- //Callback the caller in order to allow him to handle the data
- if (this.callback)
- {
- this.callback.call(this.sender, res.data);
- hasResponse = true;
- }
- break;
- case 'script':
- if (typeof res.data == 'string')
- {
- try
+ break;
+ case 'script':
+ if (typeof res.data == 'string')
{
- var func = function() {eval(res.data);};
- func.call(window);
- }
- catch (e)
+ try
+ {
+ var func = function() {eval(res.data);};
+ func.call(window);
+ }
+ catch (e)
+ {
+ e.code = res.data;
+ _egw_json_debug_log(e);
+ }
+ hasResponse = true;
+ } else
+ throw 'Invalid parameters';
+ break;
+ case 'jquery':
+ if (typeof res.data.select == 'string' &&
+ typeof res.data.func == 'string')
{
- e.code = res.data;
- _egw_json_debug_log(e);
- }
- hasResponse = true;
- }
- break;
- case 'jquery':
- if (typeof res.data.select == 'string' &&
- typeof res.data.func == 'string')
- {
- try
+ try
+ {
+ var jQueryObject = $(res.data.select, this.context);
+ jQueryObject[res.data.func].apply(jQueryObject, res.data.parms);
+ }
+ catch (e)
+ {
+ _egw_json_debug_log(e);
+ }
+ hasResponse = true;
+ } else
+ throw 'Invalid parameters';
+ break;
+ case 'redirect':
+ if (typeof res.data.url == 'string' &&
+ typeof res.data.global == 'boolean')
{
- var jQueryObject = $(res.data.select);
- jQueryObject[res.data.func].apply(jQueryObject, res.data.parms);
- }
- catch (e)
- {
- _egw_json_debug_log(e);
- }
- hasResponse = true;
- }
- break;
- case 'redirect':
- if (typeof res.data.url == 'string' &&
- typeof res.data.global == 'boolean')
- {
- //Special handling for framework reload
- if (res.data.url.indexOf("?cd=10") > 0)
- res.data.global = true;
+ //Special handling for framework reload
+ if (res.data.url.indexOf("?cd=10") > 0)
+ res.data.global = true;
- if (res.data.global)
+ if (res.data.global)
+ {
+ egw_topWindow().location.href = res.data.url;
+ }
+ else
+ {
+ window.location.href = res.data.url;
+ }
+
+ hasResponse = true;
+ } else
+ throw 'Invalid parameters';
+ break;
+ case 'css':
+ if (typeof res.data == 'string')
{
- egw_topWindow().location.href = res.data.url;
- }
- else
+ //Check whether the requested file had already be included
+ if (!egw_json_files[res.data])
+ {
+ egw_json_files[res.data] = true;
+
+ //Get the head node and append a new link node with the stylesheet url to it
+ var headID = document.getElementsByTagName('head')[0];
+ var cssnode = document.createElement('link');
+ cssnode.type = "text/css";
+ cssnode.rel = "stylesheet";
+ cssnode.href = res.data;
+ headID.appendChild(cssnode);
+ }
+ hasResponse = true;
+ } else
+ throw 'Invalid parameters';
+ break;
+ case 'js':
+ if (typeof res.data == 'string')
{
- window.location.href = res.data.url;
- }
- }
- break;
+ //Check whether the requested file had already be included
+ if (!egw_json_files[res.data])
+ {
+ egw_json_files[res.data] = true;
+
+ //Get the head node and append a new script node with the js file to it
+ var headID = document.getElementsByTagName('head')[0];
+ var scriptnode = document.createElement('script');
+ scriptnode.type = "text/javascript";
+ scriptnode.src = res.data;
+ headID.appendChild(scriptnode);
+ }
+ hasResponse = true;
+ } else
+ throw 'Invalid parameters';
+ break;
+ case 'error':
+ if (typeof res.data == 'string')
+ {
+ this.jsonError(res.data);
+ hasResponse = true;
+ } else
+ throw 'Invalid parameters';
+ break;
+ }
+ } catch(e) {
+ this.jsonError('Internal JSON handler error', e);
}
}
diff --git a/phpgwapi/js/jsapi/jsapi.js b/phpgwapi/js/jsapi/jsapi.js
index bfc3505515..b5d845eb9c 100644
--- a/phpgwapi/js/jsapi/jsapi.js
+++ b/phpgwapi/js/jsapi/jsapi.js
@@ -39,19 +39,53 @@ else if (document.layers)
is_ns4 = true;
}
+/**
+ * Seperates all script tags from the given html code and returns the seperately
+ * @param object _html object that the html code from which the script should be seperated. The html code has to be stored in _html.html, the result js will be written to _html.js
+ */
+
+egw_seperateJavaScript = function(_html)
+{
+ var html = _html.html;
+
+ var in_pos = html.search(/ tag */
+ var js_str = html.substring(in_pos, out_pos+9);
+
+ /*Remove the initial tag */
+ /*js_str = js_str.substring(js_str.search(/>/) + 1);*/
+ _html.js += js_str;
+
+
+ html = html.substring(0, in_pos) + html.substring(out_pos + 9);
+
+ var in_pos = html.search(/