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 if (typeof params.no_auto_select == 'undefined') {
351 try { obj.node.view.selection.select(0); } catch(E) { obj.error.sdump('D_ERROR','tree auto select: ' + E + '\n'); }
353 var treerow = document.createElement('treerow');
354 treeitem.appendChild( treerow );
355 treerow.setAttribute('retrieve_id',params.retrieve_id);
357 s += ('tree = ' + this.node + ' treechildren = ' + treechildren_node + '\n');
358 s += ('treeitem = ' + treeitem + ' treerow = ' + treerow + '\n');
360 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
362 obj.put_retrieving_label(treerow);
363 treerow.addEventListener(
367 if (treerow.getAttribute('retrieved') == 'true') return; /* already running */
369 treerow.setAttribute('retrieved','true');
371 //dump('fleshing = ' + params.retrieve_id + '\n');
373 function inc_fleshed() {
374 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
375 treerow.setAttribute('fleshed','true');
376 obj.row_count.fleshed++;
377 if (obj.row_count.fleshed == obj.row_count.total) {
378 if (typeof obj.on_all_fleshed == 'function') {
379 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
384 params.row_node = treeitem;
385 params.on_retrieve = function(p) {
388 obj._map_row_to_treecell(p,treerow);
391 alert('fixme2: ' + E);
395 if (typeof params.retrieve_row == 'function') {
397 params.retrieve_row( params );
399 } else if (typeof obj.retrieve_row == 'function') {
401 obj.retrieve_row( params );
413 util.widgets.dispatch('flesh',treerow);
418 obj.put_retrieving_label(treerow);
419 treerow.addEventListener(
422 //dump('fleshing anon\n');
423 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
424 obj._map_row_to_treecell(params,treerow);
425 treerow.setAttribute('retrieved','true');
426 treerow.setAttribute('fleshed','true');
427 obj.row_count.fleshed++;
428 if (obj.row_count.fleshed == obj.row_count.total) {
429 if (typeof obj.on_all_fleshed == 'function') {
430 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
439 util.widgets.dispatch('flesh',treerow);
444 this.error.sdump('D_LIST',s);
448 if (obj.trim_list && obj.row_count.total >= obj.trim_list) {
450 //if (typeof params.to_bottom != 'undefined') {
451 if (typeof params.to_top == 'undefined') {
452 treechildren_node.removeChild( treechildren_node.firstChild );
454 treechildren_node.removeChild( treechildren_node.lastChild );
460 setTimeout( function() { obj.auto_retrieve(); }, 0 );
465 'put_retrieving_label' : function(treerow) {
470 dump('put_retrieving_label. columns = ' + js2JSON(obj.columns) + '\n');
471 while( obj.columns[cols_idx] && obj.columns[cols_idx].hidden && obj.columns[cols_idx].hidden == 'true') {
472 dump('\t' + cols_idx);
473 var treecell = document.createElement('treecell');
474 treerow.appendChild(treecell);
478 for (var i = 0; i < obj.columns.length; i++) {
479 var treecell = document.createElement('treecell'); treecell.setAttribute('label','Retrieving...');
480 treerow.appendChild(treecell);
483 dump('\t' + cols_idx + '\n');
490 'detect_visible' : function() {
493 //dump('detect_visible obj.node = ' + obj.node + '\n');
494 /* FIXME - this is a hack.. if the implementation of tree changes, this could break */
496 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(obj.node)[1] )[1];
497 var curpos = scrollbar.getAttribute('curpos');
498 var maxpos = scrollbar.getAttribute('maxpos');
499 //alert('curpos = ' + curpos + ' maxpos = ' + maxpos + ' obj.curpos = ' + obj.curpos + ' obj.maxpos = ' + obj.maxpos + '\n');
500 if ((curpos != obj.curpos) || (maxpos != obj.maxpos)) {
501 if ( obj.auto_retrieve() > 0 ) {
502 obj.curpos = curpos; obj.maxpos = maxpos;
506 obj.error.sdump('D_XULRUNNER', 'List implementation changed? ' + E);
508 } catch(E) { obj.error.sdump('D_ERROR',E); }
511 'detect_visible_polling' : function() {
513 //alert('detect_visible_polling');
515 obj.detect_visible();
516 setTimeout(function() { try { obj.detect_visible_polling(); } catch(E) { alert(E); } },2000);
523 'auto_retrieve' : function(params) {
525 switch (this.node.nodeName) {
526 case 'tree' : obj._auto_retrieve_tree(params); break;
527 default: throw('NYI: Need .auto_retrieve() for ' + obj.node.nodeName); break;
531 '_auto_retrieve_tree' : function (params) {
533 if (!obj.auto_retrieve_in_progress) {
534 obj.auto_retrieve_in_progress = true;
538 //alert('auto_retrieve\n');
540 var startpos = obj.node.treeBoxObject.getFirstVisibleRow();
541 var endpos = obj.node.treeBoxObject.getLastVisibleRow();
542 if (startpos > endpos) endpos = obj.node.treeBoxObject.getPageLength();
543 //dump('startpos = ' + startpos + ' endpos = ' + endpos + '\n');
544 for (var i = startpos; i < endpos + 4; i++) {
546 //dump('trying index ' + i + '\n');
547 var item = obj.node.contentView.getItemAtIndex(i).firstChild;
548 if (item && item.getAttribute('retrieved') != 'true' ) {
549 //dump('\tgot an unfleshed item = ' + item + ' = ' + item.nodeName + '\n');
550 util.widgets.dispatch('flesh',item); count++;
553 //dump(i + ' : ' + E + '\n');
556 obj.auto_retrieve_in_progress = false;
558 } catch(E) { alert(E); }
564 'full_retrieve' : function(params) {
566 switch (this.node.nodeName) {
567 case 'tree' : obj._full_retrieve_tree(params); break;
568 default: throw('NYI: Need .full_retrieve() for ' + obj.node.nodeName); break;
572 '_full_retrieve_tree' : function(params) {
575 if (obj.row_count.total == obj.row_count.fleshed) {
576 //alert('Full retrieve... tree seems to be in sync\n' + js2JSON(obj.row_count));
577 if (typeof obj.on_all_fleshed == 'function') {
578 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
580 alert('.full_retrieve called with no callback?');
583 //alert('Full retrieve... syncing tree' + js2JSON(obj.row_count));
584 JSAN.use('util.widgets');
585 var nodes = obj.treechildren.childNodes;
586 for (var i = 0; i < nodes.length; i++) {
587 util.widgets.dispatch('flesh',nodes[i].firstChild);
591 obj.error.standard_unexpected_error_alert('_full_retrieve_tree',E);
595 '_append_to_listbox' : function (params) {
599 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
601 var s = ('util.list.append: params = ' + (params) + '\n');
603 var listitem = document.createElement('listitem');
605 s += ('listbox = ' + this.node + ' listitem = ' + listitem + '\n');
607 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
611 listitem.setAttribute('retrieve_id',params.retrieve_id);
612 //FIXME//Make async and fire when row is visible in list
615 params.row_node = listitem;
616 params.on_retrieve = function(row) {
618 obj._map_row_to_listcell(params,listitem);
619 obj.node.appendChild( listitem );
622 if (typeof params.retrieve_row == 'function') {
624 row = params.retrieve_row( params );
628 if (typeof obj.retrieve_row == 'function') {
630 row = obj.retrieve_row( params );
637 this._map_row_to_listcell(params,listitem);
638 this.node.appendChild( listitem );
641 this.error.sdump('D_LIST',s);
646 '_map_row_to_treecell' : function(params,treerow) {
649 util.widgets.remove_children(treerow);
651 if (typeof params.map_row_to_column == 'function' || typeof this.map_row_to_column == 'function') {
653 for (var i = 0; i < this.columns.length; i++) {
654 var treecell = document.createElement('treecell');
656 if (params.skip_columns && (params.skip_columns.indexOf(i) != -1)) {
657 treecell.setAttribute('label',label);
658 treerow.appendChild( treecell );
659 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
662 if (params.skip_all_columns_except && (params.skip_all_columns_except.indexOf(i) == -1)) {
663 treecell.setAttribute('label',label);
664 treerow.appendChild( treecell );
665 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
669 if (typeof params.map_row_to_column == 'function') {
671 label = params.map_row_to_column(params.row,this.columns[i]);
673 } else if (typeof this.map_row_to_column == 'function') {
675 label = this.map_row_to_column(params.row,this.columns[i]);
678 treecell.setAttribute('label',label ? label : '');
679 treerow.appendChild( treecell );
680 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
682 } else if (typeof params.map_row_to_columns == 'function' || typeof this.map_row_to_columns == 'function') {
686 if (typeof params.map_row_to_columns == 'function') {
688 labels = params.map_row_to_columns(params.row,this.columns);
690 } else if (typeof this.map_row_to_columns == 'function') {
692 labels = this.map_row_to_columns(params.row,this.columns);
695 for (var i = 0; i < labels.length; i++) {
696 var treecell = document.createElement('treecell');
697 treecell.setAttribute('label',typeof labels[i] == 'string' || typeof labels[i] == 'number' ? labels[i] : '');
698 treerow.appendChild( treecell );
699 s += ('treecell = ' + treecell + ' with label = ' + labels[i] + '\n');
704 throw('No row to column mapping function.');
706 this.error.sdump('D_LIST',s);
709 '_map_row_to_listcell' : function(params,listitem) {
712 for (var i = 0; i < this.columns.length; i++) {
714 if (typeof params.map_row_to_column == 'function') {
716 value = params.map_row_to_column(params.row,this.columns[i]);
720 if (typeof this.map_row_to_column == 'function') {
722 value = this.map_row_to_column(params.row,this.columns[i]);
725 if (typeof value == 'string' || typeof value == 'number') {
726 var listcell = document.createElement('listcell');
727 listcell.setAttribute('label',value);
728 listitem.appendChild(listcell);
729 s += ('listcell = ' + listcell + ' with label = ' + value + '\n');
731 listitem.appendChild(value);
732 s += ('listcell = ' + value + ' is really a ' + value.nodeName + '\n');
735 this.error.sdump('D_LIST',s);
738 'select_all' : function(params) {
740 switch(this.node.nodeName) {
741 case 'tree' : return this._select_all_from_tree(params); break;
742 default: throw('NYI: Need ._select_all_from_() for ' + this.node.nodeName); break;
746 '_select_all_from_tree' : function(params) {
748 this.node.view.selection.selectAll();
751 'retrieve_selection' : function(params) {
753 switch(this.node.nodeName) {
754 case 'tree' : return this._retrieve_selection_from_tree(params); break;
755 default: throw('NYI: Need ._retrieve_selection_from_() for ' + this.node.nodeName); break;
759 '_retrieve_selection_from_tree' : function(params) {
762 var start = new Object();
763 var end = new Object();
764 var numRanges = this.node.view.selection.getRangeCount();
765 for (var t=0; t<numRanges; t++){
766 this.node.view.selection.getRangeAt(t,start,end);
767 for (var v=start.value; v<=end.value; v++){
768 var i = this.node.contentView.getItemAtIndex(v);
775 'dump' : function(params) {
777 switch(this.node.nodeName) {
778 case 'tree' : return this._dump_tree(params); break;
779 default: throw('NYI: Need .dump() for ' + this.node.nodeName); break;
783 '_dump_tree' : function(params) {
786 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
788 var treeitem = this.treechildren.childNodes[i];
789 var treerow = treeitem.firstChild;
790 for (var j = 0; j < treerow.childNodes.length; j++) {
791 row.push( treerow.childNodes[j].getAttribute('label') );
798 'dump_with_keys' : function(params) {
800 switch(this.node.nodeName) {
801 case 'tree' : return this._dump_tree_with_keys(params); break;
802 default: throw('NYI: Need .dump_with_keys() for ' + this.node.nodeName); break;
807 '_dump_tree_with_keys' : function(params) {
810 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
812 var treeitem = this.treechildren.childNodes[i];
813 var treerow = treeitem.firstChild;
814 for (var j = 0; j < treerow.childNodes.length; j++) {
815 row[ obj.columns[j].id ] = treerow.childNodes[j].getAttribute('label');
822 'dump_csv' : function(params) {
824 switch(this.node.nodeName) {
825 case 'tree' : return this._dump_tree_csv(params); break;
826 default: throw('NYI: Need .dump_csv() for ' + this.node.nodeName); break;
831 '_dump_tree_csv' : function(params) {
834 for (var j = 0; j < obj.columns.length; j++) {
835 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
838 if (dump) dump += ',';
839 dump += '"' + obj.columns[j].label.replace(/"/g, '""') + '"';
843 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
845 var treeitem = this.treechildren.childNodes[i];
846 var treerow = treeitem.firstChild;
847 for (var j = 0; j < treerow.childNodes.length; j++) {
848 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
852 row += '"' + treerow.childNodes[j].getAttribute('label').replace(/"/g, '""') + '"';
855 dump += row + '\r\n';
860 'dump_selected_with_keys' : function(params) {
862 switch(this.node.nodeName) {
863 case 'tree' : return this._dump_tree_selection_with_keys(params); break;
864 default: throw('NYI: Need .dump_selection_with_keys() for ' + this.node.nodeName); break;
869 '_dump_tree_selection_with_keys' : function(params) {
872 var list = obj._retrieve_selection_from_tree();
873 for (var i = 0; i < list.length; i++) {
875 var treeitem = list[i];
876 var treerow = treeitem.firstChild;
877 for (var j = 0; j < treerow.childNodes.length; j++) {
878 var value = treerow.childNodes[j].getAttribute('label');
879 if (params.skip_hidden_columns) if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') continue;
880 var id = obj.columns[j].id; if (params.labels_instead_of_ids) id = obj.columns[j].label;
888 'clipboard' : function() {
891 var dump = obj.dump_selected_with_keys({'skip_hidden_columns':true,'labels_instead_of_ids':true});
892 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
893 data.list_clipboard = dump; data.stash('list_clipboard');
894 JSAN.use('util.window'); var win = new util.window();
895 win.open(urls.XUL_LIST_CLIPBOARD,'list_clipboard','chrome,resizable,modal');
897 this.error.standard_unexpected_error_alert('clipboard',E);
901 'dump_retrieve_ids' : function(params) {
903 switch(this.node.nodeName) {
904 case 'tree' : return this._dump_retrieve_ids_tree(params); break;
905 default: throw('NYI: Need .dump_retrieve_ids() for ' + this.node.nodeName); break;
909 '_dump_retrieve_ids_tree' : function(params) {
912 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
913 var treeitem = this.treechildren.childNodes[i];
914 dump.push( treeitem.getAttribute('retrieve_id') );
919 '_sort_tree' : function(col,sortDir) {
922 if (obj.node.getAttribute('no_sort')) {
925 if (obj.on_all_fleshed) {
926 var r = window.confirm('This list is busy rendering/retrieving data. Abort current action and proceed?');
927 if (r) {} else { return; }
930 for (var i = 0; i < obj.columns.length; i++) {
931 if (obj.columns[i].id == col.id) col_pos = function(a){return a;}(i);
933 obj.on_all_fleshed = function() {
935 JSAN.use('util.money');
937 var treeitems = obj.treechildren.childNodes;
938 for (var i = 0; i < treeitems.length; i++) {
939 var treeitem = treeitems[i];
940 var treerow = treeitem.firstChild;
941 var treecell = treerow.childNodes[ col_pos ];
942 value = ( { 'value' : treecell ? treecell.getAttribute('label') : '', 'node' : treeitem } );
945 rows = rows.sort( function(a,b) {
946 a = a.value; b = b.value;
947 if (col.getAttribute('sort_type')) {
948 switch(col.getAttribute('sort_type')) {
950 a = Number(a); b = Number(b);
953 a = util.money.dollars_float_to_cents_integer(a);
954 b = util.money.dollars_float_to_cents_integer(b);
956 case 'title' : /* special case for "a" and "the". doesn't use marc 245 indicator */
957 a = String( a ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
958 b = String( b ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
961 a = String( a ).toUpperCase();
962 b = String( b ).toUpperCase();
966 if (typeof a == 'string' || typeof b == 'string') {
967 a = String( a ).toUpperCase();
968 b = String( b ).toUpperCase();
971 if (a < b) return -1;
975 if (sortDir == 'asc') rows = rows.reverse();
976 while(obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
977 for (var i = 0; i < rows.length; i++) {
978 obj.treechildren.appendChild( rows[i].node );
981 obj.error.standard_unexpected_error_alert('sorting',E);
983 setTimeout(function(){ obj.on_all_fleshed = null; },0);
987 obj.error.standard_unexpected_error_alert('pre sorting', E);
992 dump('exiting util.list.js\n');