return false, also when delete cannot be executed
[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     } else
74         obj.innerHTML = value;
75 }
76
77 function setvar(obj, name, callback, status)
78 {
79     if (!obj.options[obj.selectedIndex].value.length)
80         value = -1;
81     else
82         value = obj.options[obj.selectedIndex].value;
83
84     var source = document.getElementById('source');
85
86     if (!source) return false;
87
88     var parms = 'source=' + source.innerHTML + '&name=' + name + '&value=' + value;
89
90     ajax_request('setvar', parms, callback);
91
92     if (typeof status == 'function')
93         status(obj,value,obj.options[obj.selectedIndex].innerHTML);
94 }
95
96 function get_info(name, values, callback)
97 {
98     var source = document.getElementById('source');
99
100     if (!source) return false;
101
102     var parms = 'source=' + source.innerHTML + '&name=' + name;
103     for (key in values)
104         parms += '&' + key + '=' + values[key];
105
106     ajax_request('info', parms, callback);
107 }
108
109 /*
110  * Form functions
111  */
112 function form_init()
113 {
114     var form = document.getElementById('form_edit');
115
116     if (!form) return;
117
118     for (var i=0; i < form.childNodes.length; i++)
119         if (form.childNodes[i].nodeName.toLowerCase() == 'input'
120             && form.childNodes[i].type.toLowerCase() == 'password')
121             form.childNodes[i].value = '';
122 }
123
124 function select_update(id, options, empty)
125 {
126     var obj = document.getElementById(id);
127     if (!obj) return;
128
129     if (typeof empty == 'undefined') empty = 0;
130
131     obj.options.length = empty;
132
133     for (var i=0; i < options.length; i++)
134       obj.options[empty+i] = new Option(options[i].text,options[i].id,false,false);
135 }
136
137 var pre_save = false;
138 var pre_insert = false;
139 var post_save = function() { grid_update(grid); }
140 var post_delete = function() { grid_update(grid); }
141
142 function save_callback(data)
143 {
144     info('Datensatz gespeichert');
145
146     if (typeof post_save == 'function')
147         post_save();
148 }
149
150 function delete_callback(data)
151 {
152     info('Datensatz gelöscht');
153
154     if (typeof post_delete == 'function')
155         post_delete();
156 }
157
158 function form_save(obj)
159 {
160     var id = document.getElementById('edit_id');
161
162     if (!id.value.length)
163         return form_insert(obj);
164
165     info('');
166
167     if (typeof pre_save == 'function')
168         if (!pre_save())
169             return false;
170
171
172     ajax_request('save', Form.serialize(obj.form), save_callback);
173     return false;
174 }
175
176 function form_insert(obj)
177 {
178     info('');
179
180     if (typeof pre_insert == 'function')
181         if (!pre_insert())
182             return false;
183
184     ajax_request('insert', Form.serialize(obj.form), save_callback);
185     return false;
186 }
187
188 function form_delete(obj)
189 {
190     var id = document.getElementById('edit_id');
191
192     if (!id.value.length) return false;
193
194     var source = document.getElementById('edit_source');
195     info('');
196     var params = 'id='+id.value + '&source='+source.value;
197     ajax_request('delete', params, delete_callback);
198     return false;
199 }
200
201 /*
202  * Table functions
203  */
204 function details_callback(data)
205 {
206     for (var id in data)
207         set_value('detail_'+id, data[id]);
208 }
209
210 function fetch_callback(data)
211 {
212     for (var id in data)
213         set_value('edit_'+id, data[id]);
214
215     var status = document.getElementById('form_status');
216     status.innerHTML = 'Geändert: ' + data.sys_edit + ' von ' + data.sys_user;
217 }
218
219 /*
220  * Rico functions
221  */
222 function gridDrillDown(e)
223 {
224     if (e.originalTarget && e.originalTarget.target && e.originalTarget.target == '_top')
225         return;
226
227     var id = 0; // Column 0 contains ID
228     var row = grid.edit.drillDown(e,0,0);
229     var cell = grid.columns[id].cell(row);
230     if (!cell) return;
231     var value = cell.innerHTML;
232
233     if (!value.length || value == '&nbsp;') return;
234
235     if (document.getElementById('details')) {
236         var params = 'source=' + grid.tableId.substr(5) + '&id=' + value;
237         ajax_request('details', params, details_callback);
238     }
239
240     if (document.getElementById('form_edit')) {
241         var params = 'source=' + grid.tableId.substr(5) + '&id=' + value;
242         ajax_request('fetch', params, fetch_callback);
243     }
244 }
245
246 function gridOnScroll(grid, offset)
247 {
248     var max = Math.min(offset+grid.pageSize, grid.buffer.totalRows);
249     var info = document.getElementById('grid_info')
250     info.innerHTML = 'Datensatz ' + (offset+1) + ' - ' + max + ' von ' + grid.buffer.totalRows;
251 }
252
253 /* Update an existing grid
254  *
255  * grid is a live grid
256  * filter is the array index of the $table_filters array in mskdef
257  * value is the value applied to the filter
258  */
259 function grid_update(grid, filter, value)
260 {
261     if (grid === undefined)
262         return;
263
264     if (filter !== undefined && filter !== false)
265                 grid.buffer.options.requestParameters = ['w'+filter+'=' + value];
266     grid.buffer.clear();
267     grid.buffer.setTotalRows(0);
268     grid.buffer.foundRowCount = false;
269     grid.cancelMenu();
270     grid.ClearSelection();
271     grid.setImages();
272     if (grid.bookmark) grid.bookmark.innerHTML="&nbsp;";
273     grid.clearRows();
274     grid.buffer.fetch(-1);
275 }
276
277 function grid_update_filters(grid)
278 {
279     var todo = false;
280     for (var c=0; c < grid.headerColCnt; c++) {
281         var fmt = grid.columns[c].format;
282         if (typeof fmt.filterUI != 'string') continue;
283         if (fmt.filterUI != 's') continue;
284         $(grid.filterId(c)).options.length = 1;
285
286         var options = {};
287         Object.extend(options, grid.buffer.ajaxOptions);
288         var colnum = typeof(fmt.filterCol)=='number' ? fmt.filterCol : c;
289
290         options.parameters = 'id='+grid.tableId+'&distinct='+colnum;
291         options.onComplete = grid.filterValuesUpdate.bind(grid,c);
292         new Ajax.Request(grid.buffer.dataSource, options);
293     }
294 }
295
296 var calendars = new Array();
297 function calendar_callback(value)
298 {
299     this.input.value = value;
300 }
301
302 function calendar(name,event)
303 {
304     var input = document.getElementById(name);
305     if (!input) return;
306
307     if (calendars[name] == undefined) {
308         calendars[name] = new Rico.CalendarControl('calendar_'+name,
309                                                    {startAt: 1,
310                                                     dateFmt: 'dd.mm.yyyy',
311                                                     showWeekNumber: 1});
312         calendars[name].atLoad();
313         calendars[name].returnValue = calendar_callback;
314         RicoUtil.positionCtlOverIcon(calendars[name].container,input);
315         calendars[name].open(input.value);
316         calendars[name].input = input;
317     } else {
318         if (Element.visible(calendars[name].container))
319             calendars[name].close();
320         else
321             calendars[name].open(input.value);
322     }
323     Event.stop(event);
324 }