Adjust order of error output
[misc/kostenrechnung] / lib / rico / ricoLiveGridJSON.js
1 /*
2  *  Rico.Buffer.AjaxJSON
3  *
4  *  JSON handling code for the Rico Live Grid written by
5  *  Jeremy Green.  Adapted from code by Richard Cowin
6  *  and Matt Brown.
7  *
8  *  (c) 2005-2009 Richard Cowin (http://openrico.org)
9  *  (c) 2005-2009 Matt Brown (http://dowdybrown.com)
10  *  (c) 2008-2009 Jeremy Green (http://www.webEprint.com)
11  *
12  *  Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
13  *  file except in compliance with the License. You may obtain a copy of the License at
14  *
15  *         http://www.apache.org/licenses/LICENSE-2.0
16  *
17  *  Unless required by applicable law or agreed to in writing, software distributed under the
18  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
19  *  either express or implied. See the License for the specific language governing permissions
20  *  and limitations under the License.
21  */
22
23
24 Rico.Buffer.AjaxJSON = Class.create(
25 /** @lends Rico.Buffer.AjaxJSON# */
26 {
27 /**
28  * @class Implements a LiveGrid buffer that can make
29   *  AJAX calls to the server and process responses in
30   *  JSON format.  Extended from Rico.Buffer.AjaxSQL.
31   *
32   *  @example
33   *  Data format:
34   *  The data consumed by this buffer should be a JavaScript
35   *  hash type object.  The format closely follows the XML based
36   *  data consumed by the Rico.Buffer.AjaxSQL buffer.
37   *
38   *  {
39   *  "update_ui":true,
40   *  "offset":0,
41   *  "rowCount":20,
42   *  "rows":[
43   *     ["1","Bob"],
44   *     ["2","Bill"]
45   *   ]
46   *  }
47   *
48   *  The 'rows' value object of the data object is
49   *  a normal JS Array with each element also being an array.
50   *
51   *
52   *  @example
53   *  Example Usage:
54   *  buffer=new Rico.Buffer.AjaxJSON(jsonUrl, bufferopts);
55   *
56   *  jsonUrl should return a string in the above format.  It will
57   *  be parsed into JS objects.
58   *
59  * @extends Rico.Buffer.AjaxSQL
60  * @constructs
61  */
62 initialize: function(url,options,ajaxOptions) {
63   Object.extend(this, new Rico.Buffer.AjaxSQL());
64   Object.extend(this, new Rico.Buffer.AjaxJSONMethods());
65   this.dataSource=url;
66   Object.extend(this.options, options || {});
67   Object.extend(this.ajaxOptions, ajaxOptions || {});
68 }
69
70 });
71
72
73
74 Rico.Buffer.AjaxJSONMethods = function() {};
75
76 Rico.Buffer.AjaxJSONMethods.prototype = {
77 /** @lends Rico.Buffer.AjaxJSON# */
78
79 processResponse: function(startPos,request) {
80   var json = request.responseText.evalJSON(true);
81   if (!json || json == null) {
82     Rico.writeDebugMsg("jsonAjaxUpdate: json conversion failed");
83     return false;
84   }
85
86   if (json.debug) {
87     for (var i=0; i<json.debug.length; i++)
88       Rico.writeDebugMsg("debug msg "+i+": "+json.debug[i]);
89   }
90   if (json.error) {
91     alert("Data provider returned an error:\n"+json.error);
92     Rico.writeDebugMsg("Data provider returned an error:\n"+json.error);
93     return false;
94   }
95
96   this.rcvdRows = 0;
97   var newRows = this.loadRows(json);
98   if (newRows==null) return false;
99   this.rcvdRows = newRows.length;
100
101   this.updateBuffer(startPos, newRows);
102   return true;
103 },
104
105 loadRows: function(json) {
106   Rico.writeDebugMsg("loadRows");
107   json = $H(json);
108   this.rcvdRowCount = false;
109   var rowsElement = json.get("rows");
110   var rowcnt = json.get("rowCount");
111
112   if (rowcnt) {
113     this.rowcntContent = rowcnt;
114     this.rcvdRowCount = true;
115     this.foundRowCount = true;
116     Rico.writeDebugMsg("loadRows, found RowCount="+this.rowcntContent);
117   }
118   this.updateUI = json.get("update_ui");
119   this.rcvdOffset = json.get("offset");
120   Rico.writeDebugMsg("loadRows, rcvdOffset="+this.rcvdOffset);
121   if (this.options.template)
122     return this.template2jsTable(json,this.options.template);
123   else
124     return rowsElement;
125     //return this.json2jsTable(json);
126 },
127
128 json2jsTable: function(json,firstRow) {
129   var newRows = new Array();
130   var trs = json.get("rows");
131   trs = $A(trs);
132   var i = 0;
133   var acceptAttr=this.options.acceptAttr;
134   trs.each(function(rowData){
135     var row = new Array();
136     //var rowData = $H(pair.value);
137     rowData = $H(rowData);
138     var j = 0;
139     rowData.each(function(p2){
140       row[j]={};
141       row[j].content=p2.value;
142       for (var k=0; k<acceptAttr.length; k++)
143         row[j]['_'+acceptAttr[k]]="";
144       j++;
145     });
146     newRows.push( row );
147     i++;
148   });
149   return newRows;
150 },
151
152 template2jsTable: function(json,template){
153   var trs = json.get("rows");
154   trs = $A(trs);
155   var rowsString = '<table>';
156   trs.each(function(rowData){
157     rowsString += template.evaluate(rowData);
158   });
159   rowsString += '</table>';
160   var rowDom = this.string2DOM(rowsString);
161   return this.dom2jstable(rowDom);
162 },
163
164 string2DOM: function(string){
165   var xmlDoc = null;
166   try{ //Internet Explorer
167     xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
168     xmlDoc.async="false";
169     xmlDoc.loadXML(string);
170   } catch(e) {
171     try { //Firefox, Mozilla, Opera, etc.
172       var parser=new DOMParser();
173       xmlDoc=parser.parseFromString(string,"text/xml");
174     } catch(e) {
175       alert(e.message);
176     }
177   }
178   var el = document._importNode(xmlDoc.childNodes[0],true);
179   return el;
180 }
181
182 };
183
184 Rico.includeLoaded('ricoLiveGridJSON.js');