376245d52837d9310e175cf4eaa6c20e17b60135
[Evergreen.git] / Evergreen / staff_client / chrome / content / evergreen / util / widgets.js
1 sdump('D_WIDGETS',"Loading widgets.js\n");
2
3 // This was originally used in circ.js for checkin and checkout lists.
4 // The first argument is the treechildren element for the tree.
5 // Subsequent arguments are treated as textual values for treecells in that treeitem.
6 var treeitem_id = 0;
7 function append_treeitem() {
8         sdump('D_WIDGETS',arg_dump(arguments));
9         var d; var e;
10         if (arguments.length == 1) {
11                 e = arguments[0];
12         } else {
13                 d = arguments[0];
14                 e = arguments[1];
15                 if (typeof(e) != 'object') { e = d.getElementById(e); }
16         }
17         if (typeof(e) != 'object') { throw('typeof e != object : typeof e = ' + typeof(e)); }
18         var treechildren = e;
19
20         if (!treechildren) { sdump('D_WIDGETS','No ' + id + ' to append to\n'); return; }
21
22         var treeitem = elem('treeitem'); treechildren.appendChild(treeitem);
23         var treerow = elem('treerow'); treeitem.appendChild(treerow);
24         for (var i = 2; i < arguments.length ; i++ ) {
25                 var treecell = elem(
26                         'treecell',
27                         { 'label': arguments[i], 'id' : 'treeitem_' + treeitem_id + '_' + i }
28                 );
29                 treerow.appendChild(treecell);
30                 //sdump('D_WIDGETS','treecell.label = ' + arguments[i] + '\n');
31         }
32         return treeitem_id++;
33 }
34
35 // This was used in browse_list.js as a more flexible alternative to swap_attribute.
36 // The first argument is the element, the second argument is the pertinant attribute,
37 // and the third argument is an array of values to cycle through for setting the
38 // element's attribute.  Ex: var toggle = cycle_attribute( target,'toggle',['1','2','3'] );
39 function cycle_attribute() {
40         sdump('D_WIDGETS',arg_dump(arguments));
41         var d; var e; var a; var v;
42         if (arguments.length == 3) {
43                 e = arguments[0];
44                 a = arguments[1];
45                 v = arguments[2];
46         } else {
47                 d = arguments[0];
48                 e = arguments[1];
49                 a = arguments[2];
50                 v = arguments[3];
51                 if (typeof(e) != 'object') { e = d.getElementById(e); }
52         }
53         try {
54                 if (typeof(e) != 'object') { throw('typeof e != object : typeof e = ' + typeof(e)); }
55                 if (!a) { throw('!a : a = ' + a); }
56                 if (! e.getAttribute(a) ) { throw(' ! e.getAttribute(a) : a = ' + a); }
57                 if (typeof(v) != 'object') { throw('typeof v != object : typeof v = ' + typeof(v)); }
58
59                 var toggle = e.getAttribute(a);
60                 var next_one = false;
61                 sdump('D_WIDGETS','cycling ' + a + ' on ' + e.getAttribute('id') + ' to ');
62                 for (var i = 0; i < v.length; i++) {
63                         if (next_one) {
64                                 e.setAttribute(a,v[i]);
65                                 sdump('D_WIDGETS',v[i] + '\n');
66                                 return v[i];
67                         }
68                         if (toggle == v[i]) {
69                                 next_one = true;
70                         }
71                 }
72                 if (next_one) {
73                         e.setAttribute(a,v[0]);
74                         sdump('D_WIDGETS',v[0] + '\n');
75                         return v[0];
76                 } else {
77                         throw('current value not in list');
78                 }
79         } catch(E) {
80                 sdump('D_WIDGETS','cycle_attribute error: ' + js2JSON(E) + '\n');
81                 sdump('D_WIDGETS','null\n');
82                 return null;
83         }
84 }
85
86 // Treats each argument as an element to disable 
87 function disable_widgets() {
88         sdump('D_WIDGETS',arg_dump(arguments));
89         var d = document; var idx = 0;
90         if (arguments[0].nodeName == '#document') {
91                 idx = 1; d = arguments[0];
92         }
93         for (var i = idx; i < arguments.length; i++) {
94                 if (typeof(arguments[i]) == 'object') {
95                         sdump('D_WIDGETS',arguments[i] + '.disabled = true;\n');
96                         arguments[i].disabled = true;
97                 } else {
98                         var w = d.getElementById( arguments[i] );
99                         if (w) { 
100                                 sdump('D_WIDGETS',w + '.disabled = true;\n');
101                                 w.disabled = true; 
102                         }
103                 }
104         }
105 }
106
107 // removes listitems from listboxes
108 function empty_listbox() {
109         sdump('D_WIDGETS',arg_dump(arguments));
110         var d; var e;
111         if (arguments.length == 1) {
112                 e = arguments[0];
113         } else {
114                 d = arguments[0];
115                 e = arguments[1];
116                 if (typeof(e) != 'object') { e = d.getElementById(e); }
117         }
118         if (typeof(e) != 'object') { sdump('D_WIDGETS','Failed on empty_listbox\n'); return; }
119         var nl = e.getElementsByTagName('listitem');
120         for (var i = 0; i < nl.length; i++) {
121                 e.removeChild(nl[i]);
122         }
123 }
124
125 // removes all of an element's children
126 function empty_widget() {
127         sdump('D_WIDGETS',arg_dump(arguments));
128         var d; var e;
129         if (arguments.length == 1) {
130                 e = arguments[0];
131         } else {
132                 d = arguments[0];
133                 e = arguments[1];
134                 if (typeof(e) != 'object') { e = d.getElementById(e); }
135         }
136         if (typeof(e) != 'object') { sdump('D_WIDGETS','Failed on empty_widget\n'); return; }
137         while (e.lastChild) { e.removeChild(e.lastChild); }
138 }
139
140
141 // Treats each argument as an element to enable 
142 function enable_widgets() {
143         sdump('D_WIDGETS',arg_dump(arguments));
144         var d = document; var idx = 0;
145         if (arguments[0].nodeName == '#document') {
146                 idx = 1; d = arguments[0];
147         }
148         for (var i = idx; i < arguments.length; i++) {
149                 if (typeof(arguments[i]) == 'object') {
150                         sdump('D_WIDGETS',arguments[i] + '.disabled = false;\n');
151                         arguments[i].disabled = false;
152                 } else {
153                         var w = d.getElementById( arguments[i] );
154                         if (w) { 
155                                 sdump('D_WIDGETS',w + '.disabled = false;\n');
156                                 w.disabled = false; 
157                         }
158                 }
159         }
160 }
161
162 // Originally used in volume.js after intercepting Enter presses on the keyboard.
163 // The first argument is the element to search for textboxes, and the second
164 // argument is the current textbox.  This function finds the next textbox and
165 // gives it focus.
166 function fake_tab_for_textboxes() {
167         sdump('D_WIDGETS',arg_dump(arguments));
168         var d; var w; var current;
169         if (arguments.length == 2) {
170                 w = arguments[0];
171                 current = arguments[1];
172         } else {
173                 d = arguments[0];
174                 w = arguments[1];
175                 current = arguments[2];
176                 if (typeof(w)!='object') { w = d.getElementById(w); }
177         }
178         var flag = false; var next_one;
179         sdump('D_WIDGETS', 'fake_tab_for_textboxes: Current ' + current + '\n');
180         var nl = w.getElementsByTagName('textbox');
181         //var nl = d.getElementsByTagName('textbox');
182         sdump('D_WIDGETS', 'fake_tab_for_textboxes: nl.length = ' + nl.length + '\n');
183         for (var i = 0; i < nl.length; i++) {
184                 sdump('D_WIDGETS', 'fake_tab_for_textboxes: Considering ' + nl[i] + '...\n');
185                 if (flag && !next_one) {
186                         sdump('D_WIDGETS', 'fake_tab_for_textboxes: Setting next_one ' + nl[i] + '\n'); 
187                         next_one = nl[i];
188                 }
189                 if (nl[i] === current) {
190                         sdump('D_WIDGETS','fake_tab_for_textboxes: Found current\n');
191                         flag = true;
192                 }
193         }
194         if (!next_one) {
195                 sdump('D_WIDGETS','fake_tab_for_textboxes: Out of loop, Setting next_one ' + nl[0] + '\n');     
196                 next_one = nl[0];
197         }
198         if (next_one) {
199                 next_one.focus(); next_one.select();
200         } else {
201                 sdump('D_WIDGETS','fake_tab_for_textboxes: next_one not set\n');
202         }
203 }
204
205
206 // Not actually used anywhere.  I'm not sure what this is :D
207 // Ah, looks like it could handle XUL trees and fieldmapper trees
208 // Ex. find( org_tree, function(o){return o.children();}, function(o){return (o.id == 'the winner');})
209 function find_tree_via_children() {
210         sdump('D_WIDGETS',arg_dump(arguments));
211         var d; var tree; var children_func; var find_func;
212         if (arguments.length == 3) {
213                 tree = arguments[0];
214                 children_func = arguments[1];
215                 find_func = arguments[2];
216         } else {
217                 d = arguments[0];
218                 tree = arguments[1];
219                 children_func = arguments[2];
220                 find_func = arguments[3];
221                 if (typeof(tree)!='object') tree = d.getElementById(tree);
222         }
223
224         var t = find_func(tree); if (t) return t;
225
226         var c = children_func(tree);
227
228         for (var i = 0; i < c.length; i++) {
229                 t = find_func( c[i] );
230                 if (t) return t;
231         }
232 }
233
234
235 // Give this element focus
236 function focus_widget() {
237         sdump('D_WIDGETS',arg_dump(arguments));
238         var d = document; var e;
239         if (arguments.length == 1) {
240                 e = arguments[0];
241         } else {
242                 d = arguments[0];
243                 e = arguments[1];
244         }
245         if (typeof(e) == 'object') {
246                 e.focus();
247         } else {
248                 var w = d.getElementById(e);
249                 if (w) { w.focus(); }
250         }
251 }
252
253 // Returns a list of selected treeitems from the specified tree
254 function get_list_from_tree_selection() {
255         sdump('D_WIDGETS',arg_dump(arguments));
256         var d = document; var tree_w;
257         if (arguments.length == 1) {
258                 tree_w = arguments[0];
259         } else {
260                 d = arguments[0];
261                 tree_w = arguments[1];
262         }
263         var hitlist;
264         if (typeof(tree_w) != 'object') {
265                 hitlist = d.getElementById(tree_w);
266         } else {
267                 hitlist = tree_w;
268         }
269         var list = [];
270         var start = new Object();
271         var end = new Object();
272         var numRanges = hitlist.view.selection.getRangeCount();
273         for (var t=0; t<numRanges; t++){
274                 hitlist.view.selection.getRangeAt(t,start,end);
275                 for (var v=start.value; v<=end.value; v++){
276                         var i = hitlist.contentView.getItemAtIndex(v);
277                         //sdump('D_WIDGETS',i.tagName + '\n');
278                         list.push( i );
279                 }
280         }
281         return list;
282 }
283
284 // Make sure we a widget
285 function get_widget() {
286         sdump('D_WIDGETS',arg_dump(arguments));
287         var d = document; var e;
288         if (arguments.length == 1) {
289                 e = arguments[0];
290         } else {
291                 d = arguments[0];
292                 e = arguments[1];
293         }
294         if (typeof(e) == 'object') {
295                 return e;
296         } else {
297                 var w = d.getElementById(e);
298                 if (w) return w;
299         }
300         return null;
301 }
302
303 // Increment a XUL progressmeter
304 function incr_progressmeter() {
305         sdump('D_WIDGETS',arg_dump(arguments));
306         var d = document; var meter; var increment;
307         if (arguments.length == 2) {
308                 meter = arguments[0];
309                 increment = arguments[1];
310         } else {
311                 d = arguments[0];
312                 meter = arguments[1];
313                 increment = arguments[2];
314         }
315         if (typeof(meter)!='object') 
316                 meter = d.getElementById(meter);
317         if (typeof(meter)!='object')
318                 return;
319
320         var real = meter.getAttribute('_real');
321
322         if (!real)
323                 real = 0;
324         real = parseFloat( real ) + parseFloat( increment );
325
326         if (real > 100)
327                 real = 100;
328         else if ( real < 0)
329                 real = 0;
330
331         meter.setAttribute('_real',real);
332         meter.value = Math.ceil( real );
333 }
334
335 // Populate a treeitem row
336 function map_array_to_treecells_via_treeitem( cols, treeitem ) {
337         sdump('D_WIDGETS',arg_dump(arguments),{0:true});
338         var treerow = treeitem.firstChild;
339         for (var i = 0; i < treerow.childNodes.length; i++) {
340                 var treecell = treerow.childNodes[i];
341                 treecell.setAttribute('label',cols[i]);
342                 sdump('D_WIDGETS','treeitem = ' + treeitem + ' treerow = ' + treerow + ' treecell = ' + treecell + ' cols[ ' + i + '] = ' + cols[i] + '\n');
343         }
344 }
345
346 // Simulates radio buttons with checkboxes.  Include this in command event listeners
347 // for the pertinent textboxes.  For any set of checkboxes that have the same 'group'
348 // attribute, only one can be checked at a time.
349 function radio_checkbox() {
350         sdump('D_WIDGETS',arg_dump(arguments));
351         var d = document; var ev;
352         if (arguments.length == 1) {
353                 ev = arguments[0];
354         } else {
355                 d = arguments[0];
356                 ev = arguments[1];
357         }
358         var target = ev.target;
359         var group = target.getAttribute('group');
360         if (group) {
361                 var nl = d.getElementsByTagName('checkbox');
362                 for (var i in nl) {
363                         if (typeof(nl[i])=='object') {
364                                 var c = nl[i];
365                                 var cgroup = c.getAttribute('group');
366                                 if (cgroup == group) {
367                                         c.checked = false;
368                                 }
369                         }
370                 }
371                 target.checked = true;
372         } else {
373                 sdump('D_WIDGETS','radio_checkbox: Checkbox must have a group attribute to find peers');
374         }
375 }
376
377 // simpler version of set_decks
378 function set_deck() {
379         sdump('D_WIDGETS',arg_dump(arguments));
380         var d = document; var deck; var idx;
381         if (arguments.length == 2) {
382                 deck = arguments[0];
383                 idx = arguments[1];
384                 set_decks({ deck : idx });
385         } else {
386                 d = arguments[0];
387                 deck = arguments[1];
388                 idx = arguments[2];
389                 set_decks(d,{ deck : idx });
390         }
391 }
392
393 // Takes a hash with key:value => deck element id : page index
394 // Sets each deck to the corresponding index
395 function set_decks() {
396         sdump('D_WIDGETS',arg_dump(arguments));
397         var d = document; var params;
398         if (arguments.length == 1) {
399                 params = arguments[0];
400         } else {
401                 d = arguments[0];
402                 params = arguments[1];
403         }
404         for (var deck_id in params) {
405                 var deck = deck_id;
406                 if (typeof(deck) != 'object')
407                         deck = d.getElementById( deck_id )
408                 if (deck) {
409                         deck.setAttribute( 'selectedIndex', params[deck_id] );
410                         deck.selectedIndex = params[deck_id];
411                 }
412         }
413 }
414
415 // For setting a widget's displayable text
416 function set_widget_value_for_display(e,v) {
417         sdump('D_WIDGETS',arg_dump(arguments,{1:true}));
418         if (v == null || v == undefined) v = '.....';
419         sdump('D_WIDGETS','e.tagName = ' + e.tagName + '\n');
420         sdump('D_WIDGETS','e.nodeName = ' + e.nodeName + '\n');
421         switch (e.tagName) {
422                 case 'textbox' : e.value = v; break;
423                 case 'label' : e.setAttribute('value',v); break;
424                 case 'image' : e.setAttribute('src',v); break;
425                 case 'menulist' : e.value = v;
426                         var menupopup = e.firstChild;
427                         var menuitem;
428                         for (var i = 0; i < menupopup.childNodes.length; i++) {
429                                 if (menupopup.childNodes[i].getAttribute('value') == v ) menuitem = menupopup.childNodes[i];
430                         }
431                         if (menuitem) e.selectedItem = menuitem;
432                         break;
433                 default: try {e.setAttribute('value',v); e.value = v;} catch(E) {} break;
434         }
435 }
436
437 // swaps the values of two attributes for an element
438 function swap_attributes() {
439         sdump('D_WIDGETS',arg_dump(arguments));
440         var d = document; var e; var a1; var a2;
441         if (arguments.length == 3) {
442                 e = arguments[0];
443                 a1 = arguments[1];
444                 a2 = arguments[2];
445         } else {
446                 d = arguments[0];
447                 e = arguments[1];
448                 a1 = arguments[2];
449                 a2 = arguments[3];
450                 if (typeof(e) != 'object') { e = d.getElementById(e); }
451         }
452         if (typeof(e) != 'object') { sdump('D_WIDGETS','Failed on swap_attributes\n'); return; }
453         var a1_v = e.getAttribute(a1);
454         var a2_v = e.getAttribute(a2);
455         e.setAttribute(a1,a2_v);
456         e.setAttribute(a2, a1_v);
457         sdump('D_WIDGETS','before: a1 = ' + a1_v + ' a2 = ' + a2_v + ' and ');
458         sdump('D_WIDGETS','after: a1 = ' + a2_v + ' a2 = ' + a1_v + '\n');
459 }
460
461 // Flips the hidden value for each row in a grid
462 function toggle_hidden_grid_rows() {
463         sdump('D_WIDGETS',arg_dump(arguments));
464         if (arguments.length == 1) {
465                 grid = arguments[0];
466         } else {
467                 d = arguments[0];
468                 grid = arguments[1];
469         }
470         if (typeof(grid) != 'object') {
471                 grid = d.getElementById(grid);
472         }
473         if (!grid) { return; }
474         var rows = grid.lastChild; if (!rows) { return; }
475         for (var r = 0; r < rows.childNodes.length; r++ ) {
476                 var row = rows.childNodes[r];
477                 if (typeof(row) == 'object') {
478                         //sdump('D_WIDGETS','toggle row = ' + row + '\n');
479                         var hidden = row.getAttribute('hidden');
480                         if (hidden == 'true') {
481                                 row.setAttribute('hidden','false');
482                         } else {
483                                 row.setAttribute('hidden','true');
484                         }
485                 }
486         }
487 }
488
489 /* The first parameter is the id of the element to set, or an array of ids for elements to set in batch.  The second parameter is an object containing the attribute/value pairs to assign to the element or elements */
490 function xul_setAttributes() {
491         sdump('D_WIDGETS',arg_dump(arguments));
492         var d = document; var el; var attrs;
493         if (arguments.length == 2) {
494                 el = arguments[0];
495                 attrs = arguments[1];
496         } else {
497                 d = arguments[0];
498                 el = arguments[1];
499                 attrs = arguments[2];
500         }
501         if (typeof(el) == 'object') {
502                 for (var e in el) {
503                         var w = d.getElementById(e);
504                         for (var a in attrs) {
505                                 w.setAttribute(a,attrs[a]);
506                         }
507                 }
508         } else {
509                 var w = d.getElementById(el);
510                 for (var a in attrs) {
511                         w.setAttribute(a,attrs[a]);
512                 }
513         }
514 }
515