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.retrieve_row == 'function') obj.retrieve_row = params.retrieve_row;
36 if (typeof params.prebuilt != 'undefined') obj.prebuilt = params.prebuilt;
38 if (typeof params.columns == 'undefined') throw('util.list.init: No columns');
39 obj.columns = params.columns;
41 switch(obj.node.nodeName) {
42 case 'tree' : obj._init_tree(params); break;
43 case 'listbox' : obj._init_listbox(params); break;
44 default: throw('NYI: Need ._init() for ' + obj.node.nodeName); break;
48 'register_all_fleshed_callback' : function(f) {
49 this.on_all_fleshed = f;
52 '_init_tree' : function (params) {
56 this.treechildren = this.node.lastChild;
59 var treecols = document.createElement('treecols');
60 this.node.appendChild(treecols);
62 for (var i = 0; i < this.columns.length; i++) {
63 var treecol = document.createElement('treecol');
64 for (var j in this.columns[i]) {
65 treecol.setAttribute(j,this.columns[i][j]);
67 treecols.appendChild(treecol);
68 treecol.addEventListener(
72 var sortDir = ev.target.getAttribute('sortDir') || 'desc';
73 if (sortDir == 'desc') sortDir = 'asc'; else sortDir = 'desc';
74 ev.target.setAttribute('sortDir',sortDir);
75 obj._sort_tree(ev.target,sortDir);
78 if (obj.row_count.total != obj.row_count.fleshed && (obj.row_count.total - obj.row_count.fleshed) > 50) {
79 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?');
82 setTimeout( do_it, 0 );
85 setTimeout( do_it, 0 );
90 var splitter = document.createElement('splitter');
91 splitter.setAttribute('class','tree-splitter');
92 treecols.appendChild(splitter);
95 var treechildren = document.createElement('treechildren');
96 this.node.appendChild(treechildren);
97 this.treechildren = treechildren;
99 if (typeof params.on_select == 'function') {
100 this.node.addEventListener(
106 if (typeof params.on_click == 'function') {
107 this.node.addEventListener(
114 this.node.addEventListener(
116 function(ev) { obj.detect_visible(); },
120 this.node.addEventListener(
122 function(ev) { obj.auto_retrieve(); },
125 this.node.addEventListener(
127 function(ev) { obj.auto_retrieve(); },
130 window.addEventListener(
132 function(ev) { obj.auto_retrieve(); },
135 /* FIXME -- find events on scrollbar to trigger this */
136 obj.detect_visible_polling();
138 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(this.node)[1] )[1];
139 var slider = document.getAnonymousNodes( scrollbar )[2];
140 alert('scrollbar = ' + scrollbar.nodeName + ' grippy = ' + slider.nodeName);
141 scrollbar.addEventListener('click',function(){alert('sb click');},false);
142 scrollbar.addEventListener('command',function(){alert('sb command');},false);
143 scrollbar.addEventListener('scroll',function(){alert('sb scroll');},false);
144 slider.addEventListener('click',function(){alert('slider click');},false);
145 slider.addEventListener('command',function(){alert('slider command');},false);
146 slider.addEventListener('scroll',function(){alert('slider scroll');},false);
148 this.node.addEventListener('scroll',function(){ obj.auto_retrieve(); },false);
150 this.restores_columns(params);
153 '_init_listbox' : function (params) {
156 var listhead = document.createElement('listhead');
157 this.node.appendChild(listhead);
159 var listcols = document.createElement('listcols');
160 this.node.appendChild(listcols);
162 for (var i = 0; i < this.columns.length; i++) {
163 var listheader = document.createElement('listheader');
164 listhead.appendChild(listheader);
165 var listcol = document.createElement('listcol');
166 listcols.appendChild(listcol);
167 for (var j in this.columns[i]) {
168 listheader.setAttribute(j,this.columns[i][j]);
169 listcol.setAttribute(j,this.columns[i][j]);
175 'save_columns' : function (params) {
177 switch (this.node.nodeName) {
178 case 'tree' : this._save_columns_tree(params); break;
179 default: throw('NYI: Need .save_columns() for ' + this.node.nodeName); break;
183 '_save_columns_tree' : function (params) {
186 var id = obj.node.getAttribute('id'); if (!id) {
187 alert("FIXME: The columns for this list cannot be saved because the list has no id.");
191 var nl = obj.node.getElementsByTagName('treecol');
192 for (var i = 0; i < nl.length; i++) {
194 var col_id = col.getAttribute('id');
196 alert('FIXME: A column in this list does not have an id and cannot be saved');
199 var col_hidden = col.getAttribute('hidden');
200 var col_width = col.getAttribute('width');
201 var col_ordinal = col.getAttribute('ordinal');
202 my_cols[ col_id ] = { 'hidden' : col_hidden, 'width' : col_width, 'ordinal' : col_ordinal };
204 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
205 JSAN.use('util.file'); var file = new util.file('tree_columns_for_'+window.escape(id));
206 file.set_object(my_cols);
208 alert('Columns saved.');
210 obj.error.standard_unexpected_error_alert('_save_columns_tree',E);
214 'restores_columns' : function (params) {
216 switch (this.node.nodeName) {
217 case 'tree' : this._restores_columns_tree(params); break;
218 default: throw('NYI: Need .restores_columns() for ' + this.node.nodeName); break;
222 '_restores_columns_tree' : function (params) {
225 var id = obj.node.getAttribute('id'); if (!id) {
226 alert("FIXME: The columns for this list cannot be restored because the list has no id.");
230 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
231 JSAN.use('util.file'); var file = new util.file('tree_columns_for_'+window.escape(id));
232 if (file._file.exists()) {
233 var my_cols = file.get_object(); file.close();
234 var nl = obj.node.getElementsByTagName('treecol');
235 for (var i = 0; i < nl.length; i++) {
237 var col_id = col.getAttribute('id');
239 alert('FIXME: A column in this list does not have an id and cannot be saved');
242 if (typeof my_cols[col_id] != 'undefined') {
243 col.setAttribute('hidden',my_cols[col_id].hidden);
244 col.setAttribute('width',my_cols[col_id].width);
245 col.setAttribute('ordinal',my_cols[col_id].ordinal);
247 obj.error.sdump('D_ERROR','WARNING: Column ' + col_id + ' did not have a saved state.');
252 obj.error.standard_unexpected_error_alert('_restore_columns_tree',E);
256 'clear' : function (params) {
258 switch (this.node.nodeName) {
259 case 'tree' : this._clear_tree(params); break;
260 case 'listbox' : this._clear_listbox(params); break;
261 default: throw('NYI: Need .clear() for ' + this.node.nodeName); break;
263 this.error.sdump('D_LIST','Clearing list ' + this.node.getAttribute('id') + '\n');
264 this.row_count.total = 0;
265 this.row_count.fleshed = 0;
266 if (typeof obj.on_all_fleshed == 'function') {
267 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
271 '_clear_tree' : function(params) {
273 if (obj.error.sdump_levels.D_LIST_DUMP_ON_CLEAR) {
274 obj.error.sdump('D_LIST_DUMP_ON_CLEAR',obj.dump());
276 if (obj.error.sdump_levels.D_LIST_DUMP_WITH_KEYS_ON_CLEAR) {
277 obj.error.sdump('D_LIST_DUMP_WITH_KEYS_ON_CLEAR',obj.dump_with_keys());
279 while (obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
282 '_clear_listbox' : function(params) {
285 var nl = this.node.getElementsByTagName('listitem');
286 for (var i = 0; i < nl.length; i++) {
289 for (var i = 0; i < items.length; i++) {
290 this.node.removeChild(items[i]);
294 'append' : function (params) {
297 switch (this.node.nodeName) {
298 case 'tree' : rnode = this._append_to_tree(params); break;
299 case 'listbox' : rnode = this._append_to_listbox(params); break;
300 default: throw('NYI: Need .append() for ' + this.node.nodeName); break;
302 if (rnode && params.attributes) {
303 for (var i in params.attributes) {
304 rnode.setAttribute(i,params.attributes[i]);
307 this.row_count.total++;
308 if (this.row_count.fleshed == this.row_count.total) {
309 if (typeof this.on_all_fleshed == 'function') {
310 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
316 '_append_to_tree' : function (params) {
320 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
322 var s = ('util.list.append: params = ' + (params) + '\n');
324 var treechildren_node = this.treechildren;
326 if (params.node && params.node.nodeName == 'treeitem') {
327 params.node.setAttribute('container','true'); /* params.node.setAttribute('open','true'); */
328 if (params.node.lastChild.nodeName == 'treechildren') {
329 treechildren_node = params.node.lastChild;
331 treechildren_node = document.createElement('treechildren');
332 params.node.appendChild(treechildren_node);
336 var treeitem = document.createElement('treeitem');
337 treeitem.setAttribute('retrieve_id',params.retrieve_id);
338 if (typeof params.to_top == 'undefined') {
339 treechildren_node.appendChild( treeitem );
341 if (treechildren_node.firstChild) {
342 treechildren_node.insertBefore( treeitem, treechildren_node.firstChild );
344 treechildren_node.appendChild( treeitem );
347 var treerow = document.createElement('treerow');
348 treeitem.appendChild( treerow );
349 treerow.setAttribute('retrieve_id',params.retrieve_id);
351 s += ('tree = ' + this.node + ' treechildren = ' + treechildren_node + '\n');
352 s += ('treeitem = ' + treeitem + ' treerow = ' + treerow + '\n');
354 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
356 obj.put_retrieving_label(treerow);
357 treerow.addEventListener(
361 if (treerow.getAttribute('retrieved') == 'true') return; /* already running */
363 treerow.setAttribute('retrieved','true');
365 //dump('fleshing = ' + params.retrieve_id + '\n');
367 function inc_fleshed() {
368 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
369 treerow.setAttribute('fleshed','true');
370 obj.row_count.fleshed++;
371 if (obj.row_count.fleshed == obj.row_count.total) {
372 if (typeof obj.on_all_fleshed == 'function') {
373 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
378 params.row_node = treeitem;
379 params.on_retrieve = function(p) {
382 obj._map_row_to_treecell(p,treerow);
385 alert('fixme2: ' + E);
389 if (typeof params.retrieve_row == 'function') {
391 params.retrieve_row( params );
393 } else if (typeof obj.retrieve_row == 'function') {
395 obj.retrieve_row( params );
407 util.widgets.dispatch('flesh',treerow);
412 obj.put_retrieving_label(treerow);
413 treerow.addEventListener(
416 //dump('fleshing anon\n');
417 if (treerow.getAttribute('fleshed') == 'true') return; /* already fleshed */
418 obj._map_row_to_treecell(params,treerow);
419 treerow.setAttribute('retrieved','true');
420 treerow.setAttribute('fleshed','true');
421 obj.row_count.fleshed++;
422 if (obj.row_count.fleshed == obj.row_count.total) {
423 if (typeof obj.on_all_fleshed == 'function') {
424 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
433 util.widgets.dispatch('flesh',treerow);
438 this.error.sdump('D_LIST',s);
440 setTimeout( function() { obj.auto_retrieve(); }, 0 );
445 'put_retrieving_label' : function(treerow) {
450 dump('put_retrieving_label. columns = ' + js2JSON(obj.columns) + '\n');
451 while( obj.columns[cols_idx] && obj.columns[cols_idx].hidden && obj.columns[cols_idx].hidden == 'true') {
452 dump('\t' + cols_idx);
453 var treecell = document.createElement('treecell');
454 treerow.appendChild(treecell);
458 for (var i = 0; i < obj.columns.length; i++) {
459 var treecell = document.createElement('treecell'); treecell.setAttribute('label','Retrieving...');
460 treerow.appendChild(treecell);
463 dump('\t' + cols_idx + '\n');
470 'detect_visible' : function() {
473 //dump('detect_visible obj.node = ' + obj.node + '\n');
474 /* FIXME - this is a hack.. if the implementation of tree changes, this could break */
476 var scrollbar = document.getAnonymousNodes( document.getAnonymousNodes(obj.node)[1] )[1];
477 var curpos = scrollbar.getAttribute('curpos');
478 var maxpos = scrollbar.getAttribute('maxpos');
479 //alert('curpos = ' + curpos + ' maxpos = ' + maxpos + ' obj.curpos = ' + obj.curpos + ' obj.maxpos = ' + obj.maxpos + '\n');
480 if ((curpos != obj.curpos) || (maxpos != obj.maxpos)) {
481 if ( obj.auto_retrieve() > 0 ) {
482 obj.curpos = curpos; obj.maxpos = maxpos;
486 obj.error.sdump('D_XULRUNNER', 'List implementation changed? ' + E);
488 } catch(E) { obj.error.sdump('D_ERROR',E); }
491 'detect_visible_polling' : function() {
493 //alert('detect_visible_polling');
495 obj.detect_visible();
496 setTimeout(function() { try { obj.detect_visible_polling(); } catch(E) { alert(E); } },2000);
503 'auto_retrieve' : function(params) {
505 switch (this.node.nodeName) {
506 case 'tree' : obj._auto_retrieve_tree(params); break;
507 default: throw('NYI: Need .auto_retrieve() for ' + obj.node.nodeName); break;
511 '_auto_retrieve_tree' : function (params) {
513 if (!obj.auto_retrieve_in_progress) {
514 obj.auto_retrieve_in_progress = true;
518 //alert('auto_retrieve\n');
520 var startpos = obj.node.treeBoxObject.getFirstVisibleRow();
521 var endpos = obj.node.treeBoxObject.getLastVisibleRow();
522 if (startpos > endpos) endpos = obj.node.treeBoxObject.getPageLength();
523 //dump('startpos = ' + startpos + ' endpos = ' + endpos + '\n');
524 for (var i = startpos; i < endpos + 4; i++) {
526 //dump('trying index ' + i + '\n');
527 var item = obj.node.contentView.getItemAtIndex(i).firstChild;
528 if (item && item.getAttribute('retrieved') != 'true' ) {
529 //dump('\tgot an unfleshed item = ' + item + ' = ' + item.nodeName + '\n');
530 util.widgets.dispatch('flesh',item); count++;
533 //dump(i + ' : ' + E + '\n');
536 obj.auto_retrieve_in_progress = false;
538 } catch(E) { alert(E); }
544 'full_retrieve' : function(params) {
546 switch (this.node.nodeName) {
547 case 'tree' : obj._full_retrieve_tree(params); break;
548 default: throw('NYI: Need .full_retrieve() for ' + obj.node.nodeName); break;
552 '_full_retrieve_tree' : function(params) {
555 if (obj.row_count.total == obj.row_count.fleshed) {
556 //alert('Full retrieve... tree seems to be in sync\n' + js2JSON(obj.row_count));
557 if (typeof obj.on_all_fleshed == 'function') {
558 setTimeout( function() { obj.on_all_fleshed(); }, 0 );
560 alert('.full_retrieve called with no callback?');
563 //alert('Full retrieve... syncing tree' + js2JSON(obj.row_count));
564 JSAN.use('util.widgets');
565 var nodes = obj.treechildren.childNodes;
566 for (var i = 0; i < nodes.length; i++) {
567 util.widgets.dispatch('flesh',nodes[i].firstChild);
571 obj.error.standard_unexpected_error_alert('_full_retrieve_tree',E);
575 '_append_to_listbox' : function (params) {
579 if (typeof params.row == 'undefined') throw('util.list.append: Object must contain a row');
581 var s = ('util.list.append: params = ' + (params) + '\n');
583 var listitem = document.createElement('listitem');
585 s += ('listbox = ' + this.node + ' listitem = ' + listitem + '\n');
587 if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
591 listitem.setAttribute('retrieve_id',params.retrieve_id);
592 //FIXME//Make async and fire when row is visible in list
595 params.row_node = listitem;
596 params.on_retrieve = function(row) {
598 obj._map_row_to_listcell(params,listitem);
599 obj.node.appendChild( listitem );
602 if (typeof params.retrieve_row == 'function') {
604 row = params.retrieve_row( params );
608 if (typeof obj.retrieve_row == 'function') {
610 row = obj.retrieve_row( params );
617 this._map_row_to_listcell(params,listitem);
618 this.node.appendChild( listitem );
621 this.error.sdump('D_LIST',s);
626 '_map_row_to_treecell' : function(params,treerow) {
629 util.widgets.remove_children(treerow);
630 for (var i = 0; i < this.columns.length; i++) {
631 var treecell = document.createElement('treecell');
633 if (params.skip_columns && (params.skip_columns.indexOf(i) != -1)) {
634 treecell.setAttribute('label',label);
635 treerow.appendChild( treecell );
636 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
639 if (params.skip_all_columns_except && (params.skip_all_columns_except.indexOf(i) == -1)) {
640 treecell.setAttribute('label',label);
641 treerow.appendChild( treecell );
642 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
645 if (typeof params.map_row_to_column == 'function') {
647 label = params.map_row_to_column(params.row,this.columns[i]);
651 if (typeof this.map_row_to_column == 'function') {
653 label = this.map_row_to_column(params.row,this.columns[i]);
657 throw('No map_row_to_column function');
661 treecell.setAttribute('label',label);
662 treerow.appendChild( treecell );
663 s += ('treecell = ' + treecell + ' with label = ' + label + '\n');
665 this.error.sdump('D_LIST',s);
668 '_map_row_to_listcell' : function(params,listitem) {
671 for (var i = 0; i < this.columns.length; i++) {
673 if (typeof params.map_row_to_column == 'function') {
675 value = params.map_row_to_column(params.row,this.columns[i]);
679 if (typeof this.map_row_to_column == 'function') {
681 value = this.map_row_to_column(params.row,this.columns[i]);
684 if (typeof value == 'string' || typeof value == 'number') {
685 var listcell = document.createElement('listcell');
686 listcell.setAttribute('label',value);
687 listitem.appendChild(listcell);
688 s += ('listcell = ' + listcell + ' with label = ' + value + '\n');
690 listitem.appendChild(value);
691 s += ('listcell = ' + value + ' is really a ' + value.nodeName + '\n');
694 this.error.sdump('D_LIST',s);
697 'select_all' : function(params) {
699 switch(this.node.nodeName) {
700 case 'tree' : return this._select_all_from_tree(params); break;
701 default: throw('NYI: Need ._select_all_from_() for ' + this.node.nodeName); break;
705 '_select_all_from_tree' : function(params) {
707 this.node.view.selection.selectAll();
710 'retrieve_selection' : function(params) {
712 switch(this.node.nodeName) {
713 case 'tree' : return this._retrieve_selection_from_tree(params); break;
714 default: throw('NYI: Need ._retrieve_selection_from_() for ' + this.node.nodeName); break;
718 '_retrieve_selection_from_tree' : function(params) {
721 var start = new Object();
722 var end = new Object();
723 var numRanges = this.node.view.selection.getRangeCount();
724 for (var t=0; t<numRanges; t++){
725 this.node.view.selection.getRangeAt(t,start,end);
726 for (var v=start.value; v<=end.value; v++){
727 var i = this.node.contentView.getItemAtIndex(v);
734 'dump' : function(params) {
736 switch(this.node.nodeName) {
737 case 'tree' : return this._dump_tree(params); break;
738 default: throw('NYI: Need .dump() for ' + this.node.nodeName); break;
742 '_dump_tree' : function(params) {
745 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
747 var treeitem = this.treechildren.childNodes[i];
748 var treerow = treeitem.firstChild;
749 for (var j = 0; j < treerow.childNodes.length; j++) {
750 row.push( treerow.childNodes[j].getAttribute('label') );
757 'dump_with_keys' : function(params) {
759 switch(this.node.nodeName) {
760 case 'tree' : return this._dump_tree_with_keys(params); break;
761 default: throw('NYI: Need .dump_with_keys() for ' + this.node.nodeName); break;
766 '_dump_tree_with_keys' : function(params) {
769 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
771 var treeitem = this.treechildren.childNodes[i];
772 var treerow = treeitem.firstChild;
773 for (var j = 0; j < treerow.childNodes.length; j++) {
774 row[ obj.columns[j].id ] = treerow.childNodes[j].getAttribute('label');
781 'dump_selected_with_keys' : function(params) {
783 switch(this.node.nodeName) {
784 case 'tree' : return this._dump_tree_selection_with_keys(params); break;
785 default: throw('NYI: Need .dump_selection_with_keys() for ' + this.node.nodeName); break;
790 '_dump_tree_selection_with_keys' : function(params) {
793 var list = obj._retrieve_selection_from_tree();
794 for (var i = 0; i < list.length; i++) {
796 var treeitem = list[i];
797 var treerow = treeitem.firstChild;
798 for (var j = 0; j < treerow.childNodes.length; j++) {
799 var value = treerow.childNodes[j].getAttribute('label');
801 //if (params.skip_hidden_columns) if (obj.node.firstChild.childNodes[j].getAttribute('hidden')) continue;
802 var id = obj.columns[j].id; if (params.labels_instead_of_ids) id = obj.columns[j].label;
810 'clipboard' : function() {
813 var dump = obj.dump_selected_with_keys({'skip_hidden_columns':true,'labels_instead_of_ids':true});
814 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
815 data.list_clipboard = dump; data.stash('list_clipboard');
816 JSAN.use('util.window'); var win = new util.window();
817 win.open(urls.XUL_LIST_CLIPBOARD,'list_clipboard','chrome,resizable,modal');
819 this.error.standard_unexpected_error_alert('clipboard',E);
823 'dump_retrieve_ids' : function(params) {
825 switch(this.node.nodeName) {
826 case 'tree' : return this._dump_retrieve_ids_tree(params); break;
827 default: throw('NYI: Need .dump_retrieve_ids() for ' + this.node.nodeName); break;
831 '_dump_retrieve_ids_tree' : function(params) {
834 for (var i = 0; i < this.treechildren.childNodes.length; i++) {
835 var treeitem = this.treechildren.childNodes[i];
836 dump.push( treeitem.getAttribute('retrieve_id') );
841 '_sort_tree' : function(col,sortDir) {
844 if (obj.node.getAttribute('no_sort')) {
847 if (obj.on_all_fleshed) {
848 var r = window.confirm('This list is busy rendering/retrieving data. Abort current action and proceed?');
849 if (r) {} else { return; }
852 for (var i = 0; i < obj.columns.length; i++) {
853 if (obj.columns[i].id == col.id) col_pos = function(a){return a;}(i);
855 obj.on_all_fleshed = function() {
857 JSAN.use('util.money');
859 var treeitems = obj.treechildren.childNodes;
860 for (var i = 0; i < treeitems.length; i++) {
861 var treeitem = treeitems[i];
862 var treerow = treeitem.firstChild;
863 var treecell = treerow.childNodes[ col_pos ];
864 value = ( { 'value' : treecell ? treecell.getAttribute('label') : '', 'node' : treeitem } );
867 rows = rows.sort( function(a,b) {
868 a = a.value; b = b.value;
869 if (col.getAttribute('sort_type')) {
870 switch(col.getAttribute('sort_type')) {
872 a = Number(a); b = Number(b);
875 a = util.money.dollars_float_to_cents_integer(a);
876 b = util.money.dollars_float_to_cents_integer(b);
878 case 'title' : /* special case for "a" and "the". doesn't use marc 245 indicator */
879 a = String( a ).toUpperCase().replace( /^(THE|A)\s+/, '' );
880 b = String( b ).toUpperCase().replace( /^(THE|A)\s+/, '' );
883 a = String( a ).toUpperCase();
884 b = String( a ).toUpperCase();
888 if (a < b) return -1;
892 if (sortDir == 'asc') rows = rows.reverse();
893 while(obj.treechildren.lastChild) obj.treechildren.removeChild( obj.treechildren.lastChild );
894 for (var i = 0; i < rows.length; i++) {
895 obj.treechildren.appendChild( rows[i].node );
898 obj.error.standard_unexpected_error_alert('sorting',E);
900 setTimeout(function(){ obj.on_all_fleshed = null; },0);
904 obj.error.standard_unexpected_error_alert('pre sorting', E);
909 dump('exiting util.list.js\n');