1 dump('entering util.list.js\n');
3 if (typeof main == 'undefined') main = {};
4 util.list = function (id) {
6 this.node = document.getElementById(id);
8 this.row_count = { 'total' : 0, 'fleshed' : 0 };
10 if (!this.node) throw('Could not find element ' + id);
11 switch(this.node.nodeName) {
15 throw(this.node.nodeName + ' not yet supported'); break;
16 default: throw(this.node.nodeName + ' not supported'); break;
19 JSAN.use('util.error'); this.error = new util.error();
24 util.list.prototype = {
26 'init' : function (params) {
30 JSAN.use('util.widgets');
32 if (typeof params.map_row_to_column == 'function') obj.map_row_to_column = params.map_row_to_column;
33 if (typeof params.map_row_to_columns == 'function') obj.map_row_to_columns = params.map_row_to_columns;
34 if (typeof params.retrieve_row == 'function') obj.retrieve_row = params.retrieve_row;
37 if (typeof params.prebuilt != 'undefined') obj.prebuilt = params.prebuilt;
39 if (typeof params.columns == 'undefined') throw('util.list.init: No columns');
40 obj.columns = params.columns;
42 switch(obj.node.nodeName) {
43 case 'tree' : obj._init_tree(params); break;
44 case 'listbox' : obj._init_listbox(params); break;
45 default: throw('NYI: Need ._init() for ' + obj.node.nodeName); break;
49 'register_all_fleshed_callback' : function(f) {
50 this.on_all_fleshed = f;
53 '_init_tree' : function (params) {
57 this.treechildren = this.node.lastChild;
60 var treecols = document.createElement('treecols');
61 this.node.appendChild(treecols);
62 this.treecols = treecols;
64 for (var i = 0; i < this.columns.length; i++) {
65 var treecol = document.createElement('treecol');
66 for (var j in this.columns[i]) {
67 treecol.setAttribute(j,this.columns[i][j]);
69 treecols.appendChild(treecol);
70 treecol.addEventListener(
74 var sortDir = ev.target.getAttribute('sortDir') || 'desc';
75 if (sortDir == 'desc') sortDir = 'asc'; else sortDir = 'desc';
76 ev.target.setAttribute('sortDir',sortDir);
77 obj._sort_tree(ev.target,sortDir);
80 if (obj.row_count.total != obj.row_count.fleshed && (obj.row_count.total - obj.row_count.fleshed) > 50) {
81 var r = window.confirm('WARNING: Only ' + obj.row_count.fleshed + ' out of ' + obj.row_count.total + ' rows in this list have been retrieved for immediate viewing. Sorting this list requires that all these rows be retrieved, and this may take some time and lag the staff client. Would you like to proceed?');
84 setTimeout( do_it, 0 );
87 setTimeout( do_it, 0 );
92 var splitter = document.createElement('splitter');
93 splitter.setAttribute('class','tree-splitter');
94 treecols.appendChild(splitter);
97 var treechildren = document.createElement('treechildren');
98 this.node.appendChild(treechildren);
99 this.treechildren = treechildren;
101 if (typeof params.on_select == 'function') {
102 this.node.addEventListener(
108 if (typeof params.on_click == 'function') {
109 this.node.addEventListener(
116 this.node.addEventListener(
118 function(ev) { obj.detect_visible(); },
122 this.node.addEventListener(
124 function(ev) { obj.auto_retrieve(); },
127 this.node.addEventListener(
129 function(ev) { obj.auto_retrieve(); },
132 window.addEventListener(
134 function(ev) { obj.auto_retrieve(); },
137 /* FIXME -- find events on scrollbar to trigger this */
138 obj.detect_visible_polling();
140 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(this.node)[1] )[1];
141 var slider = document.getAnonymousNodes( scrollbar )[2];
142 alert('scrollbar = ' + scrollbar.nodeName + ' grippy = ' + slider.nodeName);
143 scrollbar.addEventListener('click',function(){alert('sb click');},false);
144 scrollbar.addEventListener('command',function(){alert('sb command');},false);
145 scrollbar.addEventListener('scroll',function(){alert('sb scroll');},false);
146 slider.addEventListener('click',function(){alert('slider click');},false);
147 slider.addEventListener('command',function(){alert('slider command');},false);
148 slider.addEventListener('scroll',function(){alert('slider scroll');},false);
150 this.node.addEventListener('scroll',function(){ obj.auto_retrieve(); },false);
152 this.restores_columns(params);
155 '_init_listbox' : function (params) {
158 var listhead = document.createElement('listhead');
159 this.node.appendChild(listhead);
161 var listcols = document.createElement('listcols');
162 this.node.appendChild(listcols);
164 for (var i = 0; i < this.columns.length; i++) {
165 var listheader = document.createElement('listheader');
166 listhead.appendChild(listheader);
167 var listcol = document.createElement('listcol');
168 listcols.appendChild(listcol);
169 for (var j in this.columns[i]) {
170 listheader.setAttribute(j,this.columns[i][j]);
171 listcol.setAttribute(j,this.columns[i][j]);
177 'save_columns' : function (params) {
179 switch (this.node.nodeName) {
180 case 'tree' : this._save_columns_tree(params); break;
181 default: throw('NYI: Need .save_columns() for ' + this.node.nodeName); break;
185 '_save_columns_tree' : function (params) {
188 var id = obj.node.getAttribute('id'); if (!id) {
189 alert("FIXME: The columns for this list cannot be saved because the list has no id.");
193 var nl = obj.node.getElementsByTagName('treecol');
194 for (var i = 0; i < nl.length; i++) {
196 var col_id = col.getAttribute('id');
198 alert('FIXME: A column in this list does not have an id and cannot be saved');
201 var col_hidden = col.getAttribute('hidden');
202 var col_width = col.getAttribute('width');
203 var col_ordinal = col.getAttribute('ordinal');
204 my_cols[ col_id ] = { 'hidden' : col_hidden, 'width' : col_width, 'ordinal' : col_ordinal };
206 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
207 JSAN.use('util.file'); var file = new util.file('tree_columns_for_'+window.escape(id));
208 file.set_object(my_cols);
210 alert('Columns saved.');
212 obj.error.standard_unexpected_error_alert('_save_columns_tree',E);
216 'restores_columns' : function (params) {
218 switch (this.node.nodeName) {
219 case 'tree' : this._restores_columns_tree(params); break;
220 default: throw('NYI: Need .restores_columns() for ' + this.node.nodeName); break;
224 '_restores_columns_tree' : function (params) {
227 var id = obj.node.getAttribute('id'); if (!id) {
228 alert("FIXME: The columns for this list cannot be restored because the list has no id.");
232 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
233 JSAN.use('util.file'); var file = new util.file('tree_columns_for_'+window.escape(id));
234 if (file._file.exists()) {
235 var my_cols = file.get_object(); file.close();
236 var nl = obj.node.getElementsByTagName('treecol');
237 for (var i = 0; i < nl.length; i++) {
239 var col_id = col.getAttribute('id');
241 alert('FIXME: A column in this list does not have an id and cannot be saved');
244 if (typeof my_cols[col_id] != 'undefined') {
245 col.setAttribute('hidden',my_cols[col_id].hidden);
246 col.setAttribute('width',my_cols[col_id].width);
247 col.setAttribute('ordinal',my_cols[col_id].ordinal);
249 obj.error.sdump('D_ERROR','WARNING: Column ' + col_id + ' did not have a saved state.');
254 obj.error.standard_unexpected_error_alert('_restore_columns_tree',E);
258 'clear' : function (params) {
260 switch (this.node.nodeName) {
261 case 'tree' : this._clear_tree(params); break;
262 case 'listbox' : this._clear_listbox(params); break;
263 default: throw('NYI: Need .clear() for ' + this.node.nodeName); break;
265 this.error.sdump('D_LIST','Clearing list ' + this.node.getAttribute('id') + '\n');
266 this.row_count.total = 0;
267 this.row_count.fleshed = 0;
268 if (typeof obj.on_all_fleshed == 'function') {
269 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
273 '_clear_tree' : function(params) {
275 if (obj.error.sdump_levels.D_LIST_DUMP_ON_CLEAR) {
276 obj.error.sdump('D_LIST_DUMP_ON_CLEAR',obj.dump());
278 if (obj.error.sdump_levels.D_LIST_DUMP_WITH_KEYS_ON_CLEAR) {
279 obj.error.sdump('D_LIST_DUMP_WITH_KEYS_ON_CLEAR',obj.dump_with_keys());
281 while (obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
284 '_clear_listbox' : function(params) {
287 var nl = this.node.getElementsByTagName('listitem');
288 for (var i = 0; i < nl.length; i++) {
291 for (var i = 0; i < items.length; i++) {
292 this.node.removeChild(items[i]);
296 'append' : function (params) {
299 switch (this.node.nodeName) {
300 case 'tree' : rnode = this._append_to_tree(params); break;
301 case 'listbox' : rnode = this._append_to_listbox(params); break;
302 default: throw('NYI: Need .append() for ' + this.node.nodeName); break;
304 if (rnode && params.attributes) {
305 for (var i in params.attributes) {
306 rnode.setAttribute(i,params.attributes[i]);
309 this.row_count.total++;
310 if (this.row_count.fleshed == this.row_count.total) {
311 if (typeof this.on_all_fleshed == 'function') {
312 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
318 '_append_to_tree' : function (params) {
322 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
324 var s = ('util.list.append: params = ' + (params) + '\n');
326 var treechildren_node = this.treechildren;
328 if (params.node && params.node.nodeName == 'treeitem') {
329 params.node.setAttribute('container','true'); /* params.node.setAttribute('open','true'); */
330 if (params.node.lastChild.nodeName == 'treechildren') {
331 treechildren_node = params.node.lastChild;
333 treechildren_node = document.createElement('treechildren');
334 params.node.appendChild(treechildren_node);
338 var treeitem = document.createElement('treeitem');
339 treeitem.setAttribute('retrieve_id',params.retrieve_id);
340 if (typeof params.to_bottom != 'undefined') {
341 treechildren_node.appendChild( treeitem );
342 if (typeof params.no_auto_select == 'undefined') {
343 try { obj.node.view.selection.select(Number(obj.node.view.rowCount)-1); } catch(E) { obj.error.sdump('D_ALERT','tree auto select: ' + E + '\n'); }
346 if (treechildren_node.firstChild) {
347 treechildren_node.insertBefore( treeitem, treechildren_node.firstChild );
349 treechildren_node.appendChild( treeitem );
351 if (typeof params.no_auto_select == 'undefined') {
352 try { obj.node.view.selection.select(0); } catch(E) { obj.error.sdump('D_ALERT','tree auto select: ' + E + '\n'); }
355 var treerow = document.createElement('treerow');
356 treeitem.appendChild( treerow );
357 treerow.setAttribute('retrieve_id',params.retrieve_id);
359 s += ('tree = ' + this.node + ' treechildren = ' + treechildren_node + '\n');
360 s += ('treeitem = ' + treeitem + ' treerow = ' + treerow + '\n');
362 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
364 obj.put_retrieving_label(treerow);
365 treerow.addEventListener(
369 if (treerow.getAttribute('retrieved') == 'true') return; /* already running */
371 treerow.setAttribute('retrieved','true');
373 //dump('fleshing = ' + params.retrieve_id + '\n');
375 function inc_fleshed() {
376 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
377 treerow.setAttribute('fleshed','true');
378 obj.row_count.fleshed++;
379 if (obj.row_count.fleshed == obj.row_count.total) {
380 if (typeof obj.on_all_fleshed == 'function') {
381 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
386 params.row_node = treeitem;
387 params.on_retrieve = function(p) {
390 obj._map_row_to_treecell(p,treerow);
393 alert('fixme2: ' + E);
397 if (typeof params.retrieve_row == 'function') {
399 params.retrieve_row( params );
401 } else if (typeof obj.retrieve_row == 'function') {
403 obj.retrieve_row( params );
415 util.widgets.dispatch('flesh',treerow);
420 obj.put_retrieving_label(treerow);
421 treerow.addEventListener(
424 //dump('fleshing anon\n');
425 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
426 obj._map_row_to_treecell(params,treerow);
427 treerow.setAttribute('retrieved','true');
428 treerow.setAttribute('fleshed','true');
429 obj.row_count.fleshed++;
430 if (obj.row_count.fleshed == obj.row_count.total) {
431 if (typeof obj.on_all_fleshed == 'function') {
432 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
441 util.widgets.dispatch('flesh',treerow);
446 this.error.sdump('D_LIST',s);
450 if (obj.trim_list && obj.row_count.total >= obj.trim_list) {
452 //if (typeof params.to_bottom != 'undefined') {
453 if (typeof params.to_top == 'undefined') {
454 treechildren_node.removeChild( treechildren_node.firstChild );
456 treechildren_node.removeChild( treechildren_node.lastChild );
462 setTimeout( function() { obj.auto_retrieve(); }, 0 );
467 'put_retrieving_label' : function(treerow) {
472 dump('put_retrieving_label. columns = ' + js2JSON(obj.columns) + '\n');
473 while( obj.columns[cols_idx] && obj.columns[cols_idx].hidden && obj.columns[cols_idx].hidden == 'true') {
474 dump('\t' + cols_idx);
475 var treecell = document.createElement('treecell');
476 treerow.appendChild(treecell);
480 for (var i = 0; i < obj.columns.length; i++) {
481 var treecell = document.createElement('treecell'); treecell.setAttribute('label','Retrieving...');
482 treerow.appendChild(treecell);
485 dump('\t' + cols_idx + '\n');
492 'detect_visible' : function() {
495 //dump('detect_visible obj.node = ' + obj.node + '\n');
496 /* FIXME - this is a hack.. if the implementation of tree changes, this could break */
498 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(obj.node)[1] )[1];
499 var curpos = scrollbar.getAttribute('curpos');
500 var maxpos = scrollbar.getAttribute('maxpos');
501 //alert('curpos = ' + curpos + ' maxpos = ' + maxpos + ' obj.curpos = ' + obj.curpos + ' obj.maxpos = ' + obj.maxpos + '\n');
502 if ((curpos != obj.curpos) || (maxpos != obj.maxpos)) {
503 if ( obj.auto_retrieve() > 0 ) {
504 obj.curpos = curpos; obj.maxpos = maxpos;
508 obj.error.sdump('D_XULRUNNER', 'List implementation changed? ' + E);
510 } catch(E) { obj.error.sdump('D_ERROR',E); }
513 'detect_visible_polling' : function() {
515 //alert('detect_visible_polling');
517 obj.detect_visible();
518 setTimeout(function() { try { obj.detect_visible_polling(); } catch(E) { alert(E); } },2000);
525 'auto_retrieve' : function(params) {
527 switch (this.node.nodeName) {
528 case 'tree' : obj._auto_retrieve_tree(params); break;
529 default: throw('NYI: Need .auto_retrieve() for ' + obj.node.nodeName); break;
533 '_auto_retrieve_tree' : function (params) {
535 if (!obj.auto_retrieve_in_progress) {
536 obj.auto_retrieve_in_progress = true;
540 //alert('auto_retrieve\n');
542 var startpos = obj.node.treeBoxObject.getFirstVisibleRow();
543 var endpos = obj.node.treeBoxObject.getLastVisibleRow();
544 if (startpos > endpos) endpos = obj.node.treeBoxObject.getPageLength();
545 //dump('startpos = ' + startpos + ' endpos = ' + endpos + '\n');
546 for (var i = startpos; i < endpos + 4; i++) {
548 //dump('trying index ' + i + '\n');
549 var item = obj.node.contentView.getItemAtIndex(i).firstChild;
550 if (item && item.getAttribute('retrieved') != 'true' ) {
551 //dump('\tgot an unfleshed item = ' + item + ' = ' + item.nodeName + '\n');
552 util.widgets.dispatch('flesh',item); count++;
555 //dump(i + ' : ' + E + '\n');
558 obj.auto_retrieve_in_progress = false;
560 } catch(E) { alert(E); }
566 'full_retrieve' : function(params) {
568 switch (this.node.nodeName) {
569 case 'tree' : obj._full_retrieve_tree(params); break;
570 default: throw('NYI: Need .full_retrieve() for ' + obj.node.nodeName); break;
574 '_full_retrieve_tree' : function(params) {
577 if (obj.row_count.total == obj.row_count.fleshed) {
578 //alert('Full retrieve... tree seems to be in sync\n' + js2JSON(obj.row_count));
579 if (typeof obj.on_all_fleshed == 'function') {
580 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
582 alert('.full_retrieve called with no callback?');
585 //alert('Full retrieve... syncing tree' + js2JSON(obj.row_count));
586 JSAN.use('util.widgets');
587 var nodes = obj.treechildren.childNodes;
588 for (var i = 0; i < nodes.length; i++) {
589 util.widgets.dispatch('flesh',nodes[i].firstChild);
593 obj.error.standard_unexpected_error_alert('_full_retrieve_tree',E);
597 '_append_to_listbox' : function (params) {
601 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
603 var s = ('util.list.append: params = ' + (params) + '\n');
605 var listitem = document.createElement('listitem');
607 s += ('listbox = ' + this.node + ' listitem = ' + listitem + '\n');
609 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
613 listitem.setAttribute('retrieve_id',params.retrieve_id);
614 //FIXME//Make async and fire when row is visible in list
617 params.row_node = listitem;
618 params.on_retrieve = function(row) {
620 obj._map_row_to_listcell(params,listitem);
621 obj.node.appendChild( listitem );
624 if (typeof params.retrieve_row == 'function') {
626 row = params.retrieve_row( params );
630 if (typeof obj.retrieve_row == 'function') {
632 row = obj.retrieve_row( params );
639 this._map_row_to_listcell(params,listitem);
640 this.node.appendChild( listitem );
643 this.error.sdump('D_LIST',s);
648 '_map_row_to_treecell' : function(params,treerow) {
651 util.widgets.remove_children(treerow);
653 if (typeof params.map_row_to_column == 'function' || typeof this.map_row_to_column == 'function') {
655 for (var i = 0; i < this.columns.length; i++) {
656 var treecell = document.createElement('treecell');
658 if (params.skip_columns && (params.skip_columns.indexOf(i) != -1)) {
659 treecell.setAttribute('label',label);
660 treerow.appendChild( treecell );
661 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
664 if (params.skip_all_columns_except && (params.skip_all_columns_except.indexOf(i) == -1)) {
665 treecell.setAttribute('label',label);
666 treerow.appendChild( treecell );
667 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
671 if (typeof params.map_row_to_column == 'function') {
673 label = params.map_row_to_column(params.row,this.columns[i]);
675 } else if (typeof this.map_row_to_column == 'function') {
677 label = this.map_row_to_column(params.row,this.columns[i]);
680 treecell.setAttribute('label',label ? label : '');
681 treerow.appendChild( treecell );
682 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
684 } else if (typeof params.map_row_to_columns == 'function' || typeof this.map_row_to_columns == 'function') {
688 if (typeof params.map_row_to_columns == 'function') {
690 labels = params.map_row_to_columns(params.row,this.columns);
692 } else if (typeof this.map_row_to_columns == 'function') {
694 labels = this.map_row_to_columns(params.row,this.columns);
697 for (var i = 0; i < labels.length; i++) {
698 var treecell = document.createElement('treecell');
699 treecell.setAttribute('label',typeof labels[i] == 'string' || typeof labels[i] == 'number' ? labels[i] : '');
700 treerow.appendChild( treecell );
701 s += ('treecell = ' + treecell + ' with label = ' + labels[i] + '\n');
706 throw('No row to column mapping function.');
708 this.error.sdump('D_LIST',s);
711 '_map_row_to_listcell' : function(params,listitem) {
714 for (var i = 0; i < this.columns.length; i++) {
716 if (typeof params.map_row_to_column == 'function') {
718 value = params.map_row_to_column(params.row,this.columns[i]);
722 if (typeof this.map_row_to_column == 'function') {
724 value = this.map_row_to_column(params.row,this.columns[i]);
727 if (typeof value == 'string' || typeof value == 'number') {
728 var listcell = document.createElement('listcell');
729 listcell.setAttribute('label',value);
730 listitem.appendChild(listcell);
731 s += ('listcell = ' + listcell + ' with label = ' + value + '\n');
733 listitem.appendChild(value);
734 s += ('listcell = ' + value + ' is really a ' + value.nodeName + '\n');
737 this.error.sdump('D_LIST',s);
740 'select_all' : function(params) {
742 switch(this.node.nodeName) {
743 case 'tree' : return this._select_all_from_tree(params); break;
744 default: throw('NYI: Need ._select_all_from_() for ' + this.node.nodeName); break;
748 '_select_all_from_tree' : function(params) {
750 this.node.view.selection.selectAll();
753 'retrieve_selection' : function(params) {
755 switch(this.node.nodeName) {
756 case 'tree' : return this._retrieve_selection_from_tree(params); break;
757 default: throw('NYI: Need ._retrieve_selection_from_() for ' + this.node.nodeName); break;
761 '_retrieve_selection_from_tree' : function(params) {
764 var start = new Object();
765 var end = new Object();
766 var numRanges = this.node.view.selection.getRangeCount();
767 for (var t=0; t<numRanges; t++){
768 this.node.view.selection.getRangeAt(t,start,end);
769 for (var v=start.value; v<=end.value; v++){
770 var i = this.node.contentView.getItemAtIndex(v);
777 'dump' : function(params) {
779 switch(this.node.nodeName) {
780 case 'tree' : return this._dump_tree(params); break;
781 default: throw('NYI: Need .dump() for ' + this.node.nodeName); break;
785 '_dump_tree' : function(params) {
788 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
790 var treeitem = this.treechildren.childNodes[i];
791 var treerow = treeitem.firstChild;
792 for (var j = 0; j < treerow.childNodes.length; j++) {
793 row.push( treerow.childNodes[j].getAttribute('label') );
800 'dump_with_keys' : function(params) {
802 switch(this.node.nodeName) {
803 case 'tree' : return this._dump_tree_with_keys(params); break;
804 default: throw('NYI: Need .dump_with_keys() for ' + this.node.nodeName); break;
809 '_dump_tree_with_keys' : function(params) {
812 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
814 var treeitem = this.treechildren.childNodes[i];
815 var treerow = treeitem.firstChild;
816 for (var j = 0; j < treerow.childNodes.length; j++) {
817 row[ obj.columns[j].id ] = treerow.childNodes[j].getAttribute('label');
824 'dump_csv' : function(params) {
826 switch(this.node.nodeName) {
827 case 'tree' : return this._dump_tree_csv(params); break;
828 default: throw('NYI: Need .dump_csv() for ' + this.node.nodeName); break;
833 '_dump_tree_csv' : function(params) {
836 for (var j = 0; j < obj.columns.length; j++) {
837 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
840 if (dump) dump += ',';
841 dump += '"' + obj.columns[j].label.replace(/"/g, '""') + '"';
845 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
847 var treeitem = this.treechildren.childNodes[i];
848 var treerow = treeitem.firstChild;
849 for (var j = 0; j < treerow.childNodes.length; j++) {
850 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
854 row += '"' + treerow.childNodes[j].getAttribute('label').replace(/"/g, '""') + '"';
857 dump += row + '\r\n';
862 'dump_selected_with_keys' : function(params) {
864 switch(this.node.nodeName) {
865 case 'tree' : return this._dump_tree_selection_with_keys(params); break;
866 default: throw('NYI: Need .dump_selection_with_keys() for ' + this.node.nodeName); break;
871 '_dump_tree_selection_with_keys' : function(params) {
874 var list = obj._retrieve_selection_from_tree();
875 for (var i = 0; i < list.length; i++) {
877 var treeitem = list[i];
878 var treerow = treeitem.firstChild;
879 for (var j = 0; j < treerow.childNodes.length; j++) {
880 var value = treerow.childNodes[j].getAttribute('label');
881 if (params.skip_hidden_columns) if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') continue;
882 var id = obj.columns[j].id; if (params.labels_instead_of_ids) id = obj.columns[j].label;
890 'clipboard' : function() {
893 var dump = obj.dump_selected_with_keys({'skip_hidden_columns':true,'labels_instead_of_ids':true});
894 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
895 data.list_clipboard = dump; data.stash('list_clipboard');
896 JSAN.use('util.window'); var win = new util.window();
897 win.open(urls.XUL_LIST_CLIPBOARD,'list_clipboard','chrome,resizable,modal');
899 this.error.standard_unexpected_error_alert('clipboard',E);
903 'dump_retrieve_ids' : function(params) {
905 switch(this.node.nodeName) {
906 case 'tree' : return this._dump_retrieve_ids_tree(params); break;
907 default: throw('NYI: Need .dump_retrieve_ids() for ' + this.node.nodeName); break;
911 '_dump_retrieve_ids_tree' : function(params) {
914 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
915 var treeitem = this.treechildren.childNodes[i];
916 dump.push( treeitem.getAttribute('retrieve_id') );
921 '_sort_tree' : function(col,sortDir) {
924 if (obj.node.getAttribute('no_sort')) {
927 if (obj.on_all_fleshed) {
928 var r = window.confirm('This list is busy rendering/retrieving data. Abort current action and proceed?');
929 if (r) {} else { return; }
932 for (var i = 0; i < obj.columns.length; i++) {
933 if (obj.columns[i].id == col.id) col_pos = function(a){return a;}(i);
935 obj.on_all_fleshed = function() {
937 JSAN.use('util.money');
939 var treeitems = obj.treechildren.childNodes;
940 for (var i = 0; i < treeitems.length; i++) {
941 var treeitem = treeitems[i];
942 var treerow = treeitem.firstChild;
943 var treecell = treerow.childNodes[ col_pos ];
944 value = ( { 'value' : treecell ? treecell.getAttribute('label') : '', 'node' : treeitem } );
947 rows = rows.sort( function(a,b) {
948 a = a.value; b = b.value;
949 if (col.getAttribute('sort_type')) {
950 switch(col.getAttribute('sort_type')) {
952 a = Number(a); b = Number(b);
955 a = util.money.dollars_float_to_cents_integer(a);
956 b = util.money.dollars_float_to_cents_integer(b);
958 case 'title' : /* special case for "a" and "the". doesn't use marc 245 indicator */
959 a = String( a ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
960 b = String( b ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
963 a = String( a ).toUpperCase();
964 b = String( b ).toUpperCase();
968 if (typeof a == 'string' || typeof b == 'string') {
969 a = String( a ).toUpperCase();
970 b = String( b ).toUpperCase();
973 if (a < b) return -1;
977 if (sortDir == 'asc') rows = rows.reverse();
978 while(obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
979 for (var i = 0; i < rows.length; i++) {
980 obj.treechildren.appendChild( rows[i].node );
983 obj.error.standard_unexpected_error_alert('sorting',E);
985 setTimeout(function(){ obj.on_all_fleshed = null; },0);
989 obj.error.standard_unexpected_error_alert('pre sorting', E);
994 dump('exiting util.list.js\n');