]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/result_common.js
71471b5bb47eb40f8d1f85707a7d5589b30e5e73
[working/Evergreen.git] / Open-ILS / web / opac / skin / default / js / result_common.js
1
2 var recordsHandled = 0;
3 var recordsCache = [];
4 var lowHitCount = 4;
5 var isbnList = '';
6 var googleBooksLink = true;
7
8 var resultFetchAllRecords = false;
9 var resultCompiledSearch = null;
10
11 /* set up the event handlers */
12 if( findCurrentPage() == MRESULT || findCurrentPage() == RRESULT ) {
13         G.evt.result.hitCountReceived.push(resultSetHitInfo);
14         G.evt.result.recordReceived.push(resultDisplayRecord, resultAddCopyCounts);
15         G.evt.result.copyCountsReceived.push(resultDisplayCopyCounts);
16         G.evt.result.allRecordsReceived.push(resultBuildCaches, resultDrawSubjects, 
17       resultDrawAuthors, resultDrawSeries, function(){unHideMe($('result_info_2'))},
18           fetchGoogleBooksLink);
19
20         attachEvt('result','lowHits',resultLowHits);
21         attachEvt('result','zeroHits',resultZeroHits);
22         attachEvt( "common", "locationUpdated", resultSBSubmit );
23         /* do this after we have ID's so the rank for mr pages will be correct */
24         attachEvt("result", "preCollectRecords", resultPaginate);
25 }
26
27 function resultSBSubmit(){searchBarSubmit();}
28
29 /* returns the last 'index' postion ocurring in this page */
30 function resultFinalPageIndex() {
31         if(getHitCount() < (getOffset() + getDisplayCount())) 
32                 return getHitCount() - 1;
33         return getOffset() + getDisplayCount() - 1;
34 }
35
36
37
38
39 /* generic search method */
40 function resultCollectSearchIds( type, method, handler ) {
41
42         var sort                = (getSort() == SORT_TYPE_REL) ? null : getSort(); 
43         var sortdir = (sort) ? ((getSortDir()) ? getSortDir() : SORT_DIR_ASC) : null;
44
45         var item_type;
46         var item_form;
47         var args = {};
48
49         if( type ) {
50                 var form = parseForm(getForm());
51                 item_type = form.item_type;
52                 item_form = form.item_form;
53
54         } else {
55                 item_type = (getItemType()) ? getItemType().split(/,/) : null;
56                 item_form = (getItemForm()) ? getItemForm().split(/,/) : null;
57         }
58
59         var limit = (resultFetchAllRecords) ? 1000 : getDisplayCount();
60
61         if( getOffset() > 0 ) {
62                 if( getHitCount() > 0 && (getOffset() + getDisplayCount()) > getHitCount() ) 
63                         limit = getHitCount() - getOffset();
64         }
65
66         var lasso = getLasso();
67
68         if (lasso) args.org_unit = -lasso;
69         else args.org_unit = getLocation();
70
71         args.depth    = getDepth();
72         args.limit    = limit;
73         args.offset   = getOffset();
74         args.visibility_limit = 3000;
75     args.default_class = getStype();
76
77         if(sort) args.sort = sort;
78         if(sortdir) args.sort_dir = sortdir;
79         if(item_type) args.item_type    = item_type;
80         if(item_form) args.item_form    = item_form;
81     if(getAvail()) args.available = 1;
82
83
84         if(getAudience()) args.audience  = getAudience().split(/,/);
85         if(getLitForm()) args.lit_form  = getLitForm().split(/,/);
86         if(getLanguage()) args.language = getLanguage().split(/,/);
87         if(getBibLevel()) args.bib_level        = getBibLevel().split(/,/);
88         if(getCopyLocs()) args.locations        = getCopyLocs().split(/,/);
89     if(getPubdBefore()) args.before = getPubdBefore();
90     else if(getPubdAfter()) args.after = getPubdAfter();
91     else if(getPubdBetween()) args.between = getPubdBetween().split(/,/);
92
93         _debug('Search args: ' + js2JSON(args));
94         _debug('Raw query: ' + getTerm());
95
96         var req = new Request(method, args, getTerm(), 1);
97         req.callback(handler);
98         req.send();
99 }
100
101
102
103
104
105 /* set the search result info, number of hits, which results we're 
106         displaying, links to the next/prev pages, etc. */
107 function resultSetHitInfo() { 
108
109         var lasso = getLasso();
110         if (!lasso) {
111                 /* tell the user where the results are coming from */
112                 var baseorg = findOrgUnit(getLocation());
113                 var depth = getDepth();
114                 var mydepth = findOrgDepth(baseorg);
115                 if( findOrgDepth(baseorg) != depth ) {
116                         var tmporg = baseorg;
117                         while( mydepth > depth ) {
118                                 mydepth--;
119                                 tmporg = findOrgUnit(tmporg.parent_ou());
120                         }
121                         unHideMe($('including_results_for'));
122                         $('including_results_location').appendChild(text(tmporg.name()));
123                 }
124         }
125
126
127         try{searchTimer.stop()}catch(e){}
128
129         //if( findCurrentPage() == MRESULT ) {
130         if( findCurrentPage() == MRESULT || 
131
132                 (findCurrentPage() == RRESULT &&
133                         (
134                                 getRtype() == RTYPE_TITLE ||
135                                 getRtype() == RTYPE_AUTHOR ||
136                                 getRtype() == RTYPE_SUBJECT ||
137                                 getRtype() == RTYPE_SERIES ||
138                                 getRtype() == RTYPE_KEYWORD 
139                         )
140
141                 ) ) {
142
143                 if(getHitCount() <= lowHitCount && getTerm())
144                         runEvt('result', 'lowHits');
145         }
146
147         if(getHitCount() == 0) {
148                 runEvt('result', 'zeroHits');
149                 return;
150         }
151
152
153         var pages = getHitCount() / getDisplayCount();
154         if(pages % 1) pages = parseInt(pages) + 1;
155
156         
157
158         var cpage = (getOffset()/getDisplayCount()) + 1;
159
160         G.ui.result.current_page.appendChild(text(cpage));
161         G.ui.result.num_pages.appendChild(text(pages + ")")); /* the ) is dumb */
162
163         $('current_page2').appendChild(text(cpage));
164         $('num_pages2').appendChild(text(pages + ")")); /* the ) is dumb */
165
166         /* set the offsets */
167         var offsetEnd = getDisplayCount() + getOffset();  
168         if( getDisplayCount() > (getHitCount() - getOffset()))  
169                 offsetEnd = getHitCount();
170
171         G.ui.result.offset_end.appendChild(text(offsetEnd));
172         G.ui.result.offset_start.appendChild(text(getOffset() + 1));
173
174         $('offset_end2').appendChild(text(offsetEnd));
175         $('offset_start2').appendChild(text(getOffset() + 1));
176
177         G.ui.result.result_count.appendChild(text(getHitCount()));
178         unHideMe(G.ui.result.info);
179
180         $('result_count2').appendChild(text(getHitCount()));
181         unHideMe($('result_info_div2'));
182 }
183
184 function resultLowHits() {
185         showCanvas();
186         unHideMe($('result_low_hits'));
187         if(getHitCount() > 0)
188                 unHideMe($('result_low_hits_msg'));
189
190     var words = [];
191     for(var key in resultCompiledSearch.searches) 
192         words.push(resultCompiledSearch.searches[key].term);
193
194         var sreq = new Request(CHECK_SPELL, words.join(' '));
195         sreq.callback(resultSuggestSpelling);
196         sreq.send();
197
198     for(var key in resultCompiledSearch.searches) {
199                 var areq = new Request(FETCH_CROSSREF, key, resultCompiledSearch.searches[key].term);
200                 areq.callback(resultLowHitXRef);
201                 areq.send();
202         }
203
204         if( !(getForm() == null || getForm() == 'all' || getForm() == "") ) {
205                 var a = {};
206                 a[PARAM_FORM] = "all";
207                 $('low_hits_remove_format_link').setAttribute('href',buildOPACLink(a));
208                 unHideMe($('low_hits_remove_format'));
209         }
210
211         resultSuggestSearchClass();
212
213         if(getTerm()) resultExpandSearch(); /* advanced search */
214 }
215
216 var lowHitsXRefSet = {};
217 var lowHitsXRefLink;
218 var lowHitsXRefLinkParent;
219 function resultLowHitXRef(r) {
220         if(!lowHitsXRefLink){
221                 lowHitsXRefLinkParent = $('low_hits_xref_link').parentNode;
222                 lowHitsXRefLink = lowHitsXRefLinkParent.removeChild($('low_hits_xref_link'));
223         }
224         var res = r.getResultObject();
225         var arr = res.from;
226         arr.concat(res.also);
227         if(arr && arr.length > 0) {
228                 unHideMe($('low_hits_cross_ref'));
229                 var word;
230                 var c = 0;
231                 while( word = arr.shift() ) {
232
233             if (lowHitsXRefSet[word] == 1) continue;
234             lowHitsXRefSet[word] = 1;
235
236                         if(c++ > 20) break;
237                         var a = {};
238                         a[PARAM_TERM] = word;
239                         var template = lowHitsXRefLink.cloneNode(true);
240                         template.setAttribute('href',buildOPACLink(a));
241                         template.appendChild(text(word));
242                         lowHitsXRefLinkParent.appendChild(template);
243                         lowHitsXRefLinkParent.appendChild(text(' '));
244                 }
245         }
246 }
247
248 function resultZeroHits() {
249         showCanvas();
250         unHideMe($('result_low_hits'));
251         unHideMe($('result_zero_hits_msg'));
252         //if(getTerm()) resultExpandSearch(); /* advanced search */
253 }
254
255 function resultExpandSearch() {
256         var top = findOrgDepth(globalOrgTree);
257         if(getDepth() == top) return;
258         unHideMe($('low_hits_expand_range'));
259         var par = $('low_hits_expand_link').parentNode;
260         var template = par.removeChild($('low_hits_expand_link'));
261
262         var bottom = getDepth();
263         while( top < bottom ) {
264                 var a = {};
265                 a[PARAM_DEPTH] = top;
266                 var temp = template.cloneNode(true);
267                 temp.appendChild(text(findOrgTypeFromDepth(top).opac_label()))
268                 temp.setAttribute('href',buildOPACLink(a));
269                 par.appendChild(temp);
270                 top++;
271         }
272 }
273
274 function resultSuggestSearchClass() {
275         var stype = getStype();
276         if(stype == STYPE_KEYWORD) return;
277         var a = {}; var ref;
278         unHideMe($('low_hits_search_type'));
279         if(stype != STYPE_TITLE) {
280                 ref = $('low_hits_title_search');
281                 unHideMe(ref);
282                 a[PARAM_STYPE] = STYPE_TITLE;
283                 ref.setAttribute('href',buildOPACLink(a));
284         }
285         if(stype != STYPE_AUTHOR) {
286                 ref = $('low_hits_author_search');
287                 unHideMe(ref);
288                 a[PARAM_STYPE] = STYPE_AUTHOR;
289                 ref.setAttribute('href',buildOPACLink(a));
290         }
291         if(stype != STYPE_SUBJECT) {
292                 ref = $('low_hits_subject_search');
293                 unHideMe(ref);
294                 a[PARAM_STYPE] = STYPE_SUBJECT;
295                 ref.setAttribute('href',buildOPACLink(a));
296         }
297         if(stype != STYPE_KEYWORD) {
298                 ref = $('low_hits_keyword_search');
299                 unHideMe(ref);
300                 a[PARAM_STYPE] = STYPE_KEYWORD;
301                 ref.setAttribute('href',buildOPACLink(a));
302         }
303         if(stype != STYPE_SERIES) {
304                 ref = $('low_hits_series_search');
305                 unHideMe(ref);
306                 a[PARAM_STYPE] = STYPE_SERIES;
307                 ref.setAttribute('href',buildOPACLink(a));
308         }
309 }
310
311 function resultSuggestSpelling(r) {
312         var res = r.getResultObject();
313         var phrase = getTerm();
314         var words = phrase.split(/ /);
315
316         var newterm = "";
317
318         for( var w = 0; w < words.length; w++ ) {
319                 var word = words[w];
320                 var blob = grep(res, function(i){return (i.word == word);});
321                 if( blob ) blob = blob[0];
322                 else continue;
323                 if( blob.word == word ) {
324                         if( blob.suggestions && blob.suggestions[0] ) {
325                                 newterm += " " + blob.suggestions[0];
326                                 unHideMe($('did_you_mean'));
327                         } else {
328                                 newterm += " " + word;
329                         }
330                 }
331         }
332
333         var arg = {};
334         arg[PARAM_TERM] = newterm;
335         $('spell_check_link').setAttribute('href', buildOPACLink(arg));
336         $('spell_check_link').appendChild(text(newterm));
337 }
338
339
340 function resultPaginate() {
341         var o = getOffset();
342
343         if( !(  ((o) + getDisplayCount()) >= getHitCount()) ) {
344
345                 var args = {};
346                 args[PARAM_OFFSET]      = o + getDisplayCount();
347                 args[PARAM_SORT]                = SORT;
348                 args[PARAM_SORT_DIR] = SORT_DIR;
349                 args[PARAM_RLIST]               = new CGI().param(PARAM_RLIST);
350
351                 G.ui.result.next_link.setAttribute("href", buildOPACLink(args)); 
352                 addCSSClass(G.ui.result.next_link, config.css.result.nav_active);
353
354                 $('next_link2').setAttribute("href", buildOPACLink(args)); 
355                 addCSSClass($('next_link2'), config.css.result.nav_active);
356
357                 args[PARAM_OFFSET] = getHitCount() - (getHitCount() % getDisplayCount());
358
359                 /* when hit count is divisible by display count, we have to adjust */
360                 if( getHitCount() % getDisplayCount() == 0 ) 
361                         args[PARAM_OFFSET] -= getDisplayCount();
362
363         /*
364                 G.ui.result.end_link.setAttribute("href", buildOPACLink(args)); 
365                 addCSSClass(G.ui.result.end_link, config.css.result.nav_active);
366
367                 $('end_link2').setAttribute("href", buildOPACLink(args)); 
368                 addCSSClass($('end_link2'), config.css.result.nav_active);
369         */
370         }
371
372         if( o > 0 ) {
373
374                 var args = {};
375                 args[PARAM_SORT]                = SORT;
376                 args[PARAM_SORT_DIR] = SORT_DIR;
377                 args[PARAM_RLIST]               = new CGI().param(PARAM_RLIST);
378
379                 args[PARAM_OFFSET] = o - getDisplayCount();
380                 G.ui.result.prev_link.setAttribute( "href", buildOPACLink(args)); 
381                 addCSSClass(G.ui.result.prev_link, config.css.result.nav_active);
382
383                 $('prev_link2').setAttribute( "href", buildOPACLink(args)); 
384                 addCSSClass($('prev_link2'), config.css.result.nav_active);
385
386                 args[PARAM_OFFSET] = 0;
387                 G.ui.result.home_link.setAttribute( "href", buildOPACLink(args)); 
388                 addCSSClass(G.ui.result.home_link, config.css.result.nav_active);
389
390                 $('search_home_link2').setAttribute( "href", buildOPACLink(args)); 
391                 addCSSClass($('search_home_link2'), config.css.result.nav_active);
392         }
393
394         if(getDisplayCount() < getHitCount()) {
395                 unHideMe($('start_end_links_span'));
396                 unHideMe($('start_end_links_span2'));
397    }
398
399         showCanvas();
400         try{searchTimer.stop()}catch(e){}
401 }
402
403 function buildunAPISpan (span, type, id) {
404         var cgi = new CGI();
405         var d = new Date();
406
407         addCSSClass(span,'unapi-id');
408
409         span.setAttribute(
410                 'title',
411                 'tag:' + cgi.server_name + ',' +
412                         d.getFullYear() +
413                         ':' + type + '/' + id
414         );
415 }
416
417 function unhideGoogleBooksLink (data) {
418     for ( var i in data ) {
419         //if (data[i].preview == 'noview') continue;
420
421         var gbspan = $n(document.documentElement, 'googleBooksLink-' + i);
422         var gba = $n(gbspan, "googleBooks-link");
423
424         gba.setAttribute(
425             'href',
426             data[i].info_url
427         );
428         removeCSSClass( gbspan, 'hide_me' );
429     }
430 }
431
432 /* display the record info in the record display table 'pos' is the 
433                 zero based position the record should have in the display table */
434 function resultDisplayRecord(rec, pos, is_mr) {
435
436         if(rec == null) rec = new mvr(); /* so the page won't die if there was an error */
437         recordsHandled++;
438         recordsCache.push(rec);
439
440         var r = table.rows[pos + 1];
441     var currentISBN = cleanISBN(rec.isbn());
442
443     if (googleBooksLink) {
444             var gbspan = $n(r, "googleBooksLink");
445         if (currentISBN) {
446             gbspan.setAttribute(
447                 'name',
448                 gbspan.getAttribute('name') + '-' + currentISBN
449             );
450
451             if (isbnList) isbnList += ', ';
452             isbnList += currentISBN;
453         }
454     }
455
456 /*
457         try {
458                 var rank = parseFloat(ranks[pos + getOffset()]);
459                 rank            = parseInt( rank * 100 );
460                 var relspan = $n(r, "relevancy_span");
461                 relspan.appendChild(text(rank));
462                 unHideMe(relspan.parentNode);
463         } catch(e){ }
464 */
465
466         var pic = $n(r, config.names.result.item_jacket);
467         pic.setAttribute("src", buildISBNSrc(currentISBN));
468
469         var title_link = $n(r, config.names.result.item_title);
470         var author_link = $n(r, config.names.result.item_author);
471
472         if( is_mr )  {
473                 var onlyrec = onlyrecord[ getOffset() + pos ];
474                 if(onlyrec) {
475                         buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', onlyrec);
476
477                         var args = {};
478                         args.page = RDETAIL;
479                         args[PARAM_OFFSET] = 0;
480                         args[PARAM_RID] = onlyrec;
481                         args[PARAM_MRID] = rec.doc_id();
482                         pic.parentNode.setAttribute("href", buildOPACLink(args));
483                         title_link.setAttribute("href", buildOPACLink(args));
484                         title_link.appendChild(text(normalize(truncate(rec.title(), 65))));
485                         
486                         var here = findOrgUnit(getLocation());
487                         if (findOrgType(here.ou_type()).can_have_vols()) { // show the callnumber list
488                                 dojo.require('openils.BibTemplate');
489                                 var l_cn_list = $n(r,'local_callnumber_list');
490
491                                 setTimeout(
492                                         function () {
493                                                 unHideMe(l_cn_list);
494                                                 new openils.BibTemplate({
495                                                         root : l_cn_list,
496                                                         record : '' + onlyrec + '[10]',
497                                                         org_unit : here.shortname()
498                                                 }).render();
499                                         }, 0
500                                 );
501                         }
502
503                 } else {
504                         buildunAPISpan($n(r,'unapi'), 'metabib-metarecord', rec.doc_id());
505
506                         buildTitleLink(rec, title_link); 
507                         var args = {};
508                         args.page = RRESULT;
509                         args[PARAM_OFFSET] = 0;
510                         args[PARAM_MRID] = rec.doc_id();
511                         pic.parentNode.setAttribute("href", buildOPACLink(args));
512                 }
513
514         } else {
515                 buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', rec.doc_id());
516
517                 buildTitleDetailLink(rec, title_link); 
518                 var args = {};
519                 args.page = RDETAIL;
520                 args[PARAM_OFFSET] = 0;
521                 args[PARAM_RID] = rec.doc_id();
522                 pic.parentNode.setAttribute("href", buildOPACLink(args));
523
524                 unHideMe($n(r,'place_hold_span'));
525                 $n(r,'place_hold_link').setAttribute(
526                         'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"T"});');
527
528                 var here = findOrgUnit(getLocation());
529                 if (findOrgType(here.ou_type()).can_have_vols()) { // show the callnumber list
530                         dojo.require('openils.BibTemplate');
531                         var l_cn_list = $n(r,'local_callnumber_list');
532                         var onlyrec = rec.doc_id();
533
534                         setTimeout(
535                                 function () {
536                                         unHideMe(l_cn_list);
537                                         new openils.BibTemplate({
538                                                 root : l_cn_list,
539                                                 record : '' + onlyrec + '[10]',
540                                                 org_unit : here.shortname()
541                                         }).render();
542                                 }, 0
543                         );
544                 }
545         }
546
547         buildSearchLink(STYPE_AUTHOR, rec.author(), author_link);
548
549         if(! is_mr ) {
550         
551                 if(!isNull(rec.edition()))      {
552                         unHideMe( $n(r, "result_table_extra_span"));
553                         $n(r, "result_table_edition_span").appendChild( text( rec.edition()) );
554                 }
555                 if(!isNull(rec.pubdate())) {
556                         unHideMe( $n(r, "result_table_extra_span"));
557                         unHideMe($n(r, "result_table_pub_span"));
558                         $n(r, "result_table_pub_span").appendChild( text( rec.pubdate() ));
559                 }
560                 if(!isNull(rec.publisher()) ) {
561                         unHideMe( $n(r, "result_table_extra_span"));
562                         unHideMe($n(r, "result_table_pub_span"));
563                         $n(r, "result_table_pub_span").appendChild( text( " " + rec.publisher() ));
564                 }
565
566                 if(!isNull(rec.physical_description()) ) {
567                         unHideMe( $n(r, "result_table_extra_span"));
568                         var t = " " + rec.physical_description();
569                         //$n(r, "result_table_phys_span").appendChild( text(t.replace(/:.*/g,'')));
570                         $n(r, "result_table_phys_span").appendChild( text(t));
571                 }
572
573         }
574
575         resultBuildFormatIcons( r, rec, is_mr );
576
577         unHideMe(r);
578         
579         runEvt("result", "recordDrawn", rec.doc_id(), title_link);
580
581         /*
582         if(resultPageIsDone())  {
583                 runEvt('result', 'allRecordsReceived', recordsCache);
584         }
585         */
586 }
587
588 function _resultFindRec(id) {
589         for( var i = 0; i != recordsCache.length; i++ ) {
590                 var rec = recordsCache[i];
591                 if( rec && rec.doc_id() == id )
592                         return rec;
593         }
594         return null;
595 }
596
597
598 function resultBuildFormatIcons( row, rec, is_mr ) {
599
600         var ress = rec.types_of_resource();
601
602         for( var i in ress ) {
603
604                 var res = ress[i];
605                 if(!res) continue;
606
607                 var link = $n(row, res + "_link");
608                 link.title = res;
609                 var img = link.getElementsByTagName("img")[0];
610                 removeCSSClass( img, config.css.dim );
611
612                 var f = getForm();
613                 if( f != "all" ) {
614                         if( f == modsFormatToMARC(res) ) 
615                                 addCSSClass( img, "dim2_border");
616                 }
617
618                 var args = {};
619                 args[PARAM_OFFSET] = 0;
620
621                 if(is_mr) {
622                         args.page = RRESULT;
623                         args[PARAM_TFORM] = modsFormatToMARC(res);
624                         args[PARAM_MRID] = rec.doc_id();
625
626                 } else {
627                         args.page = RDETAIL
628                         args[PARAM_RID] = rec.doc_id();
629                 }
630
631                 link.setAttribute("href", buildOPACLink(args));
632
633         }
634 }
635
636 function fetchGoogleBooksLink () {
637     if (isbnList && googleBooksLink) {
638         var scriptElement = document.createElement("script");
639         scriptElement.setAttribute("id", "jsonScript");
640         scriptElement.setAttribute("src",
641             "http://books.google.com/books?bibkeys=" + 
642             escape(isbnList) + "&jscmd=viewapi&callback=unhideGoogleBooksLink");
643         scriptElement.setAttribute("type", "text/javascript");
644         // make the request to Google Book Search
645         document.documentElement.firstChild.appendChild(scriptElement);
646     }
647 }
648
649 function resultPageIsDone(pos) {
650
651         return (recordsHandled == getDisplayCount() 
652                 || recordsHandled + getOffset() == getHitCount());
653 }
654
655 var resultCCHeaderApplied = false;
656
657 /* -------------------------------------------------------------------- */
658 /* dynamically add the copy count rows based on the org type 'countsrow' 
659         is the row into which we will add TD's to hold the copy counts 
660         This code generates copy count cells with an id of
661         'copy_count_cell_<depth>_<pagePosition>'  */
662 function resultAddCopyCounts(rec, pagePosition) {
663
664         var r = table.rows[pagePosition + 1];
665         var countsrow = $n(r, config.names.result.counts_row );
666         var ccell = $n(countsrow, config.names.result.count_cell);
667
668         var nodes = orgNodeTrail(findOrgUnit(getLocation()));
669         var node = nodes[0];
670         var type = findOrgType(node.ou_type());
671         ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
672         ccell.title = type.opac_label();
673         //addCSSClass(ccell, config.css.result.cc_cell_even);
674
675         var lastcell = ccell;
676         var lastheadcell = null;
677
678         var cchead = null;
679         var ccheadcell = null;
680         if(!resultCCHeaderApplied && !getLasso()) {
681                 ccrow = $('result_thead_row');
682                 ccheadcell =  ccrow.removeChild($n(ccrow, "result_thead_ccell"));
683                 var t = ccheadcell.cloneNode(true);
684                 lastheadcell = t;
685                 t.appendChild(text(type.opac_label()));
686                 ccrow.appendChild(t);
687                 resultCCHeaderApplied = true;
688         }
689
690         if(nodes[1]) {
691
692                 var x = 1;
693                 var d = findOrgDepth(nodes[1]);
694                 var d2 = findOrgDepth(nodes[nodes.length -1]);
695
696                 for( var i = d; i <= d2 ; i++ ) {
697         
698                         ccell = ccell.cloneNode(true);
699
700                         //if((i % 2)) removeCSSClass(ccell, "copy_count_cell_even");
701                         //else addCSSClass(ccell, "copy_count_cell_even");
702
703                         var node = nodes[x++];
704                         var type = findOrgType(node.ou_type());
705         
706                         ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
707                         ccell.title = type.opac_label();
708                         countsrow.insertBefore(ccell, lastcell);
709                         lastcell = ccell;
710
711                         if(ccheadcell) {
712                                 var t = ccheadcell.cloneNode(true);
713                                 t.appendChild(text(type.opac_label()));
714                                 ccrow.insertBefore(t, lastheadcell);
715                                 lastheadcell = t;
716                         }
717                 }
718         }
719
720         unHideMe($("search_info_table"));
721 }
722
723 /* collect copy counts for a record using method 'methodName' */
724 function resultCollectCopyCounts(rec, pagePosition, methodName) {
725         if(rec == null || rec.doc_id() == null) return;
726
727         var loc = getLasso();
728         if (loc) loc = -loc;
729         else loc= getLocation();
730
731         var req = new Request(methodName, loc, rec.doc_id(), getForm() );
732         req.request.userdata = [ rec, pagePosition ];
733         req.callback(resultHandleCopyCounts);
734         req.send();
735 }
736
737 function resultHandleCopyCounts(r) {
738         runEvt('result', 'copyCountsReceived', r.userdata[0], r.userdata[1], r.getResultObject()); 
739 }
740
741
742 /* XXX Needs to understand Lasso copy counts... */
743 /* display the collected copy counts */
744 function resultDisplayCopyCounts(rec, pagePosition, copy_counts) {
745         if(copy_counts == null || rec == null) return;
746
747         if (getLasso()) {
748                 var copy_counts_lasso = {
749                         transcendant : null,
750                         count : 0,
751                         unshadow : 0,
752                         available : 0,
753                         depth : -1,
754                         org_unit : getLasso()
755                 };
756
757                 for (var i in copy_counts) {
758                         copy_counts_lasso.transcendant = copy_counts[i].transcendant;
759                         copy_counts_lasso.count += parseInt(copy_counts[i].count);
760                         copy_counts_lasso.unshadow += parseInt(copy_counts[i].unshadow);
761                         copy_counts_lasso.available += parseInt(copy_counts[i].available);
762                 }
763
764                 copy_counts = [ copy_counts_lasso ];
765         }
766
767         var i = 0;
768         while(copy_counts[i] != null) {
769                 var cell = $("copy_count_cell_" + i +"_" + pagePosition);
770                 var cts = copy_counts[i];
771                 cell.appendChild(text(cts.available + " / " + cts.count));
772
773                 if(isXUL()) {
774                         /* here we style opac-invisible records for xul */
775
776                         if( cts.depth == 0 ) {
777                                 if(cts.transcendant == null && cts.unshadow == 0) {
778                                         _debug("found an opac-shadowed record: " + rec.doc_id());
779                                         var row = cell.parentNode.parentNode.parentNode.parentNode.parentNode; 
780                                         if( cts.count == 0 ) 
781                                                 addCSSClass( row, 'no_copies' );
782                                         else 
783                                                 addCSSClass( row, 'shadowed' );
784                                 }
785                         }
786                 }
787                 i++;
788         }
789 }
790
791