Rename mask parameter into source
[misc/kostenrechnung] / lib / rico / ricoLiveGridControls.js
1 /*
2  *  (c) 2005-2009 Richard Cowin (http://openrico.org)
3  *  (c) 2005-2009 Matt Brown (http://dowdybrown.com)
4  *
5  *  Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6  *  file except in compliance with the License. You may obtain a copy of the License at
7  *
8  *         http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software distributed under the
11  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
12  *  either express or implied. See the License for the specific language governing permissions
13  *  and limitations under the License.
14  */
15
16 // -----------------------------------------------------
17 //
18 // Custom formatting for LiveGrid columns
19 //
20 // columnSpecs Usage: { type:'control', control:new Rico.TableColumn.CONTROLNAME() }
21 //
22 // -----------------------------------------------------
23
24
25 Rico.TableColumn.checkboxKey = Class.create(
26 /** @lends Rico.TableColumn.checkboxKey# */
27 {
28 /**
29  * @class Custom formatting for a LiveGrid column.
30  * Display unique key column as: <checkbox> <key value>
31  * and keep track of which keys the user selects
32  * Key values should not contain <, >, or &
33  * @constructs
34  */
35   initialize: function(showKey) {
36     this._checkboxes=[];
37     this._spans=[];
38     this._KeyHash=$H();
39     this._showKey=showKey;
40   },
41
42   _create: function(gridCell,windowRow) {
43     this._checkboxes[windowRow]=RicoUtil.createFormField(gridCell,'input','checkbox',this.liveGrid.tableId+'_chkbox_'+this.index+'_'+windowRow);
44     this._spans[windowRow]=RicoUtil.createFormField(gridCell,'span',null,this.liveGrid.tableId+'_desc_'+this.index+'_'+windowRow);
45     this._clear(gridCell,windowRow);
46     Event.observe(this._checkboxes[windowRow], "click", this._onclick.bindAsEventListener(this), false);
47   },
48
49   _onclick: function(e) {
50     var elem=Event.element(e);
51     var windowRow=parseInt(elem.id.split(/_/).pop(),10);
52     var v=this.getValue(windowRow);
53     if (elem.checked)
54       this._addChecked(v);
55     else
56       this._remChecked(v);
57   },
58
59   _clear: function(gridCell,windowRow) {
60     var box=this._checkboxes[windowRow];
61     box.checked=false;
62     box.style.display='none';
63     this._spans[windowRow].innerHTML='';
64   },
65
66   _display: function(v,gridCell,windowRow) {
67     var box=this._checkboxes[windowRow];
68     box.style.display='';
69     box.checked=this._KeyHash.get(v);
70     if (this._showKey) this._spans[windowRow].innerHTML=v;
71   },
72
73   _SelectedKeys: function() {
74     return this._KeyHash.keys();
75   },
76
77   _addChecked: function(k){
78     this._KeyHash.set(k,1);
79   },
80
81   _remChecked: function(k){
82     this._KeyHash.unset(k);
83   }
84 });
85
86
87 Rico.TableColumn.checkbox = Class.create(
88 /** @lends Rico.TableColumn.checkbox# */
89 {
90 /**
91  * @class display checkboxes for two-valued column (e.g. yes/no)
92  * @constructs
93  */
94   initialize: function(checkedValue, uncheckedValue, defaultValue, readOnly) {
95     this._checkedValue=checkedValue;
96     this._uncheckedValue=uncheckedValue;
97     this._defaultValue=defaultValue || false;
98     this._readOnly=readOnly || false;
99     this._checkboxes=[];
100   },
101
102   _create: function(gridCell,windowRow) {
103     this._checkboxes[windowRow]=RicoUtil.createFormField(gridCell,'input','checkbox',this.liveGrid.tableId+'_chkbox_'+this.index+'_'+windowRow);
104     this._clear(gridCell,windowRow);
105     if (this._readOnly)
106       this._checkboxes[windowRow].disabled=true;
107     else
108       Event.observe(this._checkboxes[windowRow], "click", this._onclick.bindAsEventListener(this), false);
109   },
110
111   _onclick: function(e) {
112     var elem=Event.element(e);
113     var windowRow=parseInt(elem.id.split(/_/).pop(),10);
114     var newval=elem.checked ? this._checkedValue : this._uncheckedValue;
115     this.setValue(windowRow,newval);
116   },
117
118   _clear: function(gridCell,windowRow) {
119     var box=this._checkboxes[windowRow];
120     box.checked=this._defaultValue;
121     box.style.display='none';
122   },
123
124   _display: function(v,gridCell,windowRow) {
125     var box=this._checkboxes[windowRow];
126     box.style.display='';
127     box.checked=(v==this._checkedValue);
128   }
129
130 });
131
132
133 Rico.TableColumn.textbox = Class.create(
134 /** @lends Rico.TableColumn.textbox# */
135 {
136 /**
137  * @class display value in a text box
138  * @constructs
139  */
140   initialize: function(boxSize, boxMaxLen, readOnly) {
141     this._boxSize=boxSize;
142     this._boxMaxLen=boxMaxLen;
143     this._readOnly=readOnly || false;
144     this._textboxes=[];
145   },
146
147   _create: function(gridCell,windowRow) {
148     var box=RicoUtil.createFormField(gridCell,'input','text',this.liveGrid.tableId+'_txtbox_'+this.index+'_'+windowRow);
149     box.size=this._boxSize;
150     box.maxLength=this._boxMaxLen;
151     this._textboxes[windowRow]=box;
152     this._clear(gridCell,windowRow);
153     if (this._readOnly)
154       box.disabled=true;
155     else
156       Event.observe(box, "change", this._onchange.bindAsEventListener(this), false);
157   },
158
159   _onchange: function(e) {
160     var elem=Event.element(e);
161     var windowRow=parseInt(elem.id.split(/_/).pop(),10);
162     this.setValue(windowRow,elem.value);
163   },
164
165   _clear: function(gridCell,windowRow) {
166     var box=this._textboxes[windowRow];
167     box.value='';
168     box.style.display='none';
169   },
170
171   _display: function(v,gridCell,windowRow) {
172     var box=this._textboxes[windowRow];
173     box.style.display='';
174     box.value=v;
175   }
176
177 });
178
179
180 Rico.TableColumn.HighlightCell = Class.create(
181 /** @lends Rico.TableColumn.HighlightCell# */
182 {
183 /**
184  * @class highlight a grid cell when a particular value is present in the specified column
185  * @constructs
186  */
187   initialize: function(chkcol,chkval,highlightColor,highlightBackground,chkop) {
188     this._chkcol=chkcol;
189     this._chkval=chkval;
190     this._chkop=chkop;
191     this._highlightColor=highlightColor;
192     this._highlightBackground=highlightBackground;
193   },
194
195   _clear: function(gridCell,windowRow) {
196     gridCell.style.color='';
197     gridCell.style.backgroundColor='';
198     gridCell.innerHTML=' ';
199   },
200
201   _display: function(v,gridCell,windowRow) {
202     var gridval=this.liveGrid.buffer.getWindowValue(windowRow,this._chkcol);
203     var match;
204     switch(this._chkop){
205         case '!=':
206           match=(gridval!=this._chkval);
207           break;
208         case '>':
209           match=(gridval>this._chkval);
210           break;
211         case '<':
212           match=(gridval<this._chkval);
213           break;
214         case '>=':
215           match=(gridval>=this._chkval);
216           break;
217         case '<=':
218           match=(gridval<=this._chkval);
219           break;
220         default:
221           match=(gridval==this._chkval);
222           break;
223     }
224     gridCell.style.color=match ? this._highlightColor : '';
225     gridCell.style.backgroundColor=match ? this._highlightBackground : '';
226     gridCell.innerHTML=this._format(v);
227   }
228 });
229
230
231 Rico.TableColumn.bgColor = Class.create(
232 /** @lends Rico.TableColumn.bgColor# */
233 {
234 /**
235  * @class database value contains a css color name/value
236  * @constructs
237  */
238   initialize: function() {
239   },
240
241   _clear: function(gridCell,windowRow) {
242     gridCell.style.backgroundColor='';
243   },
244
245   _display: function(v,gridCell,windowRow) {
246     gridCell.style.backgroundColor=v;
247   }
248
249 });
250
251
252 Rico.TableColumn.link = Class.create(
253 /** @lends Rico.TableColumn.link# */
254 {
255 /**
256  * @class database value contains a url to another page
257  * @constructs
258  */
259   initialize: function(href,target) {
260     this._href=href;
261     this._target=target;
262     this._anchors=[];
263   },
264
265   _create: function(gridCell,windowRow) {
266     this._anchors[windowRow]=RicoUtil.createFormField(gridCell,'a',null,this.liveGrid.tableId+'_a_'+this.index+'_'+windowRow);
267     if (this._target) this._anchors[windowRow].target=this._target;
268     this._clear(gridCell,windowRow);
269   },
270
271   _clear: function(gridCell,windowRow) {
272     this._anchors[windowRow].href='';
273     this._anchors[windowRow].innerHTML='';
274   },
275
276   _display: function(v,gridCell,windowRow) {
277     this._anchors[windowRow].innerHTML=v;
278     var getWindowValue=this.liveGrid.buffer.getWindowValue.bind(this.liveGrid.buffer);
279     this._anchors[windowRow].href=this._href.replace(/\{\d+\}/g,
280       function ($1) {
281         var colIdx=parseInt($1.substr(1),10);
282         return getWindowValue(windowRow,colIdx);
283       }
284     );
285   }
286
287 });
288
289
290 Rico.TableColumn.image = Class.create(
291 /** @lends Rico.TableColumn.image# */
292 {
293 /**
294  * @class database value contains a url to an image
295  * @constructs
296  */
297   initialize: function() {
298     this._img=[];
299   },
300
301   _create: function(gridCell,windowRow) {
302     this._img[windowRow]=RicoUtil.createFormField(gridCell,'img',null,this.liveGrid.tableId+'_img_'+this.index+'_'+windowRow);
303     this._clear(gridCell,windowRow);
304   },
305
306   _clear: function(gridCell,windowRow) {
307     var img=this._img[windowRow];
308     img.style.display='none';
309     img.src='';
310   },
311
312   _display: function(v,gridCell,windowRow) {
313     var img=this._img[windowRow];
314     this._img[windowRow].src=v;
315     img.style.display='';
316   }
317
318 });
319
320
321 Rico.TableColumn.lookup = Class.create(
322 /** @lends Rico.TableColumn.lookup# */
323 {
324 /**
325  * @class map a database value to a display value
326  * @constructs
327  */
328   initialize: function(map, defaultCode, defaultDesc) {
329     this._map=map;
330     this._defaultCode=defaultCode || '';
331     this._defaultDesc=defaultDesc || '&nbsp;';
332     this._sortfunc=this._sortvalue.bind(this);
333     this._codes=[];
334     this._descriptions=[];
335   },
336
337   _create: function(gridCell,windowRow) {
338     this._descriptions[windowRow]=RicoUtil.createFormField(gridCell,'span',null,this.liveGrid.tableId+'_desc_'+this.index+'_'+windowRow);
339     this._codes[windowRow]=RicoUtil.createFormField(gridCell,'input','hidden',this.liveGrid.tableId+'_code_'+this.index+'_'+windowRow);
340     this._clear(gridCell,windowRow);
341   },
342
343   _clear: function(gridCell,windowRow) {
344     this._codes[windowRow].value=this._defaultCode;
345     this._descriptions[windowRow].innerHTML=this._defaultDesc;
346   },
347
348   _sortvalue: function(v) {
349     return this._getdesc(v).replace(/&amp;/g, '&').replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&nbsp;/g,' ');
350   },
351
352   _getdesc: function(v) {
353     var desc=this._map[v];
354     return (typeof desc=='string') ? desc : this._defaultDesc;
355   },
356
357   _export: function(v) {
358     return this._getdesc(v);
359   },
360
361   _display: function(v,gridCell,windowRow) {
362     this._codes[windowRow].value=v;
363     this._descriptions[windowRow].innerHTML=this._getdesc(v);
364   }
365
366 });
367
368
369
370 Rico.TableColumn.MultiLine = Class.create(
371 /** @lends Rico.TableColumn.MultiLine# */
372 {
373 /**
374  * @class Fix issues with multiline content in IE
375  * @constructs
376  */
377   initialize: function() {
378   },
379
380   _display: function(v,gridCell,windowRow) {
381     var newdiv = document.createElement("div");
382     newdiv.innerHTML = this._format(v);
383     newdiv.style.height='100%';
384     if (gridCell.firstChild)
385       gridCell.replaceChild(newdiv, gridCell.firstChild);
386     else
387       gridCell.appendChild(newdiv);
388   }
389
390 });
391
392 Rico.includeLoaded('ricoLiveGridControls.js');