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_top == 'undefined') {
341 treechildren_node.appendChild( treeitem );
343 if (treechildren_node.firstChild) {
344 treechildren_node.insertBefore( treeitem, treechildren_node.firstChild );
346 treechildren_node.appendChild( treeitem );
349 var treerow = document.createElement('treerow');
350 treeitem.appendChild( treerow );
351 treerow.setAttribute('retrieve_id',params.retrieve_id);
353 s += ('tree = ' + this.node + ' treechildren = ' + treechildren_node + '\n');
354 s += ('treeitem = ' + treeitem + ' treerow = ' + treerow + '\n');
356 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
358 obj.put_retrieving_label(treerow);
359 treerow.addEventListener(
363 if (treerow.getAttribute('retrieved') == 'true') return; /* already running */
365 treerow.setAttribute('retrieved','true');
367 //dump('fleshing = ' + params.retrieve_id + '\n');
369 function inc_fleshed() {
370 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
371 treerow.setAttribute('fleshed','true');
372 obj.row_count.fleshed++;
373 if (obj.row_count.fleshed == obj.row_count.total) {
374 if (typeof obj.on_all_fleshed == 'function') {
375 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
380 params.row_node = treeitem;
381 params.on_retrieve = function(p) {
384 obj._map_row_to_treecell(p,treerow);
387 alert('fixme2: ' + E);
391 if (typeof params.retrieve_row == 'function') {
393 params.retrieve_row( params );
395 } else if (typeof obj.retrieve_row == 'function') {
397 obj.retrieve_row( params );
409 util.widgets.dispatch('flesh',treerow);
414 obj.put_retrieving_label(treerow);
415 treerow.addEventListener(
418 //dump('fleshing anon\n');
419 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
420 obj._map_row_to_treecell(params,treerow);
421 treerow.setAttribute('retrieved','true');
422 treerow.setAttribute('fleshed','true');
423 obj.row_count.fleshed++;
424 if (obj.row_count.fleshed == obj.row_count.total) {
425 if (typeof obj.on_all_fleshed == 'function') {
426 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
435 util.widgets.dispatch('flesh',treerow);
440 this.error.sdump('D_LIST',s);
444 if (obj.trim_list && obj.row_count.total >= obj.trim_list) {
446 if (typeof params.to_top == 'undefined') {
447 treechildren_node.removeChild( treechildren_node.firstChild );
449 treechildren_node.removeChild( treechildren_node.lastChild );
455 setTimeout( function() { obj.auto_retrieve(); }, 0 );
460 'put_retrieving_label' : function(treerow) {
465 dump('put_retrieving_label. columns = ' + js2JSON(obj.columns) + '\n');
466 while( obj.columns[cols_idx] && obj.columns[cols_idx].hidden && obj.columns[cols_idx].hidden == 'true') {
467 dump('\t' + cols_idx);
468 var treecell = document.createElement('treecell');
469 treerow.appendChild(treecell);
473 for (var i = 0; i < obj.columns.length; i++) {
474 var treecell = document.createElement('treecell'); treecell.setAttribute('label','Retrieving...');
475 treerow.appendChild(treecell);
478 dump('\t' + cols_idx + '\n');
485 'detect_visible' : function() {
488 //dump('detect_visible obj.node = ' + obj.node + '\n');
489 /* FIXME - this is a hack.. if the implementation of tree changes, this could break */
491 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(obj.node)[1] )[1];
492 var curpos = scrollbar.getAttribute('curpos');
493 var maxpos = scrollbar.getAttribute('maxpos');
494 //alert('curpos = ' + curpos + ' maxpos = ' + maxpos + ' obj.curpos = ' + obj.curpos + ' obj.maxpos = ' + obj.maxpos + '\n');
495 if ((curpos != obj.curpos) || (maxpos != obj.maxpos)) {
496 if ( obj.auto_retrieve() > 0 ) {
497 obj.curpos = curpos; obj.maxpos = maxpos;
501 obj.error.sdump('D_XULRUNNER', 'List implementation changed? ' + E);
503 } catch(E) { obj.error.sdump('D_ERROR',E); }
506 'detect_visible_polling' : function() {
508 //alert('detect_visible_polling');
510 obj.detect_visible();
511 setTimeout(function() { try { obj.detect_visible_polling(); } catch(E) { alert(E); } },2000);
518 'auto_retrieve' : function(params) {
520 switch (this.node.nodeName) {
521 case 'tree' : obj._auto_retrieve_tree(params); break;
522 default: throw('NYI: Need .auto_retrieve() for ' + obj.node.nodeName); break;
526 '_auto_retrieve_tree' : function (params) {
528 if (!obj.auto_retrieve_in_progress) {
529 obj.auto_retrieve_in_progress = true;
533 //alert('auto_retrieve\n');
535 var startpos = obj.node.treeBoxObject.getFirstVisibleRow();
536 var endpos = obj.node.treeBoxObject.getLastVisibleRow();
537 if (startpos > endpos) endpos = obj.node.treeBoxObject.getPageLength();
538 //dump('startpos = ' + startpos + ' endpos = ' + endpos + '\n');
539 for (var i = startpos; i < endpos + 4; i++) {
541 //dump('trying index ' + i + '\n');
542 var item = obj.node.contentView.getItemAtIndex(i).firstChild;
543 if (item && item.getAttribute('retrieved') != 'true' ) {
544 //dump('\tgot an unfleshed item = ' + item + ' = ' + item.nodeName + '\n');
545 util.widgets.dispatch('flesh',item); count++;
548 //dump(i + ' : ' + E + '\n');
551 obj.auto_retrieve_in_progress = false;
553 } catch(E) { alert(E); }
559 'full_retrieve' : function(params) {
561 switch (this.node.nodeName) {
562 case 'tree' : obj._full_retrieve_tree(params); break;
563 default: throw('NYI: Need .full_retrieve() for ' + obj.node.nodeName); break;
567 '_full_retrieve_tree' : function(params) {
570 if (obj.row_count.total == obj.row_count.fleshed) {
571 //alert('Full retrieve... tree seems to be in sync\n' + js2JSON(obj.row_count));
572 if (typeof obj.on_all_fleshed == 'function') {
573 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
575 alert('.full_retrieve called with no callback?');
578 //alert('Full retrieve... syncing tree' + js2JSON(obj.row_count));
579 JSAN.use('util.widgets');
580 var nodes = obj.treechildren.childNodes;
581 for (var i = 0; i < nodes.length; i++) {
582 util.widgets.dispatch('flesh',nodes[i].firstChild);
586 obj.error.standard_unexpected_error_alert('_full_retrieve_tree',E);
590 '_append_to_listbox' : function (params) {
594 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
596 var s = ('util.list.append: params = ' + (params) + '\n');
598 var listitem = document.createElement('listitem');
600 s += ('listbox = ' + this.node + ' listitem = ' + listitem + '\n');
602 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
606 listitem.setAttribute('retrieve_id',params.retrieve_id);
607 //FIXME//Make async and fire when row is visible in list
610 params.row_node = listitem;
611 params.on_retrieve = function(row) {
613 obj._map_row_to_listcell(params,listitem);
614 obj.node.appendChild( listitem );
617 if (typeof params.retrieve_row == 'function') {
619 row = params.retrieve_row( params );
623 if (typeof obj.retrieve_row == 'function') {
625 row = obj.retrieve_row( params );
632 this._map_row_to_listcell(params,listitem);
633 this.node.appendChild( listitem );
636 this.error.sdump('D_LIST',s);
641 '_map_row_to_treecell' : function(params,treerow) {
644 util.widgets.remove_children(treerow);
646 if (typeof params.map_row_to_column == 'function' || typeof this.map_row_to_column == 'function') {
648 for (var i = 0; i < this.columns.length; i++) {
649 var treecell = document.createElement('treecell');
651 if (params.skip_columns && (params.skip_columns.indexOf(i) != -1)) {
652 treecell.setAttribute('label',label);
653 treerow.appendChild( treecell );
654 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
657 if (params.skip_all_columns_except && (params.skip_all_columns_except.indexOf(i) == -1)) {
658 treecell.setAttribute('label',label);
659 treerow.appendChild( treecell );
660 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
664 if (typeof params.map_row_to_column == 'function') {
666 label = params.map_row_to_column(params.row,this.columns[i]);
668 } else if (typeof this.map_row_to_column == 'function') {
670 label = this.map_row_to_column(params.row,this.columns[i]);
673 treecell.setAttribute('label',label ? label : '');
674 treerow.appendChild( treecell );
675 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
677 } else if (typeof params.map_row_to_columns == 'function' || typeof this.map_row_to_columns == 'function') {
681 if (typeof params.map_row_to_columns == 'function') {
683 labels = params.map_row_to_columns(params.row,this.columns);
685 } else if (typeof this.map_row_to_columns == 'function') {
687 labels = this.map_row_to_columns(params.row,this.columns);
690 for (var i = 0; i < labels.length; i++) {
691 var treecell = document.createElement('treecell');
692 treecell.setAttribute('label',typeof labels[i] == 'string' || typeof labels[i] == 'number' ? labels[i] : '');
693 treerow.appendChild( treecell );
694 s += ('treecell = ' + treecell + ' with label = ' + labels[i] + '\n');
699 throw('No row to column mapping function.');
701 this.error.sdump('D_LIST',s);
704 '_map_row_to_listcell' : function(params,listitem) {
707 for (var i = 0; i < this.columns.length; i++) {
709 if (typeof params.map_row_to_column == 'function') {
711 value = params.map_row_to_column(params.row,this.columns[i]);
715 if (typeof this.map_row_to_column == 'function') {
717 value = this.map_row_to_column(params.row,this.columns[i]);
720 if (typeof value == 'string' || typeof value == 'number') {
721 var listcell = document.createElement('listcell');
722 listcell.setAttribute('label',value);
723 listitem.appendChild(listcell);
724 s += ('listcell = ' + listcell + ' with label = ' + value + '\n');
726 listitem.appendChild(value);
727 s += ('listcell = ' + value + ' is really a ' + value.nodeName + '\n');
730 this.error.sdump('D_LIST',s);
733 'select_all' : function(params) {
735 switch(this.node.nodeName) {
736 case 'tree' : return this._select_all_from_tree(params); break;
737 default: throw('NYI: Need ._select_all_from_() for ' + this.node.nodeName); break;
741 '_select_all_from_tree' : function(params) {
743 this.node.view.selection.selectAll();
746 'retrieve_selection' : function(params) {
748 switch(this.node.nodeName) {
749 case 'tree' : return this._retrieve_selection_from_tree(params); break;
750 default: throw('NYI: Need ._retrieve_selection_from_() for ' + this.node.nodeName); break;
754 '_retrieve_selection_from_tree' : function(params) {
757 var start = new Object();
758 var end = new Object();
759 var numRanges = this.node.view.selection.getRangeCount();
760 for (var t=0; t<numRanges; t++){
761 this.node.view.selection.getRangeAt(t,start,end);
762 for (var v=start.value; v<=end.value; v++){
763 var i = this.node.contentView.getItemAtIndex(v);
770 'dump' : function(params) {
772 switch(this.node.nodeName) {
773 case 'tree' : return this._dump_tree(params); break;
774 default: throw('NYI: Need .dump() for ' + this.node.nodeName); break;
778 '_dump_tree' : function(params) {
781 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
783 var treeitem = this.treechildren.childNodes[i];
784 var treerow = treeitem.firstChild;
785 for (var j = 0; j < treerow.childNodes.length; j++) {
786 row.push( treerow.childNodes[j].getAttribute('label') );
793 'dump_with_keys' : function(params) {
795 switch(this.node.nodeName) {
796 case 'tree' : return this._dump_tree_with_keys(params); break;
797 default: throw('NYI: Need .dump_with_keys() for ' + this.node.nodeName); break;
802 '_dump_tree_with_keys' : function(params) {
805 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
807 var treeitem = this.treechildren.childNodes[i];
808 var treerow = treeitem.firstChild;
809 for (var j = 0; j < treerow.childNodes.length; j++) {
810 row[ obj.columns[j].id ] = treerow.childNodes[j].getAttribute('label');
817 'dump_csv' : function(params) {
819 switch(this.node.nodeName) {
820 case 'tree' : return this._dump_tree_csv(params); break;
821 default: throw('NYI: Need .dump_csv() for ' + this.node.nodeName); break;
826 '_dump_tree_csv' : function(params) {
829 for (var j = 0; j < obj.columns.length; j++) {
830 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
833 if (dump) dump += ',';
834 dump += '"' + obj.columns[j].label.replace(/"/g, '""') + '"';
838 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
840 var treeitem = this.treechildren.childNodes[i];
841 var treerow = treeitem.firstChild;
842 for (var j = 0; j < treerow.childNodes.length; j++) {
843 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
847 row += '"' + treerow.childNodes[j].getAttribute('label').replace(/"/g, '""') + '"';
850 dump += row + '\r\n';
855 'dump_selected_with_keys' : function(params) {
857 switch(this.node.nodeName) {
858 case 'tree' : return this._dump_tree_selection_with_keys(params); break;
859 default: throw('NYI: Need .dump_selection_with_keys() for ' + this.node.nodeName); break;
864 '_dump_tree_selection_with_keys' : function(params) {
867 var list = obj._retrieve_selection_from_tree();
868 for (var i = 0; i < list.length; i++) {
870 var treeitem = list[i];
871 var treerow = treeitem.firstChild;
872 for (var j = 0; j < treerow.childNodes.length; j++) {
873 var value = treerow.childNodes[j].getAttribute('label');
874 if (params.skip_hidden_columns) if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') continue;
875 var id = obj.columns[j].id; if (params.labels_instead_of_ids) id = obj.columns[j].label;
883 'clipboard' : function() {
886 var dump = obj.dump_selected_with_keys({'skip_hidden_columns':true,'labels_instead_of_ids':true});
887 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
888 data.list_clipboard = dump; data.stash('list_clipboard');
889 JSAN.use('util.window'); var win = new util.window();
890 win.open(urls.XUL_LIST_CLIPBOARD,'list_clipboard','chrome,resizable,modal');
892 this.error.standard_unexpected_error_alert('clipboard',E);
896 'dump_retrieve_ids' : function(params) {
898 switch(this.node.nodeName) {
899 case 'tree' : return this._dump_retrieve_ids_tree(params); break;
900 default: throw('NYI: Need .dump_retrieve_ids() for ' + this.node.nodeName); break;
904 '_dump_retrieve_ids_tree' : function(params) {
907 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
908 var treeitem = this.treechildren.childNodes[i];
909 dump.push( treeitem.getAttribute('retrieve_id') );
914 '_sort_tree' : function(col,sortDir) {
917 if (obj.node.getAttribute('no_sort')) {
920 if (obj.on_all_fleshed) {
921 var r = window.confirm('This list is busy rendering/retrieving data. Abort current action and proceed?');
922 if (r) {} else { return; }
925 for (var i = 0; i < obj.columns.length; i++) {
926 if (obj.columns[i].id == col.id) col_pos = function(a){return a;}(i);
928 obj.on_all_fleshed = function() {
930 JSAN.use('util.money');
932 var treeitems = obj.treechildren.childNodes;
933 for (var i = 0; i < treeitems.length; i++) {
934 var treeitem = treeitems[i];
935 var treerow = treeitem.firstChild;
936 var treecell = treerow.childNodes[ col_pos ];
937 value = ( { 'value' : treecell ? treecell.getAttribute('label') : '', 'node' : treeitem } );
940 rows = rows.sort( function(a,b) {
941 a = a.value; b = b.value;
942 if (col.getAttribute('sort_type')) {
943 switch(col.getAttribute('sort_type')) {
945 a = Number(a); b = Number(b);
948 a = util.money.dollars_float_to_cents_integer(a);
949 b = util.money.dollars_float_to_cents_integer(b);
951 case 'title' : /* special case for "a" and "the". doesn't use marc 245 indicator */
952 a = String( a ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
953 b = String( b ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
956 a = String( a ).toUpperCase();
957 b = String( b ).toUpperCase();
961 if (typeof a == 'string' || typeof b == 'string') {
962 a = String( a ).toUpperCase();
963 b = String( b ).toUpperCase();
966 if (a < b) return -1;
970 if (sortDir == 'asc') rows = rows.reverse();
971 while(obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
972 for (var i = 0; i < rows.length; i++) {
973 obj.treechildren.appendChild( rows[i].node );
976 obj.error.standard_unexpected_error_alert('sorting',E);
978 setTimeout(function(){ obj.on_all_fleshed = null; },0);
982 obj.error.standard_unexpected_error_alert('pre sorting', E);
987 dump('exiting util.list.js\n');