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 if (typeof params.to_top == 'undefined') {
342 treechildren_node.appendChild( treeitem );
344 if (treechildren_node.firstChild) {
345 treechildren_node.insertBefore( treeitem, treechildren_node.firstChild );
347 treechildren_node.appendChild( treeitem );
350 var treerow = document.createElement('treerow');
351 treeitem.appendChild( treerow );
352 treerow.setAttribute('retrieve_id',params.retrieve_id);
354 s += ('tree = ' + this.node + ' treechildren = ' + treechildren_node + '\n');
355 s += ('treeitem = ' + treeitem + ' treerow = ' + treerow + '\n');
357 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
359 obj.put_retrieving_label(treerow);
360 treerow.addEventListener(
364 if (treerow.getAttribute('retrieved') == 'true') return; /* already running */
366 treerow.setAttribute('retrieved','true');
368 //dump('fleshing = ' + params.retrieve_id + '\n');
370 function inc_fleshed() {
371 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
372 treerow.setAttribute('fleshed','true');
373 obj.row_count.fleshed++;
374 if (obj.row_count.fleshed == obj.row_count.total) {
375 if (typeof obj.on_all_fleshed == 'function') {
376 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
381 params.row_node = treeitem;
382 params.on_retrieve = function(p) {
385 obj._map_row_to_treecell(p,treerow);
388 alert('fixme2: ' + E);
392 if (typeof params.retrieve_row == 'function') {
394 params.retrieve_row( params );
396 } else if (typeof obj.retrieve_row == 'function') {
398 obj.retrieve_row( params );
410 util.widgets.dispatch('flesh',treerow);
415 obj.put_retrieving_label(treerow);
416 treerow.addEventListener(
419 //dump('fleshing anon\n');
420 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
421 obj._map_row_to_treecell(params,treerow);
422 treerow.setAttribute('retrieved','true');
423 treerow.setAttribute('fleshed','true');
424 obj.row_count.fleshed++;
425 if (obj.row_count.fleshed == obj.row_count.total) {
426 if (typeof obj.on_all_fleshed == 'function') {
427 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
436 util.widgets.dispatch('flesh',treerow);
441 this.error.sdump('D_LIST',s);
445 if (obj.trim_list && obj.row_count.total >= obj.trim_list) {
447 //if (typeof params.to_bottom != 'undefined') {
448 if (typeof params.to_top == 'undefined') {
449 treechildren_node.removeChild( treechildren_node.firstChild );
451 treechildren_node.removeChild( treechildren_node.lastChild );
457 setTimeout( function() { obj.auto_retrieve(); }, 0 );
462 'put_retrieving_label' : function(treerow) {
467 dump('put_retrieving_label. columns = ' + js2JSON(obj.columns) + '\n');
468 while( obj.columns[cols_idx] && obj.columns[cols_idx].hidden && obj.columns[cols_idx].hidden == 'true') {
469 dump('\t' + cols_idx);
470 var treecell = document.createElement('treecell');
471 treerow.appendChild(treecell);
475 for (var i = 0; i < obj.columns.length; i++) {
476 var treecell = document.createElement('treecell'); treecell.setAttribute('label','Retrieving...');
477 treerow.appendChild(treecell);
480 dump('\t' + cols_idx + '\n');
487 'detect_visible' : function() {
490 //dump('detect_visible obj.node = ' + obj.node + '\n');
491 /* FIXME - this is a hack.. if the implementation of tree changes, this could break */
493 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(obj.node)[1] )[1];
494 var curpos = scrollbar.getAttribute('curpos');
495 var maxpos = scrollbar.getAttribute('maxpos');
496 //alert('curpos = ' + curpos + ' maxpos = ' + maxpos + ' obj.curpos = ' + obj.curpos + ' obj.maxpos = ' + obj.maxpos + '\n');
497 if ((curpos != obj.curpos) || (maxpos != obj.maxpos)) {
498 if ( obj.auto_retrieve() > 0 ) {
499 obj.curpos = curpos; obj.maxpos = maxpos;
503 obj.error.sdump('D_XULRUNNER', 'List implementation changed? ' + E);
505 } catch(E) { obj.error.sdump('D_ERROR',E); }
508 'detect_visible_polling' : function() {
510 //alert('detect_visible_polling');
512 obj.detect_visible();
513 setTimeout(function() { try { obj.detect_visible_polling(); } catch(E) { alert(E); } },2000);
520 'auto_retrieve' : function(params) {
522 switch (this.node.nodeName) {
523 case 'tree' : obj._auto_retrieve_tree(params); break;
524 default: throw('NYI: Need .auto_retrieve() for ' + obj.node.nodeName); break;
528 '_auto_retrieve_tree' : function (params) {
530 if (!obj.auto_retrieve_in_progress) {
531 obj.auto_retrieve_in_progress = true;
535 //alert('auto_retrieve\n');
537 var startpos = obj.node.treeBoxObject.getFirstVisibleRow();
538 var endpos = obj.node.treeBoxObject.getLastVisibleRow();
539 if (startpos > endpos) endpos = obj.node.treeBoxObject.getPageLength();
540 //dump('startpos = ' + startpos + ' endpos = ' + endpos + '\n');
541 for (var i = startpos; i < endpos + 4; i++) {
543 //dump('trying index ' + i + '\n');
544 var item = obj.node.contentView.getItemAtIndex(i).firstChild;
545 if (item && item.getAttribute('retrieved') != 'true' ) {
546 //dump('\tgot an unfleshed item = ' + item + ' = ' + item.nodeName + '\n');
547 util.widgets.dispatch('flesh',item); count++;
550 //dump(i + ' : ' + E + '\n');
553 obj.auto_retrieve_in_progress = false;
555 } catch(E) { alert(E); }
561 'full_retrieve' : function(params) {
563 switch (this.node.nodeName) {
564 case 'tree' : obj._full_retrieve_tree(params); break;
565 default: throw('NYI: Need .full_retrieve() for ' + obj.node.nodeName); break;
569 '_full_retrieve_tree' : function(params) {
572 if (obj.row_count.total == obj.row_count.fleshed) {
573 //alert('Full retrieve... tree seems to be in sync\n' + js2JSON(obj.row_count));
574 if (typeof obj.on_all_fleshed == 'function') {
575 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
577 alert('.full_retrieve called with no callback?');
580 //alert('Full retrieve... syncing tree' + js2JSON(obj.row_count));
581 JSAN.use('util.widgets');
582 var nodes = obj.treechildren.childNodes;
583 for (var i = 0; i < nodes.length; i++) {
584 util.widgets.dispatch('flesh',nodes[i].firstChild);
588 obj.error.standard_unexpected_error_alert('_full_retrieve_tree',E);
592 '_append_to_listbox' : function (params) {
596 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
598 var s = ('util.list.append: params = ' + (params) + '\n');
600 var listitem = document.createElement('listitem');
602 s += ('listbox = ' + this.node + ' listitem = ' + listitem + '\n');
604 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
608 listitem.setAttribute('retrieve_id',params.retrieve_id);
609 //FIXME//Make async and fire when row is visible in list
612 params.row_node = listitem;
613 params.on_retrieve = function(row) {
615 obj._map_row_to_listcell(params,listitem);
616 obj.node.appendChild( listitem );
619 if (typeof params.retrieve_row == 'function') {
621 row = params.retrieve_row( params );
625 if (typeof obj.retrieve_row == 'function') {
627 row = obj.retrieve_row( params );
634 this._map_row_to_listcell(params,listitem);
635 this.node.appendChild( listitem );
638 this.error.sdump('D_LIST',s);
643 '_map_row_to_treecell' : function(params,treerow) {
646 util.widgets.remove_children(treerow);
648 if (typeof params.map_row_to_column == 'function' || typeof this.map_row_to_column == 'function') {
650 for (var i = 0; i < this.columns.length; i++) {
651 var treecell = document.createElement('treecell');
653 if (params.skip_columns && (params.skip_columns.indexOf(i) != -1)) {
654 treecell.setAttribute('label',label);
655 treerow.appendChild( treecell );
656 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
659 if (params.skip_all_columns_except && (params.skip_all_columns_except.indexOf(i) == -1)) {
660 treecell.setAttribute('label',label);
661 treerow.appendChild( treecell );
662 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
666 if (typeof params.map_row_to_column == 'function') {
668 label = params.map_row_to_column(params.row,this.columns[i]);
670 } else if (typeof this.map_row_to_column == 'function') {
672 label = this.map_row_to_column(params.row,this.columns[i]);
675 treecell.setAttribute('label',label ? label : '');
676 treerow.appendChild( treecell );
677 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
679 } else if (typeof params.map_row_to_columns == 'function' || typeof this.map_row_to_columns == 'function') {
683 if (typeof params.map_row_to_columns == 'function') {
685 labels = params.map_row_to_columns(params.row,this.columns);
687 } else if (typeof this.map_row_to_columns == 'function') {
689 labels = this.map_row_to_columns(params.row,this.columns);
692 for (var i = 0; i < labels.length; i++) {
693 var treecell = document.createElement('treecell');
694 treecell.setAttribute('label',typeof labels[i] == 'string' || typeof labels[i] == 'number' ? labels[i] : '');
695 treerow.appendChild( treecell );
696 s += ('treecell = ' + treecell + ' with label = ' + labels[i] + '\n');
701 throw('No row to column mapping function.');
703 this.error.sdump('D_LIST',s);
706 '_map_row_to_listcell' : function(params,listitem) {
709 for (var i = 0; i < this.columns.length; i++) {
711 if (typeof params.map_row_to_column == 'function') {
713 value = params.map_row_to_column(params.row,this.columns[i]);
717 if (typeof this.map_row_to_column == 'function') {
719 value = this.map_row_to_column(params.row,this.columns[i]);
722 if (typeof value == 'string' || typeof value == 'number') {
723 var listcell = document.createElement('listcell');
724 listcell.setAttribute('label',value);
725 listitem.appendChild(listcell);
726 s += ('listcell = ' + listcell + ' with label = ' + value + '\n');
728 listitem.appendChild(value);
729 s += ('listcell = ' + value + ' is really a ' + value.nodeName + '\n');
732 this.error.sdump('D_LIST',s);
735 'select_all' : function(params) {
737 switch(this.node.nodeName) {
738 case 'tree' : return this._select_all_from_tree(params); break;
739 default: throw('NYI: Need ._select_all_from_() for ' + this.node.nodeName); break;
743 '_select_all_from_tree' : function(params) {
745 this.node.view.selection.selectAll();
748 'retrieve_selection' : function(params) {
750 switch(this.node.nodeName) {
751 case 'tree' : return this._retrieve_selection_from_tree(params); break;
752 default: throw('NYI: Need ._retrieve_selection_from_() for ' + this.node.nodeName); break;
756 '_retrieve_selection_from_tree' : function(params) {
759 var start = new Object();
760 var end = new Object();
761 var numRanges = this.node.view.selection.getRangeCount();
762 for (var t=0; t<numRanges; t++){
763 this.node.view.selection.getRangeAt(t,start,end);
764 for (var v=start.value; v<=end.value; v++){
765 var i = this.node.contentView.getItemAtIndex(v);
772 'dump' : function(params) {
774 switch(this.node.nodeName) {
775 case 'tree' : return this._dump_tree(params); break;
776 default: throw('NYI: Need .dump() for ' + this.node.nodeName); break;
780 '_dump_tree' : function(params) {
783 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
785 var treeitem = this.treechildren.childNodes[i];
786 var treerow = treeitem.firstChild;
787 for (var j = 0; j < treerow.childNodes.length; j++) {
788 row.push( treerow.childNodes[j].getAttribute('label') );
795 'dump_with_keys' : function(params) {
797 switch(this.node.nodeName) {
798 case 'tree' : return this._dump_tree_with_keys(params); break;
799 default: throw('NYI: Need .dump_with_keys() for ' + this.node.nodeName); break;
804 '_dump_tree_with_keys' : function(params) {
807 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
809 var treeitem = this.treechildren.childNodes[i];
810 var treerow = treeitem.firstChild;
811 for (var j = 0; j < treerow.childNodes.length; j++) {
812 row[ obj.columns[j].id ] = treerow.childNodes[j].getAttribute('label');
819 'dump_csv' : function(params) {
821 switch(this.node.nodeName) {
822 case 'tree' : return this._dump_tree_csv(params); break;
823 default: throw('NYI: Need .dump_csv() for ' + this.node.nodeName); break;
828 '_dump_tree_csv' : function(params) {
831 for (var j = 0; j < obj.columns.length; j++) {
832 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
835 if (dump) dump += ',';
836 dump += '"' + obj.columns[j].label.replace(/"/g, '""') + '"';
840 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
842 var treeitem = this.treechildren.childNodes[i];
843 var treerow = treeitem.firstChild;
844 for (var j = 0; j < treerow.childNodes.length; j++) {
845 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
849 row += '"' + treerow.childNodes[j].getAttribute('label').replace(/"/g, '""') + '"';
852 dump += row + '\r\n';
857 'dump_selected_with_keys' : function(params) {
859 switch(this.node.nodeName) {
860 case 'tree' : return this._dump_tree_selection_with_keys(params); break;
861 default: throw('NYI: Need .dump_selection_with_keys() for ' + this.node.nodeName); break;
866 '_dump_tree_selection_with_keys' : function(params) {
869 var list = obj._retrieve_selection_from_tree();
870 for (var i = 0; i < list.length; i++) {
872 var treeitem = list[i];
873 var treerow = treeitem.firstChild;
874 for (var j = 0; j < treerow.childNodes.length; j++) {
875 var value = treerow.childNodes[j].getAttribute('label');
876 if (params.skip_hidden_columns) if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') continue;
877 var id = obj.columns[j].id; if (params.labels_instead_of_ids) id = obj.columns[j].label;
885 'clipboard' : function() {
888 var dump = obj.dump_selected_with_keys({'skip_hidden_columns':true,'labels_instead_of_ids':true});
889 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
890 data.list_clipboard = dump; data.stash('list_clipboard');
891 JSAN.use('util.window'); var win = new util.window();
892 win.open(urls.XUL_LIST_CLIPBOARD,'list_clipboard','chrome,resizable,modal');
894 this.error.standard_unexpected_error_alert('clipboard',E);
898 'dump_retrieve_ids' : function(params) {
900 switch(this.node.nodeName) {
901 case 'tree' : return this._dump_retrieve_ids_tree(params); break;
902 default: throw('NYI: Need .dump_retrieve_ids() for ' + this.node.nodeName); break;
906 '_dump_retrieve_ids_tree' : function(params) {
909 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
910 var treeitem = this.treechildren.childNodes[i];
911 dump.push( treeitem.getAttribute('retrieve_id') );
916 '_sort_tree' : function(col,sortDir) {
919 if (obj.node.getAttribute('no_sort')) {
922 if (obj.on_all_fleshed) {
923 var r = window.confirm('This list is busy rendering/retrieving data. Abort current action and proceed?');
924 if (r) {} else { return; }
927 for (var i = 0; i < obj.columns.length; i++) {
928 if (obj.columns[i].id == col.id) col_pos = function(a){return a;}(i);
930 obj.on_all_fleshed = function() {
932 JSAN.use('util.money');
934 var treeitems = obj.treechildren.childNodes;
935 for (var i = 0; i < treeitems.length; i++) {
936 var treeitem = treeitems[i];
937 var treerow = treeitem.firstChild;
938 var treecell = treerow.childNodes[ col_pos ];
939 value = ( { 'value' : treecell ? treecell.getAttribute('label') : '', 'node' : treeitem } );
942 rows = rows.sort( function(a,b) {
943 a = a.value; b = b.value;
944 if (col.getAttribute('sort_type')) {
945 switch(col.getAttribute('sort_type')) {
947 a = Number(a); b = Number(b);
950 a = util.money.dollars_float_to_cents_integer(a);
951 b = util.money.dollars_float_to_cents_integer(b);
953 case 'title' : /* special case for "a" and "the". doesn't use marc 245 indicator */
954 a = String( a ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
955 b = String( b ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
958 a = String( a ).toUpperCase();
959 b = String( b ).toUpperCase();
963 if (typeof a == 'string' || typeof b == 'string') {
964 a = String( a ).toUpperCase();
965 b = String( b ).toUpperCase();
968 if (a < b) return -1;
972 if (sortDir == 'asc') rows = rows.reverse();
973 while(obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
974 for (var i = 0; i < rows.length; i++) {
975 obj.treechildren.appendChild( rows[i].node );
978 obj.error.standard_unexpected_error_alert('sorting',E);
980 setTimeout(function(){ obj.on_all_fleshed = null; },0);
984 obj.error.standard_unexpected_error_alert('pre sorting', E);
989 dump('exiting util.list.js\n');