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