Support arbitrary callback queries
[misc/kostenrechnung] / lib / functions.js
1 /*
2  * Small AJAX framework
3  */
4 function ajax_request_callback(req)
5 {
6     if (req.readyState == 4 && req.status == 200) {
7         var data = json_parse(req.responseText);
8
9         if (typeof data.error == 'string') {
10             if (typeof data.errormsg == 'string')
11                 error(data.errormsg);
12             else
13                 error('Fehler im AJAX-Backend');
14             alert("Fehler im AJAX-Backend:\n" + data.error);
15         } else if (req.oncomplete)
16             req.oncomplete(data);
17     }
18 }
19
20 function ajax_request(func,params,oncomplete)
21 {
22     var req = new XMLHttpRequest();
23     if (!req) return;
24
25     var params = 'func=' + func + '&' + params;
26     req.open ("POST", 'ajax/ajax.php');
27     req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
28     req.setRequestHeader("Content-length", params.length);
29     req.setRequestHeader("Connection", "close");
30     req.onreadystatechange = function() { ajax_request_callback(req); }
31     if (typeof oncomplete == 'function')
32         req.oncomplete = oncomplete;
33     req.send(params);
34     info('');
35 }
36
37 function info(msg)
38 {
39     var status = document.getElementById('status');
40     if (!status) return;
41
42     status.innerHTML = msg;
43     status.className = 'status_ok';
44 }
45
46 function error(msg)
47 {
48     var status = document.getElementById('status');
49     if (!status) return;
50
51     status.innerHTML = msg;
52     status.className = 'status_error';
53 }
54
55 function set_value(id, value)
56 {
57     var obj = document.getElementById(id);
58     if (!obj) return;
59
60     if (obj.nodeName.toLowerCase() == 'input'
61         && obj.type.toLowerCase() == 'checkbox')
62         if (value) obj.checked = true;
63         else obj.checked = false;
64     else if (obj.nodeName.toLowerCase() == 'input'
65         || obj.nodeName.toLowerCase() == 'textarea')
66         obj.value = value;
67     else if (obj.nodeName.toLowerCase() == 'span')
68         obj.innerHTML = value;
69     else if (obj.nodeName.toLowerCase() == 'select')
70         for (var i=0; i < obj.options.length; i++)
71             if (obj.options[i].value == value)
72                 obj.selectedIndex = i;
73 }
74
75 function setvar(obj, name, callback, status)
76 {
77     if (!obj.options[obj.selectedIndex].value.length)
78         value = -1;
79     else
80         value = obj.options[obj.selectedIndex].value;
81
82     var source = document.getElementById('source');
83
84     if (!source) return false;
85
86     var parms = 'source=' + source.innerHTML + '&name=' + name + '&value=' + value;
87
88     ajax_request('setvar', parms, callback);
89
90     if (typeof status == 'function')
91         status(obj,value,obj.options[obj.selectedIndex].innerHTML);
92 }
93
94 function get_info(name, values, callback)
95 {
96     var source = document.getElementById('source');
97
98     if (!source) return false;
99
100     var parms = 'source=' + source.innerHTML + '&name=' + name;
101     for (key in values)
102         parms += '&' + key + '=' + values[key];
103
104     ajax_request('info', parms, callback);
105 }
106
107 /*
108  * Form functions
109  */
110 function form_init()
111 {
112     var form = document.getElementById('form_edit');
113
114     if (!form) return;
115
116     for (var i=0; i<form.children.length; i++)
117         if (form.children[i].tagName.toLowerCase() == 'input'
118             && form.children[i].type.toLowerCase() == 'password')
119             form.children[i].value = '';
120 }
121
122 function save_callback(data)
123 {
124     info('Datensatz gespeichert');
125     grid_update(grid);
126 }
127
128 function delete_callback(data)
129 {
130     info('Datensatz gelöscht');
131     grid_update(grid);
132 }
133
134 function form_save(obj)
135 {
136     info('');
137     ajax_request('save', Form.serialize(obj.form), save_callback);
138     return false;
139 }
140
141 function form_insert(obj)
142 {
143     info('');
144     ajax_request('insert', Form.serialize(obj.form), save_callback);
145     return false;
146 }
147
148 function form_delete(obj)
149 {
150     var id = document.getElementById('edit_id');
151     var source = document.getElementById('edit_source');
152     info('');
153     var params = 'id='+id.value + '&source='+source.value;
154     ajax_request('delete', params, delete_callback);
155     return false;
156 }
157
158 /*
159  * Table functions
160  */
161 function details_callback(data)
162 {
163     for (var id in data)
164         set_value('detail_'+id, data[id]);
165 }
166
167 function fetch_callback(data)
168 {
169     for (var id in data)
170         set_value('edit_'+id, data[id]);
171
172     var status = document.getElementById('form_status');
173     status.innerHTML = 'Geändert: ' + data.sys_edit + ' von ' + data.sys_user;
174 }
175
176 /*
177  * Rico functions
178  */
179 function gridDrillDown(e)
180 {
181     if (e.originalTarget && e.originalTarget.target && e.originalTarget.target == '_top')
182         return;
183
184     var id = 0; // Column 0 contains ID
185     var row = grid.edit.drillDown(e,0,0);
186     var cell = grid.columns[id].cell(row);
187     if (!cell) return;
188     var value = cell.innerHTML;
189
190     if (document.getElementById('details')) {
191         var params = 'source=' + grid.tableId.substr(5) + '&id=' + value;
192         ajax_request('details', params, details_callback);
193     }
194
195     if (document.getElementById('form_edit')) {
196         var params = 'source=' + grid.tableId.substr(5) + '&id=' + value;
197         ajax_request('fetch', params, fetch_callback);
198     }
199 }
200
201 /* Update an existing grid
202  *
203  * grid is a live grid
204  * filter is the array index of the $table_filters array in mskdef
205  * value is the value applied to the filter
206  */
207 function grid_update(grid, filter, value)
208 {
209     if (grid === undefined)
210         return;
211
212     if (filter !== undefined && filter !== false)
213                 grid.buffer.options.requestParameters = ['w'+filter+'=' + value];
214     grid.buffer.clear();
215     grid.buffer.setTotalRows(0);
216     grid.buffer.foundRowCount = false;
217     grid.cancelMenu();
218     grid.ClearSelection();
219     grid.setImages();
220     if (grid.bookmark) grid.bookmark.innerHTML="&nbsp;";
221     grid.clearRows();
222     grid.buffer.fetch(-1);
223 }
224
225 var calendars = new Array();
226 function calendar_callback(value)
227 {
228     this.input.value = value;
229 }
230
231 function calendar(name,event)
232 {
233     var input = document.getElementById(name);
234     if (!input) return;
235
236     if (calendars[name] == undefined) {
237         calendars[name] = new Rico.CalendarControl('calendar_'+name,
238                                                    {startAt: 1,
239                                                     dateFmt: 'dd.mm.yyyy',
240                                                     showWeekNumber: 1});
241         calendars[name].atLoad();
242         calendars[name].returnValue = calendar_callback;
243         RicoUtil.positionCtlOverIcon(calendars[name].container,input);
244         calendars[name].open(input.value);
245         calendars[name].input = input;
246     } else {
247         if (Element.visible(calendars[name].container))
248             calendars[name].close();
249         else
250             calendars[name].open(input.value);
251     }
252     Event.stop(event);
253 }