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 if (!obj.auto_select_pending) {
344 obj.auto_select_pending = true;
345 setTimeout(function() {
346 try { obj.node.view.selection.select(Number(obj.node.view.rowCount)-1); } catch(E) { obj.error.sdump('D_ALERT','tree auto select: ' + E + '\n'); }
347 try { if (typeof params.on_select == 'function') params.on_select(); } catch(E) { obj.error.sdump('D_ALERT','tree auto select, on_select: ' + E + '\n'); }
348 obj.auto_select_pending = false;
353 if (treechildren_node.firstChild) {
354 treechildren_node.insertBefore( treeitem, treechildren_node.firstChild );
356 treechildren_node.appendChild( treeitem );
358 if (typeof params.no_auto_select == 'undefined') {
359 if (!obj.auto_select_pending) {
360 obj.auto_select_pending = true;
361 setTimeout(function() {
362 try { obj.node.view.selection.select(0); } catch(E) { obj.error.sdump('D_ALERT','tree auto select: ' + E + '\n'); }
363 try { if (typeof params.on_select == 'function') params.on_select(); } catch(E) { obj.error.sdump('D_ALERT','tree auto select, on_select: ' + E + '\n'); }
364 obj.auto_select_pending = false;
369 var treerow = document.createElement('treerow');
370 treeitem.appendChild( treerow );
371 treerow.setAttribute('retrieve_id',params.retrieve_id);
373 s += ('tree = ' + this.node + ' treechildren = ' + treechildren_node + '\n');
374 s += ('treeitem = ' + treeitem + ' treerow = ' + treerow + '\n');
376 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
378 obj.put_retrieving_label(treerow);
379 treerow.addEventListener(
383 if (treerow.getAttribute('retrieved') == 'true') return; /* already running */
385 treerow.setAttribute('retrieved','true');
387 //dump('fleshing = ' + params.retrieve_id + '\n');
389 function inc_fleshed() {
390 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
391 treerow.setAttribute('fleshed','true');
392 obj.row_count.fleshed++;
393 if (obj.row_count.fleshed == obj.row_count.total) {
394 if (typeof obj.on_all_fleshed == 'function') {
395 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
400 params.row_node = treeitem;
401 params.on_retrieve = function(p) {
404 obj._map_row_to_treecell(p,treerow);
407 alert('fixme2: ' + E);
411 if (typeof params.retrieve_row == 'function') {
413 params.retrieve_row( params );
415 } else if (typeof obj.retrieve_row == 'function') {
417 obj.retrieve_row( params );
429 util.widgets.dispatch('flesh',treerow);
434 obj.put_retrieving_label(treerow);
435 treerow.addEventListener(
438 //dump('fleshing anon\n');
439 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
440 obj._map_row_to_treecell(params,treerow);
441 treerow.setAttribute('retrieved','true');
442 treerow.setAttribute('fleshed','true');
443 obj.row_count.fleshed++;
444 if (obj.row_count.fleshed == obj.row_count.total) {
445 if (typeof obj.on_all_fleshed == 'function') {
446 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
455 util.widgets.dispatch('flesh',treerow);
460 this.error.sdump('D_LIST',s);
464 if (obj.trim_list && obj.row_count.total >= obj.trim_list) {
466 //if (typeof params.to_bottom != 'undefined') {
467 if (typeof params.to_top == 'undefined') {
468 treechildren_node.removeChild( treechildren_node.firstChild );
470 treechildren_node.removeChild( treechildren_node.lastChild );
476 setTimeout( function() { obj.auto_retrieve(); }, 0 );
481 'put_retrieving_label' : function(treerow) {
486 dump('put_retrieving_label. columns = ' + js2JSON(obj.columns) + '\n');
487 while( obj.columns[cols_idx] && obj.columns[cols_idx].hidden && obj.columns[cols_idx].hidden == 'true') {
488 dump('\t' + cols_idx);
489 var treecell = document.createElement('treecell');
490 treerow.appendChild(treecell);
494 for (var i = 0; i < obj.columns.length; i++) {
495 var treecell = document.createElement('treecell'); treecell.setAttribute('label','Retrieving...');
496 treerow.appendChild(treecell);
499 dump('\t' + cols_idx + '\n');
506 'detect_visible' : function() {
509 //dump('detect_visible obj.node = ' + obj.node + '\n');
510 /* FIXME - this is a hack.. if the implementation of tree changes, this could break */
512 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(obj.node)[1] )[1];
513 var curpos = scrollbar.getAttribute('curpos');
514 var maxpos = scrollbar.getAttribute('maxpos');
515 //alert('curpos = ' + curpos + ' maxpos = ' + maxpos + ' obj.curpos = ' + obj.curpos + ' obj.maxpos = ' + obj.maxpos + '\n');
516 if ((curpos != obj.curpos) || (maxpos != obj.maxpos)) {
517 if ( obj.auto_retrieve() > 0 ) {
518 obj.curpos = curpos; obj.maxpos = maxpos;
522 obj.error.sdump('D_XULRUNNER', 'List implementation changed? ' + E);
524 } catch(E) { obj.error.sdump('D_ERROR',E); }
527 'detect_visible_polling' : function() {
529 //alert('detect_visible_polling');
531 obj.detect_visible();
532 setTimeout(function() { try { obj.detect_visible_polling(); } catch(E) { alert(E); } },2000);
539 'auto_retrieve' : function(params) {
541 switch (this.node.nodeName) {
542 case 'tree' : obj._auto_retrieve_tree(params); break;
543 default: throw('NYI: Need .auto_retrieve() for ' + obj.node.nodeName); break;
547 '_auto_retrieve_tree' : function (params) {
549 if (!obj.auto_retrieve_in_progress) {
550 obj.auto_retrieve_in_progress = true;
554 //alert('auto_retrieve\n');
556 var startpos = obj.node.treeBoxObject.getFirstVisibleRow();
557 var endpos = obj.node.treeBoxObject.getLastVisibleRow();
558 if (startpos > endpos) endpos = obj.node.treeBoxObject.getPageLength();
559 //dump('startpos = ' + startpos + ' endpos = ' + endpos + '\n');
560 for (var i = startpos; i < endpos + 4; i++) {
562 //dump('trying index ' + i + '\n');
563 var item = obj.node.contentView.getItemAtIndex(i).firstChild;
564 if (item && item.getAttribute('retrieved') != 'true' ) {
565 //dump('\tgot an unfleshed item = ' + item + ' = ' + item.nodeName + '\n');
566 util.widgets.dispatch('flesh',item); count++;
569 //dump(i + ' : ' + E + '\n');
572 obj.auto_retrieve_in_progress = false;
574 } catch(E) { alert(E); }
580 'full_retrieve' : function(params) {
582 switch (this.node.nodeName) {
583 case 'tree' : obj._full_retrieve_tree(params); break;
584 default: throw('NYI: Need .full_retrieve() for ' + obj.node.nodeName); break;
588 '_full_retrieve_tree' : function(params) {
591 if (obj.row_count.total == obj.row_count.fleshed) {
592 //alert('Full retrieve... tree seems to be in sync\n' + js2JSON(obj.row_count));
593 if (typeof obj.on_all_fleshed == 'function') {
594 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
596 alert('.full_retrieve called with no callback?');
599 //alert('Full retrieve... syncing tree' + js2JSON(obj.row_count));
600 JSAN.use('util.widgets');
601 var nodes = obj.treechildren.childNodes;
602 for (var i = 0; i < nodes.length; i++) {
603 util.widgets.dispatch('flesh',nodes[i].firstChild);
607 obj.error.standard_unexpected_error_alert('_full_retrieve_tree',E);
611 '_append_to_listbox' : function (params) {
615 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
617 var s = ('util.list.append: params = ' + (params) + '\n');
619 var listitem = document.createElement('listitem');
621 s += ('listbox = ' + this.node + ' listitem = ' + listitem + '\n');
623 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
627 listitem.setAttribute('retrieve_id',params.retrieve_id);
628 //FIXME//Make async and fire when row is visible in list
631 params.row_node = listitem;
632 params.on_retrieve = function(row) {
634 obj._map_row_to_listcell(params,listitem);
635 obj.node.appendChild( listitem );
638 if (typeof params.retrieve_row == 'function') {
640 row = params.retrieve_row( params );
644 if (typeof obj.retrieve_row == 'function') {
646 row = obj.retrieve_row( params );
653 this._map_row_to_listcell(params,listitem);
654 this.node.appendChild( listitem );
657 this.error.sdump('D_LIST',s);
662 '_map_row_to_treecell' : function(params,treerow) {
665 util.widgets.remove_children(treerow);
667 if (typeof params.map_row_to_column == 'function' || typeof this.map_row_to_column == 'function') {
669 for (var i = 0; i < this.columns.length; i++) {
670 var treecell = document.createElement('treecell');
672 if (params.skip_columns && (params.skip_columns.indexOf(i) != -1)) {
673 treecell.setAttribute('label',label);
674 treerow.appendChild( treecell );
675 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
678 if (params.skip_all_columns_except && (params.skip_all_columns_except.indexOf(i) == -1)) {
679 treecell.setAttribute('label',label);
680 treerow.appendChild( treecell );
681 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
685 if (typeof params.map_row_to_column == 'function') {
687 label = params.map_row_to_column(params.row,this.columns[i]);
689 } else if (typeof this.map_row_to_column == 'function') {
691 label = this.map_row_to_column(params.row,this.columns[i]);
694 treecell.setAttribute('label',label ? label : '');
695 treerow.appendChild( treecell );
696 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
698 } else if (typeof params.map_row_to_columns == 'function' || typeof this.map_row_to_columns == 'function') {
702 if (typeof params.map_row_to_columns == 'function') {
704 labels = params.map_row_to_columns(params.row,this.columns);
706 } else if (typeof this.map_row_to_columns == 'function') {
708 labels = this.map_row_to_columns(params.row,this.columns);
711 for (var i = 0; i < labels.length; i++) {
712 var treecell = document.createElement('treecell');
713 treecell.setAttribute('label',typeof labels[i] == 'string' || typeof labels[i] == 'number' ? labels[i] : '');
714 treerow.appendChild( treecell );
715 s += ('treecell = ' + treecell + ' with label = ' + labels[i] + '\n');
720 throw('No row to column mapping function.');
722 this.error.sdump('D_LIST',s);
725 '_map_row_to_listcell' : function(params,listitem) {
728 for (var i = 0; i < this.columns.length; i++) {
730 if (typeof params.map_row_to_column == 'function') {
732 value = params.map_row_to_column(params.row,this.columns[i]);
736 if (typeof this.map_row_to_column == 'function') {
738 value = this.map_row_to_column(params.row,this.columns[i]);
741 if (typeof value == 'string' || typeof value == 'number') {
742 var listcell = document.createElement('listcell');
743 listcell.setAttribute('label',value);
744 listitem.appendChild(listcell);
745 s += ('listcell = ' + listcell + ' with label = ' + value + '\n');
747 listitem.appendChild(value);
748 s += ('listcell = ' + value + ' is really a ' + value.nodeName + '\n');
751 this.error.sdump('D_LIST',s);
754 'select_all' : function(params) {
756 switch(this.node.nodeName) {
757 case 'tree' : return this._select_all_from_tree(params); break;
758 default: throw('NYI: Need ._select_all_from_() for ' + this.node.nodeName); break;
762 '_select_all_from_tree' : function(params) {
764 this.node.view.selection.selectAll();
767 'retrieve_selection' : function(params) {
769 switch(this.node.nodeName) {
770 case 'tree' : return this._retrieve_selection_from_tree(params); break;
771 default: throw('NYI: Need ._retrieve_selection_from_() for ' + this.node.nodeName); break;
775 '_retrieve_selection_from_tree' : function(params) {
778 var start = new Object();
779 var end = new Object();
780 var numRanges = this.node.view.selection.getRangeCount();
781 for (var t=0; t<numRanges; t++){
782 this.node.view.selection.getRangeAt(t,start,end);
783 for (var v=start.value; v<=end.value; v++){
784 var i = this.node.contentView.getItemAtIndex(v);
791 'dump' : function(params) {
793 switch(this.node.nodeName) {
794 case 'tree' : return this._dump_tree(params); break;
795 default: throw('NYI: Need .dump() for ' + this.node.nodeName); break;
799 '_dump_tree' : function(params) {
802 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
804 var treeitem = this.treechildren.childNodes[i];
805 var treerow = treeitem.firstChild;
806 for (var j = 0; j < treerow.childNodes.length; j++) {
807 row.push( treerow.childNodes[j].getAttribute('label') );
814 'dump_with_keys' : function(params) {
816 switch(this.node.nodeName) {
817 case 'tree' : return this._dump_tree_with_keys(params); break;
818 default: throw('NYI: Need .dump_with_keys() for ' + this.node.nodeName); break;
823 '_dump_tree_with_keys' : function(params) {
826 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
828 var treeitem = this.treechildren.childNodes[i];
829 var treerow = treeitem.firstChild;
830 for (var j = 0; j < treerow.childNodes.length; j++) {
831 row[ obj.columns[j].id ] = treerow.childNodes[j].getAttribute('label');
838 'dump_csv' : function(params) {
840 switch(this.node.nodeName) {
841 case 'tree' : return this._dump_tree_csv(params); break;
842 default: throw('NYI: Need .dump_csv() for ' + this.node.nodeName); break;
847 '_dump_tree_csv' : function(params) {
850 for (var j = 0; j < obj.columns.length; j++) {
851 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
854 if (dump) dump += ',';
855 dump += '"' + obj.columns[j].label.replace(/"/g, '""') + '"';
859 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
861 var treeitem = this.treechildren.childNodes[i];
862 var treerow = treeitem.firstChild;
863 for (var j = 0; j < treerow.childNodes.length; j++) {
864 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
868 row += '"' + treerow.childNodes[j].getAttribute('label').replace(/"/g, '""') + '"';
871 dump += row + '\r\n';
876 'dump_selected_with_keys' : function(params) {
878 switch(this.node.nodeName) {
879 case 'tree' : return this._dump_tree_selection_with_keys(params); break;
880 default: throw('NYI: Need .dump_selection_with_keys() for ' + this.node.nodeName); break;
885 '_dump_tree_selection_with_keys' : function(params) {
888 var list = obj._retrieve_selection_from_tree();
889 for (var i = 0; i < list.length; i++) {
891 var treeitem = list[i];
892 var treerow = treeitem.firstChild;
893 for (var j = 0; j < treerow.childNodes.length; j++) {
894 var value = treerow.childNodes[j].getAttribute('label');
895 if (params.skip_hidden_columns) if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') continue;
896 var id = obj.columns[j].id; if (params.labels_instead_of_ids) id = obj.columns[j].label;
904 'clipboard' : function() {
907 var dump = obj.dump_selected_with_keys({'skip_hidden_columns':true,'labels_instead_of_ids':true});
908 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
909 data.list_clipboard = dump; data.stash('list_clipboard');
910 JSAN.use('util.window'); var win = new util.window();
911 win.open(urls.XUL_LIST_CLIPBOARD,'list_clipboard','chrome,resizable,modal');
913 this.error.standard_unexpected_error_alert('clipboard',E);
917 'dump_retrieve_ids' : function(params) {
919 switch(this.node.nodeName) {
920 case 'tree' : return this._dump_retrieve_ids_tree(params); break;
921 default: throw('NYI: Need .dump_retrieve_ids() for ' + this.node.nodeName); break;
925 '_dump_retrieve_ids_tree' : function(params) {
928 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
929 var treeitem = this.treechildren.childNodes[i];
930 dump.push( treeitem.getAttribute('retrieve_id') );
935 '_sort_tree' : function(col,sortDir) {
938 if (obj.node.getAttribute('no_sort')) {
941 if (obj.on_all_fleshed) {
942 var r = window.confirm('This list is busy rendering/retrieving data. Abort current action and proceed?');
943 if (r) {} else { return; }
946 for (var i = 0; i < obj.columns.length; i++) {
947 if (obj.columns[i].id == col.id) col_pos = function(a){return a;}(i);
949 obj.on_all_fleshed = function() {
951 JSAN.use('util.money');
953 var treeitems = obj.treechildren.childNodes;
954 for (var i = 0; i < treeitems.length; i++) {
955 var treeitem = treeitems[i];
956 var treerow = treeitem.firstChild;
957 var treecell = treerow.childNodes[ col_pos ];
958 value = ( { 'value' : treecell ? treecell.getAttribute('label') : '', 'node' : treeitem } );
961 rows = rows.sort( function(a,b) {
962 a = a.value; b = b.value;
963 if (col.getAttribute('sort_type')) {
964 switch(col.getAttribute('sort_type')) {
966 a = Number(a); b = Number(b);
969 a = util.money.dollars_float_to_cents_integer(a);
970 b = util.money.dollars_float_to_cents_integer(b);
972 case 'title' : /* special case for "a" and "the". doesn't use marc 245 indicator */
973 a = String( a ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
974 b = String( b ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
977 a = String( a ).toUpperCase();
978 b = String( b ).toUpperCase();
982 if (typeof a == 'string' || typeof b == 'string') {
983 a = String( a ).toUpperCase();
984 b = String( b ).toUpperCase();
987 if (a < b) return -1;
991 if (sortDir == 'asc') rows = rows.reverse();
992 while(obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
993 for (var i = 0; i < rows.length; i++) {
994 obj.treechildren.appendChild( rows[i].node );
997 obj.error.standard_unexpected_error_alert('sorting',E);
999 setTimeout(function(){ obj.on_all_fleshed = null; },0);
1001 obj.full_retrieve();
1003 obj.error.standard_unexpected_error_alert('pre sorting', E);
1008 dump('exiting util.list.js\n');