Handle save request as insert when there is no ID
[misc/kostenrechnung] / lib / rico / ricoAjaxEngine.js
1 // This file is provided for backward compatibility with Rico 1.1.
2 // It is not used by any other module in Rico 2.x. Furthermore, it is 
3 // recommended that you call Prototype's AJAX functions directly
4 // instead of using these functions. It will likely be removed in a
5 // future release.
6
7 Rico.AjaxEngine = Class.create();
8
9 Rico.AjaxEngine.prototype = {
10
11    initialize: function() {
12       this.ajaxElements = new Array();
13       this.ajaxObjects  = new Array();
14       this.requestURLS  = new Array();
15       this.options = {};
16    },
17
18    registerAjaxElement: function( anId, anElement ) {
19       if ( !anElement )
20          anElement = $(anId);
21       this.ajaxElements[anId] = anElement;
22    },
23
24    registerAjaxObject: function( anId, anObject ) {
25       this.ajaxObjects[anId] = anObject;
26    },
27
28    registerRequest: function (requestLogicalName, requestURL) {
29       this.requestURLS[requestLogicalName] = requestURL;
30    },
31
32    sendRequest: function(requestName, options) {
33       // Allow for backwards Compatibility
34       if ( arguments.length >= 2 )
35        if (typeof arguments[1] == 'string')
36          options = {parameters: this._createQueryString(arguments, 1)};
37       this.sendRequestWithData(requestName, null, options);
38    },
39
40    sendRequestWithData: function(requestName, xmlDocument, options) {
41       var requestURL = this.requestURLS[requestName];
42       if ( requestURL == null )
43          return;
44
45       // Allow for backwards Compatibility
46       if ( arguments.length >= 3 )
47         if (typeof arguments[2] == 'string')
48           options.parameters = this._createQueryString(arguments, 2);
49
50       new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument));
51    },
52
53    sendRequestAndUpdate: function(requestName,container,options) {
54       // Allow for backwards Compatibility
55       if ( arguments.length >= 3 )
56         if (typeof arguments[2] == 'string')
57           options.parameters = this._createQueryString(arguments, 2);
58
59       this.sendRequestWithDataAndUpdate(requestName, null, container, options);
60    },
61
62    sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
63       var requestURL = this.requestURLS[requestName];
64       if ( requestURL == null )
65          return;
66
67       // Allow for backwards Compatibility
68       if ( arguments.length >= 4 )
69         if (typeof arguments[3] == 'string')
70           options.parameters = this._createQueryString(arguments, 3);
71
72       var updaterOptions = this._requestOptions(options,xmlDocument);
73
74       new Ajax.Updater(container, requestURL, updaterOptions);
75    },
76
77    // Private -- not part of intended engine API --------------------------------------------------------------------
78
79    _requestOptions: function(options,xmlDoc) {
80       var requestHeaders = ['X-Rico-Version', Rico.Version ];
81       var sendMethod = 'post';
82       if ( xmlDoc == null )
83         if (Rico.prototypeVersion < 1.4)
84         requestHeaders.push( 'Content-type', 'text/xml' );
85       else
86           sendMethod = 'get';
87       (!options) ? options = {} : '';
88
89       if (!options._RicoOptionsProcessed){
90       // Check and keep any user onComplete functions
91         if (options.onComplete)
92              options.onRicoComplete = options.onComplete;
93         // Fix onComplete
94         if (options.overrideOnComplete)
95           options.onComplete = options.overrideOnComplete;
96         else
97           options.onComplete = this._onRequestComplete.bind(this);
98         options._RicoOptionsProcessed = true;
99       }
100
101      // Set the default options and extend with any user options
102      this.options = {
103                      requestHeaders: requestHeaders,
104                      parameters:     options.parameters,
105                      postBody:       xmlDoc,
106                      method:         sendMethod,
107                      onComplete:     options.onComplete
108                     };
109      // Set any user options:
110      Object.extend(this.options, options);
111      return this.options;
112    },
113
114    _createQueryString: function( theArgs, offset ) {
115       var queryString = ""
116       for ( var i = offset ; i < theArgs.length ; i++ ) {
117           if ( i != offset )
118             queryString += "&";
119
120           var anArg = theArgs[i];
121
122           if ( anArg.name != undefined && anArg.value != undefined ) {
123             queryString += anArg.name +  "=" + escape(anArg.value);
124           }
125           else {
126              var ePos  = anArg.indexOf('=');
127              var argName  = anArg.substring( 0, ePos );
128              var argValue = anArg.substring( ePos + 1 );
129              queryString += argName + "=" + escape(argValue);
130           }
131       }
132       return queryString;
133    },
134
135    _onRequestComplete : function(request) {
136       if(!request)
137           return;
138       // User can set an onFailure option - which will be called by prototype
139       if (request.status != 200)
140         return;
141
142       var response = request.responseXML.getElementsByTagName("ajax-response");
143       if (response == null || response.length != 1)
144          return;
145       this._processAjaxResponse( response[0].childNodes );
146       
147       // Check if user has set a onComplete function
148       var onRicoComplete = this.options.onRicoComplete;
149       if (onRicoComplete != null)
150           onRicoComplete();
151    },
152
153    _processAjaxResponse: function( xmlResponseElements ) {
154       for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
155          var responseElement = xmlResponseElements[i];
156
157          // only process nodes of type element.....
158          if ( responseElement.nodeType != 1 )
159             continue;
160
161          var responseType = responseElement.getAttribute("type");
162          var responseId   = responseElement.getAttribute("id");
163
164          if ( responseType == "object" )
165             this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
166          else if ( responseType == "element" )
167             this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
168          else
169             alert('unrecognized AjaxResponse type : ' + responseType );
170       }
171    },
172
173    _processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
174       ajaxObject.ajaxUpdate( responseElement );
175    },
176
177    _processAjaxElementUpdate: function( ajaxElement, responseElement ) {
178       ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
179    }
180
181 }
182
183 var ajaxEngine = new Rico.AjaxEngine();