diff --git a/include/js/jqSOAPClient.js b/include/js/jqSOAPClient.js
new file mode 100644
index 000000000..971dd275c
--- /dev/null
+++ b/include/js/jqSOAPClient.js
@@ -0,0 +1,159 @@
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+//Singleton SOAP Client
+var SOAPClient = {
+ Proxy: "",
+ SOAPServer: "",
+ ContentType: "text/xml",
+ CharSet: "utf-8",
+ ResponseXML: null,
+ ResponseText: "",
+ Status: 0,
+ ContentLength: 0,
+ Namespace: function(name, uri) {
+ return {"name":name, "uri":uri};
+ },
+ SendRequest: function(soapReq, callback) {
+ if(!!SOAPClient.Proxy) {
+ SOAPClient.ResponseText = "";
+ SOAPClient.ResponseXML = null;
+ SOAPClient.Status = 0;
+
+ var content = soapReq.toString();
+ SOAPClient.ContentLength = content.length;
+
+ function getResponse(xData) {
+ if(!!callback) {
+ SOAPClient.Status = xData.status;
+ SOAPClient.ResponseText = xData.responseText;
+ SOAPClient.ResponseXML = xData.responseXML;
+ var jsOut = $.xmlToJSON(xData.responseXML);
+ callback(jsOut);
+ }
+ }
+ $.ajax({
+ type: "POST",
+ url: SOAPClient.Proxy,
+ dataType: "xml",
+ processData: false,
+ data: content,
+ complete: getResponse,
+ contentType: SOAPClient.ContentType + "; charset=\"" + SOAPClient.CharSet + "\"",
+ beforeSend: function(req) {
+ req.setRequestHeader("Method", "POST");
+ req.setRequestHeader("Content-Length", SOAPClient.ContentLength);
+ req.setRequestHeader("SOAPServer", SOAPClient.SOAPServer);
+ req.setRequestHeader("SOAPAction", soapReq.Action);
+ }
+ });
+ }
+ },
+ ToXML: function(soapObj) {
+ var out = [];
+ var isNSObj=false;
+ try {
+ if(!!soapObj&&typeof(soapObj)==="object"&&soapObj.typeOf==="SOAPObject") {
+ //Namespaces
+ if(!!soapObj.ns) {
+ if(typeof(soapObj.ns)==="object") {
+ isNSObj=true;
+ out.push("<"+soapObj.ns.name+":"+soapObj.name);
+ out.push(" xmlns:"+soapObj.ns.name+"=\""+soapObj.ns.uri+"\"");
+ } else {
+ out.push("<"+soapObj.name);
+ out.push(" xmlns=\""+soapObj.ns+"\"");
+ }
+ } else {
+ out.push("<"+soapObj.name);
+ }
+ //Node Attributes
+ if(soapObj.attributes.length > 0) {
+ var cAttr;
+ var aLen=soapObj.attributes.length-1;
+ do {
+ cAttr=soapObj.attributes[aLen];
+ if(isNSObj) {
+ out.push(" "+soapObj.ns.name+":"+cAttr.name+"=\""+cAttr.value+"\"");
+ } else {
+ out.push(" "+cAttr.name+"=\""+cAttr.value+"\"");
+ }
+ } while(aLen--);
+ }
+ out.push(">");
+ //Node children
+ if(soapObj.hasChildren()) {
+ var cPos, cObj;
+ for(cPos in soapObj.children){
+ cObj = soapObj.children[cPos];
+ if(typeof(cObj)==="object"){out.push(SOAPClient.ToXML(cObj));}
+ }
+ }
+ //Node Value
+ if(!!soapObj.value){out.push(soapObj.value);}
+ //Close Tag
+ if(isNSObj){out.push(""+soapObj.ns.name+":"+soapObj.name+">");}
+ else {out.push(""+soapObj.name+">");}
+ return out.join("");
+ }
+ } catch(e){alert("Unable to process SOAPObject! Object must be an instance of SOAPObject");}
+ }
+};
+//Soap request - this is what being sent using SOAPClient.SendRequest
+var SOAPRequest=function(action, soapObj) {
+ this.Action=action;
+ var nss=[];
+ var headers=[];
+ var bodies=(!!soapObj)?[soapObj]:[];
+ this.addNamespace=function(ns, uri){nss.push(new SOAPClient.Namespace(ns, uri));};
+ this.addHeader=function(soapObj){headers.push(soapObj);};
+ this.addBody=function(soapObj){bodies.push(soapObj);};
+ this.toString=function() {
+ var soapEnv = new SOAPObject("soapenv:Envelope");
+ soapEnv.attr("xmlns:soapenv","http://schemas.xmlsoap.org/soap/envelope/");
+ //Add Namespace(s)
+ if(nss.length>0){
+ var tNs, tNo;
+ for(tNs in nss){if(!nss.hasOwnProperty || nss.hasOwnProperty(tNs)){tNo=nss[tNs];if(typeof(tNo)==="object"){soapEnv.attr("xmlns:"+tNo.name, tNo.uri);}}}
+ }
+ //Add Header(s)
+ if(headers.length>0) {
+ var soapHeader = soapEnv.appendChild(new SOAPObject("soapenv:Header"));
+ var tHdr;
+ for(tHdr in headers){if(!headers.hasOwnProperty || headers.hasOwnProperty(tHdr)){soapHeader.appendChild(headers[tHdr]);}}
+ }
+ //Add Body(s)
+ if(bodies.length>0) {
+ var soapBody = soapEnv.appendChild(new SOAPObject("soapenv:Body"));
+ var tBdy;
+ for(tBdy in bodies){if(!bodies.hasOwnProperty || bodies.hasOwnProperty(tBdy)){soapBody.appendChild(bodies[tBdy]);}}
+ }
+ return soapEnv.toString();
+ };
+};
+
+//Soap Object - Used to build body envelope and other structures
+var SOAPObject = function(name) {
+ this.typeOf="SOAPObject";
+ this.ns=null;
+ this.name=name;
+ this.attributes=[];
+ this.children=[];
+ this.value=null;
+ this.attr=function(name, value){this.attributes.push({"name":name, "value":value});return this;};
+ this.appendChild=function(obj){this.children.push(obj);return obj;};
+ this.hasChildren=function(){return (this.children.length > 0)?true:false;};
+ this.val=function(v){if(!v){return this.value;}else{this.value=v;return this;}};
+ this.toString=function(){return SOAPClient.ToXML(this);};
+};
\ No newline at end of file
diff --git a/include/js/jqXMLUtils.js b/include/js/jqXMLUtils.js
new file mode 100644
index 000000000..8d92247ee
--- /dev/null
+++ b/include/js/jqXMLUtils.js
@@ -0,0 +1,250 @@
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+(function($) {
+ //Converts XML DOM to JSON
+ $.extend ({
+ xmlToJSON: function(xdoc) {
+ try {
+ if(!xdoc){ return null; }
+ var tmpObj = {};
+ tmpObj.typeOf = "JSXBObject";
+ var xroot = (xdoc.nodeType == 9)?xdoc.documentElement:xdoc;
+ tmpObj.RootName = xroot.nodeName || "";
+ if(xdoc.nodeType == 3 || xdoc.nodeType == 4) {
+ return xdoc.nodeValue;
+ }
+ var isNumeric = function(s) {
+ var testStr = "";
+ if(s && typeof s == "string") { testStr = s; }
+ var pattern = /^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/;
+ return pattern.test(testStr);
+ };
+ //Alters attribute and collection names to comply with JS
+ function formatName(name) {
+ var regEx = /-/g;
+ var tName = String(name).replace(regEx,"_");
+ return tName;
+ }
+ //Set Attributes of an object
+ function setAttributes(obj, node) {
+ if(node.attributes.length > 0) {
+ var a = node.attributes.length-1;
+ var attName;
+ obj._attributes = [];
+ do { //Order is irrelevant (speed-up)
+ attName = String(formatName(node.attributes[a].name));
+ obj._attributes.push(attName);
+ obj[attName] = $.trim(node.attributes[a].value);
+ } while(a--);
+ }
+ }
+ //Set collections
+ function setHelpers(grpObj) {
+ //Selects a node withing array where attribute = value
+ grpObj.getNodeByAttribute = function(attr, obj) {
+ if(this.length > 0) {
+ var cNode;
+ var maxLen = this.length -1;
+ try {
+ do {
+ cNode = this[maxLen];
+ if(cNode[attr] == obj) {
+ return cNode;
+ }
+ } while(maxLen--);
+ } catch(e) {return false;}
+ return false;
+ }
+ };
+
+ grpObj.contains = function(attr, obj) {
+ if(this.length > 0) {
+ var maxLen = this.length -1;
+ try {
+ do {
+ if(this[maxLen][attr] == obj) {
+ return true;
+ }
+ } while(maxLen--);
+ } catch(e) {return false;}
+ return false;
+ }
+ };
+
+ grpObj.indexOf = function(attr, obj) {
+ var pos = -1;
+ if(this.length > 0) {
+ var maxLen = this.length -1;
+ try {
+ do {
+ if(this[maxLen][attr] == obj) {
+ pos = maxLen;
+ }
+ } while(maxLen--);
+ } catch(e) {return -1;}
+ return pos;
+ }
+ };
+
+ grpObj.SortByAttribute = function(col, dir) {
+ if(this.length) {
+ function getValue(pair, idx) {
+ var out = pair[idx];
+ out = (isNumeric(out))?parseFloat(out):out;
+ return out;
+ }
+ function sortFn(a, b) {
+ var res = 0;
+ var tA, tB;
+ tA = getValue(a, col);
+ tB = getValue(b, col);
+ if(tA < tB) { res = -1; } else if(tB < tA) { res = 1; }
+ if(dir) {
+ res = (dir.toUpperCase() == "DESC")?(0 - res):res;
+ }
+ return res;
+ }
+ this.sort(sortFn);
+ }
+ };
+
+ grpObj.SortByValue = function(dir) {
+ if(this.length) {
+ function getValue(pair) {
+ var out = pair.Text;
+ out = (isNumeric(out))?parseFloat(out):out;
+ return out;
+ }
+ function sortFn(a, b) {
+ var res = 0;
+ var tA, tB;
+ tA = getValue(a);
+ tB = getValue(b);
+ if(tA < tB) { res = -1; } else if(tB < tA) { res = 1; }
+ if(dir) {
+ res = (dir.toUpperCase() == "DESC")?(0 - res):res;
+ }
+ return res;
+ }
+ this.sort(sortFn);
+ }
+ };
+ grpObj.SortByNode = function(node, dir) {
+ if(this.length) {
+ function getValue(pair, node) {
+ var out = pair[node][0].Text;
+ out = (isNumeric(out))?parseFloat(out):out;
+ return out;
+ }
+ function sortFn(a, b) {
+ var res = 0;
+ var tA, tB;
+ tA = getValue(a, node);
+ tB = getValue(b, node);
+ if(tA < tB) { res = -1; } else if(tB < tA) { res = 1; }
+ if(dir) {
+ res = (dir.toUpperCase() == "DESC")?(0 - res):res;
+ }
+ return res;
+ }
+ this.sort(sortFn);
+ }
+ };
+ }
+ //Recursive JSON Assembler
+ //Set Object Nodes
+ function setObjects(obj, node) {
+ var elemName; //Element name
+ var cnode; //Current Node
+ var tObj; //New subnode
+ var cName = "";
+ if(!node) { return null; }
+ //Set node attributes if any
+ if(node.attributes.length > 0){setAttributes(obj, node);}
+ obj.Text = "";
+ if(node.hasChildNodes()) {
+ var nodeCount = node.childNodes.length - 1;
+ var n = 0;
+ do { //Order is irrelevant (speed-up)
+ cnode = node.childNodes[n];
+ switch(cnode.nodeType) {
+ case 1: //Node
+ //Process child nodes
+ obj._children = [];
+ //SOAP XML FIX to remove namespaces (i.e. soapenv:)
+ elemName = (cnode.localName)?cnode.localName:cnode.baseName;
+ elemName = formatName(elemName);
+ if(cName != elemName) { obj._children.push(elemName); }
+ //Create sub elemns array
+ if(!obj[elemName]) {
+ obj[elemName] = []; //Create Collection
+ }
+ tObj = {};
+ obj[elemName].push(tObj);
+ if(cnode.attributes.length > 0) {
+ setAttributes(tObj, cnode);
+ }
+ //Set Helper functions (contains, indexOf, sort, etc);
+ if(!obj[elemName].contains) {
+ setHelpers(obj[elemName]);
+ }
+ cName = elemName;
+ if(cnode.hasChildNodes()) {
+ setObjects(tObj, cnode); //Recursive Call
+ }
+ break;
+ case 3: //Text Value
+ obj.Text += $.trim(cnode.nodeValue);
+ break;
+ case 4: //CDATA
+ obj.Text += (cnode.text)?$.trim(cnode.text):$.trim(cnode.nodeValue);
+ break;
+ }
+ } while(n++ < nodeCount);
+ }
+ }
+ //RUN
+ setObjects(tmpObj, xroot);
+ //Clean-up memmory
+ xdoc = null;
+ xroot = null;
+ return tmpObj;
+
+ } catch(e) {
+ return null;
+ }
+ }
+ });
+
+ //Converts Text to XML DOM
+ $.extend({
+ textToXML: function(strXML) {
+ var xmlDoc = null;
+ try {
+ xmlDoc = ($.browser.msie)?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser();
+ xmlDoc.async = false;
+ } catch(e) {throw new Error("XML Parser could not be instantiated");}
+ var out;
+ try {
+ if($.browser.msie) {
+ out = (xmlDoc.loadXML(strXML))?xmlDoc:false;
+ } else {
+ out = xmlDoc.parseFromString(strXML, "text/xml");
+ }
+ } catch(e) { throw new Error("Error parsing XML string"); }
+ return out;
+ }
+ });
+})(jQuery);
\ No newline at end of file
diff --git a/soap/projekt_jquery_client.php b/soap/projekt_jquery_client.php
new file mode 100755
index 000000000..93750c6f5
--- /dev/null
+++ b/soap/projekt_jquery_client.php
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+