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 dump('auto-selecting\n');
347 var idx = Number(obj.node.view.rowCount)-1;
348 try { obj.node.view.selection.select(idx); } catch(E) { obj.error.sdump('D_ALERT','tree auto select: ' + E + '\n'); }
349 try { if (typeof params.on_select == 'function') params.on_select(); } catch(E) { obj.error.sdump('D_ALERT','tree auto select, on_select: ' + E + '\n'); }
350 obj.auto_select_pending = false;
351 try { util.widgets.dispatch('flesh',obj.node.contentView.getItemAtIndex(idx).firstChild); } catch(E) { obj.error.sdump('D_ALERT','tree auto select, flesh: ' + E + '\n'); }
356 if (treechildren_node.firstChild) {
357 treechildren_node.insertBefore( treeitem, treechildren_node.firstChild );
359 treechildren_node.appendChild( treeitem );
361 if (typeof params.no_auto_select == 'undefined') {
362 if (!obj.auto_select_pending) {
363 obj.auto_select_pending = true;
364 setTimeout(function() {
365 try { obj.node.view.selection.select(0); } catch(E) { obj.error.sdump('D_ALERT','tree auto select: ' + E + '\n'); }
366 try { if (typeof params.on_select == 'function') params.on_select(); } catch(E) { obj.error.sdump('D_ALERT','tree auto select, on_select: ' + E + '\n'); }
367 obj.auto_select_pending = false;
368 try { util.widgets.dispatch('flesh',obj.node.contentView.getItemAtIndex(0).firstChild); } catch(E) { obj.error.sdump('D_ALERT','tree auto select, flesh: ' + E + '\n'); }
373 var treerow = document.createElement('treerow');
374 treeitem.appendChild( treerow );
375 treerow.setAttribute('retrieve_id',params.retrieve_id);
377 s += ('tree = ' + this.node + ' treechildren = ' + treechildren_node + '\n');
378 s += ('treeitem = ' + treeitem + ' treerow = ' + treerow + '\n');
380 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
382 obj.put_retrieving_label(treerow);
383 treerow.addEventListener(
387 if (treerow.getAttribute('retrieved') == 'true') return; /* already running */
389 treerow.setAttribute('retrieved','true');
391 //dump('fleshing = ' + params.retrieve_id + '\n');
393 function inc_fleshed() {
394 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
395 treerow.setAttribute('fleshed','true');
396 obj.row_count.fleshed++;
397 if (obj.row_count.fleshed == obj.row_count.total) {
398 if (typeof obj.on_all_fleshed == 'function') {
399 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
404 params.row_node = treeitem;
405 params.on_retrieve = function(p) {
408 obj._map_row_to_treecell(p,treerow);
410 var idx = obj.node.contentView.getIndexOfItem( params.row_node );
411 dump('idx = ' + idx + '\n');
412 // if current row is selected, send another select event to re-sync data that the client code fetches on selects
413 if ( obj.node.view.selection.isSelected( idx ) ) {
414 dump('dispatching select event for on_retrieve for idx = ' + idx + '\n');
415 util.widgets.dispatch('select',params.row_node);
418 alert('fixme2: ' + E);
422 if (typeof params.retrieve_row == 'function') {
424 params.retrieve_row( params );
426 } else if (typeof obj.retrieve_row == 'function') {
428 obj.retrieve_row( params );
440 util.widgets.dispatch('flesh',treerow);
445 obj.put_retrieving_label(treerow);
446 treerow.addEventListener(
449 //dump('fleshing anon\n');
450 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
451 obj._map_row_to_treecell(params,treerow);
452 treerow.setAttribute('retrieved','true');
453 treerow.setAttribute('fleshed','true');
454 obj.row_count.fleshed++;
455 if (obj.row_count.fleshed == obj.row_count.total) {
456 if (typeof obj.on_all_fleshed == 'function') {
457 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
466 util.widgets.dispatch('flesh',treerow);
471 this.error.sdump('D_LIST',s);
475 if (obj.trim_list && obj.row_count.total >= obj.trim_list) {
477 //if (typeof params.to_bottom != 'undefined') {
478 if (typeof params.to_top == 'undefined') {
479 treechildren_node.removeChild( treechildren_node.firstChild );
481 treechildren_node.removeChild( treechildren_node.lastChild );
487 setTimeout( function() { obj.auto_retrieve(); }, 0 );
492 'put_retrieving_label' : function(treerow) {
497 dump('put_retrieving_label. columns = ' + js2JSON(obj.columns) + '\n');
498 while( obj.columns[cols_idx] && obj.columns[cols_idx].hidden && obj.columns[cols_idx].hidden == 'true') {
499 dump('\t' + cols_idx);
500 var treecell = document.createElement('treecell');
501 treerow.appendChild(treecell);
505 for (var i = 0; i < obj.columns.length; i++) {
506 var treecell = document.createElement('treecell'); treecell.setAttribute('label','Retrieving...');
507 treerow.appendChild(treecell);
510 dump('\t' + cols_idx + '\n');
517 'detect_visible' : function() {
520 //dump('detect_visible obj.node = ' + obj.node + '\n');
521 /* FIXME - this is a hack.. if the implementation of tree changes, this could break */
523 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(obj.node)[1] )[1];
524 var curpos = scrollbar.getAttribute('curpos');
525 var maxpos = scrollbar.getAttribute('maxpos');
526 //alert('curpos = ' + curpos + ' maxpos = ' + maxpos + ' obj.curpos = ' + obj.curpos + ' obj.maxpos = ' + obj.maxpos + '\n');
527 if ((curpos != obj.curpos) || (maxpos != obj.maxpos)) {
528 if ( obj.auto_retrieve() > 0 ) {
529 obj.curpos = curpos; obj.maxpos = maxpos;
533 obj.error.sdump('D_XULRUNNER', 'List implementation changed? ' + E);
535 } catch(E) { obj.error.sdump('D_ERROR',E); }
538 'detect_visible_polling' : function() {
540 //alert('detect_visible_polling');
542 obj.detect_visible();
543 setTimeout(function() { try { obj.detect_visible_polling(); } catch(E) { alert(E); } },2000);
550 'auto_retrieve' : function(params) {
552 switch (this.node.nodeName) {
553 case 'tree' : obj._auto_retrieve_tree(params); break;
554 default: throw('NYI: Need .auto_retrieve() for ' + obj.node.nodeName); break;
558 '_auto_retrieve_tree' : function (params) {
560 if (!obj.auto_retrieve_in_progress) {
561 obj.auto_retrieve_in_progress = true;
565 //alert('auto_retrieve\n');
567 var startpos = obj.node.treeBoxObject.getFirstVisibleRow();
568 var endpos = obj.node.treeBoxObject.getLastVisibleRow();
569 if (startpos > endpos) endpos = obj.node.treeBoxObject.getPageLength();
570 //dump('startpos = ' + startpos + ' endpos = ' + endpos + '\n');
571 for (var i = startpos; i < endpos + 4; i++) {
573 //dump('trying index ' + i + '\n');
574 var item = obj.node.contentView.getItemAtIndex(i).firstChild;
575 if (item && item.getAttribute('retrieved') != 'true' ) {
576 //dump('\tgot an unfleshed item = ' + item + ' = ' + item.nodeName + '\n');
577 util.widgets.dispatch('flesh',item); count++;
580 //dump(i + ' : ' + E + '\n');
583 obj.auto_retrieve_in_progress = false;
585 } catch(E) { alert(E); }
591 'full_retrieve' : function(params) {
593 switch (this.node.nodeName) {
594 case 'tree' : obj._full_retrieve_tree(params); break;
595 default: throw('NYI: Need .full_retrieve() for ' + obj.node.nodeName); break;
599 '_full_retrieve_tree' : function(params) {
602 if (obj.row_count.total == obj.row_count.fleshed) {
603 //alert('Full retrieve... tree seems to be in sync\n' + js2JSON(obj.row_count));
604 if (typeof obj.on_all_fleshed == 'function') {
605 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
607 alert('.full_retrieve called with no callback?');
610 //alert('Full retrieve... syncing tree' + js2JSON(obj.row_count));
611 JSAN.use('util.widgets');
612 var nodes = obj.treechildren.childNodes;
613 for (var i = 0; i < nodes.length; i++) {
614 util.widgets.dispatch('flesh',nodes[i].firstChild);
618 obj.error.standard_unexpected_error_alert('_full_retrieve_tree',E);
622 '_append_to_listbox' : function (params) {
626 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
628 var s = ('util.list.append: params = ' + (params) + '\n');
630 var listitem = document.createElement('listitem');
632 s += ('listbox = ' + this.node + ' listitem = ' + listitem + '\n');
634 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
638 listitem.setAttribute('retrieve_id',params.retrieve_id);
639 //FIXME//Make async and fire when row is visible in list
642 params.row_node = listitem;
643 params.on_retrieve = function(row) {
645 obj._map_row_to_listcell(params,listitem);
646 obj.node.appendChild( listitem );
647 util.widgets.dispatch('select',params.row_node);
650 if (typeof params.retrieve_row == 'function') {
652 row = params.retrieve_row( params );
656 if (typeof obj.retrieve_row == 'function') {
658 row = obj.retrieve_row( params );
665 this._map_row_to_listcell(params,listitem);
666 this.node.appendChild( listitem );
669 this.error.sdump('D_LIST',s);
674 '_map_row_to_treecell' : function(params,treerow) {
677 util.widgets.remove_children(treerow);
679 if (typeof params.map_row_to_column == 'function' || typeof this.map_row_to_column == 'function') {
681 for (var i = 0; i < this.columns.length; i++) {
682 var treecell = document.createElement('treecell');
684 if (params.skip_columns && (params.skip_columns.indexOf(i) != -1)) {
685 treecell.setAttribute('label',label);
686 treerow.appendChild( treecell );
687 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
690 if (params.skip_all_columns_except && (params.skip_all_columns_except.indexOf(i) == -1)) {
691 treecell.setAttribute('label',label);
692 treerow.appendChild( treecell );
693 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
697 if (typeof params.map_row_to_column == 'function') {
699 label = params.map_row_to_column(params.row,this.columns[i]);
701 } else if (typeof this.map_row_to_column == 'function') {
703 label = this.map_row_to_column(params.row,this.columns[i]);
706 treecell.setAttribute('label',label ? label : '');
707 treerow.appendChild( treecell );
708 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
710 } else if (typeof params.map_row_to_columns == 'function' || typeof this.map_row_to_columns == 'function') {
714 if (typeof params.map_row_to_columns == 'function') {
716 labels = params.map_row_to_columns(params.row,this.columns);
718 } else if (typeof this.map_row_to_columns == 'function') {
720 labels = this.map_row_to_columns(params.row,this.columns);
723 for (var i = 0; i < labels.length; i++) {
724 var treecell = document.createElement('treecell');
725 treecell.setAttribute('label',typeof labels[i] == 'string' || typeof labels[i] == 'number' ? labels[i] : '');
726 treerow.appendChild( treecell );
727 s += ('treecell = ' + treecell + ' with label = ' + labels[i] + '\n');
732 throw('No row to column mapping function.');
734 this.error.sdump('D_LIST',s);
737 '_map_row_to_listcell' : function(params,listitem) {
740 for (var i = 0; i < this.columns.length; i++) {
742 if (typeof params.map_row_to_column == 'function') {
744 value = params.map_row_to_column(params.row,this.columns[i]);
748 if (typeof this.map_row_to_column == 'function') {
750 value = this.map_row_to_column(params.row,this.columns[i]);
753 if (typeof value == 'string' || typeof value == 'number') {
754 var listcell = document.createElement('listcell');
755 listcell.setAttribute('label',value);
756 listitem.appendChild(listcell);
757 s += ('listcell = ' + listcell + ' with label = ' + value + '\n');
759 listitem.appendChild(value);
760 s += ('listcell = ' + value + ' is really a ' + value.nodeName + '\n');
763 this.error.sdump('D_LIST',s);
766 'select_all' : function(params) {
768 switch(this.node.nodeName) {
769 case 'tree' : return this._select_all_from_tree(params); break;
770 default: throw('NYI: Need ._select_all_from_() for ' + this.node.nodeName); break;
774 '_select_all_from_tree' : function(params) {
776 this.node.view.selection.selectAll();
779 'retrieve_selection' : function(params) {
781 switch(this.node.nodeName) {
782 case 'tree' : return this._retrieve_selection_from_tree(params); break;
783 default: throw('NYI: Need ._retrieve_selection_from_() for ' + this.node.nodeName); break;
787 '_retrieve_selection_from_tree' : function(params) {
790 var start = new Object();
791 var end = new Object();
792 var numRanges = this.node.view.selection.getRangeCount();
793 for (var t=0; t<numRanges; t++){
794 this.node.view.selection.getRangeAt(t,start,end);
795 for (var v=start.value; v<=end.value; v++){
796 var i = this.node.contentView.getItemAtIndex(v);
803 'dump' : function(params) {
805 switch(this.node.nodeName) {
806 case 'tree' : return this._dump_tree(params); break;
807 default: throw('NYI: Need .dump() for ' + this.node.nodeName); break;
811 '_dump_tree' : function(params) {
814 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
816 var treeitem = this.treechildren.childNodes[i];
817 var treerow = treeitem.firstChild;
818 for (var j = 0; j < treerow.childNodes.length; j++) {
819 row.push( treerow.childNodes[j].getAttribute('label') );
826 'dump_with_keys' : function(params) {
828 switch(this.node.nodeName) {
829 case 'tree' : return this._dump_tree_with_keys(params); break;
830 default: throw('NYI: Need .dump_with_keys() for ' + this.node.nodeName); break;
835 '_dump_tree_with_keys' : function(params) {
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 row[ obj.columns[j].id ] = treerow.childNodes[j].getAttribute('label');
850 'dump_csv' : function(params) {
852 switch(this.node.nodeName) {
853 case 'tree' : return this._dump_tree_csv(params); break;
854 default: throw('NYI: Need .dump_csv() for ' + this.node.nodeName); break;
859 '_dump_tree_csv' : function(params) {
862 for (var j = 0; j < obj.columns.length; j++) {
863 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
866 if (dump) dump += ',';
867 dump += '"' + obj.columns[j].label.replace(/"/g, '""') + '"';
871 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
873 var treeitem = this.treechildren.childNodes[i];
874 var treerow = treeitem.firstChild;
875 for (var j = 0; j < treerow.childNodes.length; j++) {
876 if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') {
880 row += '"' + treerow.childNodes[j].getAttribute('label').replace(/"/g, '""') + '"';
883 dump += row + '\r\n';
888 'dump_selected_with_keys' : function(params) {
890 switch(this.node.nodeName) {
891 case 'tree' : return this._dump_tree_selection_with_keys(params); break;
892 default: throw('NYI: Need .dump_selection_with_keys() for ' + this.node.nodeName); break;
897 '_dump_tree_selection_with_keys' : function(params) {
900 var list = obj._retrieve_selection_from_tree();
901 for (var i = 0; i < list.length; i++) {
903 var treeitem = list[i];
904 var treerow = treeitem.firstChild;
905 for (var j = 0; j < treerow.childNodes.length; j++) {
906 var value = treerow.childNodes[j].getAttribute('label');
907 if (params.skip_hidden_columns) if (obj.node.treeBoxObject.columns.getColumnAt(j).element.getAttribute('hidden') == 'true') continue;
908 var id = obj.columns[j].id; if (params.labels_instead_of_ids) id = obj.columns[j].label;
916 'clipboard' : function() {
919 var dump = obj.dump_selected_with_keys({'skip_hidden_columns':true,'labels_instead_of_ids':true});
920 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
921 data.list_clipboard = dump; data.stash('list_clipboard');
922 JSAN.use('util.window'); var win = new util.window();
923 win.open(urls.XUL_LIST_CLIPBOARD,'list_clipboard','chrome,resizable,modal');
925 this.error.standard_unexpected_error_alert('clipboard',E);
929 'dump_retrieve_ids' : function(params) {
931 switch(this.node.nodeName) {
932 case 'tree' : return this._dump_retrieve_ids_tree(params); break;
933 default: throw('NYI: Need .dump_retrieve_ids() for ' + this.node.nodeName); break;
937 '_dump_retrieve_ids_tree' : function(params) {
940 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
941 var treeitem = this.treechildren.childNodes[i];
942 dump.push( treeitem.getAttribute('retrieve_id') );
947 '_sort_tree' : function(col,sortDir) {
950 if (obj.node.getAttribute('no_sort')) {
953 if (obj.on_all_fleshed) {
954 var r = window.confirm('This list is busy rendering/retrieving data. Abort current action and proceed?');
955 if (r) {} else { return; }
958 for (var i = 0; i < obj.columns.length; i++) {
959 if (obj.columns[i].id == col.id) col_pos = function(a){return a;}(i);
961 obj.on_all_fleshed = function() {
963 JSAN.use('util.money');
965 var treeitems = obj.treechildren.childNodes;
966 for (var i = 0; i < treeitems.length; i++) {
967 var treeitem = treeitems[i];
968 var treerow = treeitem.firstChild;
969 var treecell = treerow.childNodes[ col_pos ];
970 value = ( { 'value' : treecell ? treecell.getAttribute('label') : '', 'node' : treeitem } );
973 rows = rows.sort( function(a,b) {
974 a = a.value; b = b.value;
975 if (col.getAttribute('sort_type')) {
976 switch(col.getAttribute('sort_type')) {
978 a = Number(a); b = Number(b);
981 a = util.money.dollars_float_to_cents_integer(a);
982 b = util.money.dollars_float_to_cents_integer(b);
984 case 'title' : /* special case for "a" and "the". doesn't use marc 245 indicator */
985 a = String( a ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
986 b = String( b ).toUpperCase().replace( /^\s*(THE|A|AN)\s+/, '' );
989 a = String( a ).toUpperCase();
990 b = String( b ).toUpperCase();
994 if (typeof a == 'string' || typeof b == 'string') {
995 a = String( a ).toUpperCase();
996 b = String( b ).toUpperCase();
999 if (a < b) return -1;
1000 if (a > b) return 1;
1003 if (sortDir == 'asc') rows = rows.reverse();
1004 while(obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
1005 for (var i = 0; i < rows.length; i++) {
1006 obj.treechildren.appendChild( rows[i].node );
1009 obj.error.standard_unexpected_error_alert('sorting',E);
1011 setTimeout(function(){ obj.on_all_fleshed = null; },0);
1013 obj.full_retrieve();
1015 obj.error.standard_unexpected_error_alert('pre sorting', E);
1020 dump('exiting util.list.js\n');