]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/result_common.js
Don't hardcode our password forms to en-US
[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                 unHideMe($n(r,'place_hold_span'));
515                 $n(r,'place_hold_link').setAttribute(
516                         'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"M"});');
517
518         } else {
519                 buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', rec.doc_id());
520
521                 buildTitleDetailLink(rec, title_link); 
522                 var args = {};
523                 args.page = RDETAIL;
524                 args[PARAM_OFFSET] = 0;
525                 args[PARAM_RID] = rec.doc_id();
526                 pic.parentNode.setAttribute("href", buildOPACLink(args));
527
528                 unHideMe($n(r,'place_hold_span'));
529                 $n(r,'place_hold_link').setAttribute(
530                         'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"T"});');
531
532                 var here = findOrgUnit(getLocation());
533                 if (findOrgType(here.ou_type()).can_have_vols()) { // show the callnumber list
534                         dojo.require('openils.BibTemplate');
535                         var l_cn_list = $n(r,'local_callnumber_list');
536                         var onlyrec = rec.doc_id();
537
538                         setTimeout(
539                                 function () {
540                                         unHideMe(l_cn_list);
541                                         new openils.BibTemplate({
542                                                 root : l_cn_list,
543                                                 record : '' + onlyrec + '[10]',
544                                                 org_unit : here.shortname()
545                                         }).render();
546                                 }, 0
547                         );
548                 }
549         }
550
551         buildSearchLink(STYPE_AUTHOR, rec.author(), author_link);
552
553         if(! is_mr ) {
554         
555                 if(!isNull(rec.edition()))      {
556                         unHideMe( $n(r, "result_table_extra_span"));
557                         $n(r, "result_table_edition_span").appendChild( text( rec.edition()) );
558                 }
559                 if(!isNull(rec.pubdate())) {
560                         unHideMe( $n(r, "result_table_extra_span"));
561                         unHideMe($n(r, "result_table_pub_span"));
562                         $n(r, "result_table_pub_span").appendChild( text( rec.pubdate() ));
563                 }
564                 if(!isNull(rec.publisher()) ) {
565                         unHideMe( $n(r, "result_table_extra_span"));
566                         unHideMe($n(r, "result_table_pub_span"));
567                         $n(r, "result_table_pub_span").appendChild( text( " " + rec.publisher() ));
568                 }
569
570                 if(!isNull(rec.physical_description()) ) {
571                         unHideMe( $n(r, "result_table_extra_span"));
572                         var t = " " + rec.physical_description();
573                         //$n(r, "result_table_phys_span").appendChild( text(t.replace(/:.*/g,'')));
574                         $n(r, "result_table_phys_span").appendChild( text(t));
575                 }
576
577         }
578
579         resultBuildFormatIcons( r, rec, is_mr );
580
581         unHideMe(r);
582         
583         runEvt("result", "recordDrawn", rec.doc_id(), title_link);
584
585         /*
586         if(resultPageIsDone())  {
587                 runEvt('result', 'allRecordsReceived', recordsCache);
588         }
589         */
590 }
591
592 function _resultFindRec(id) {
593         for( var i = 0; i != recordsCache.length; i++ ) {
594                 var rec = recordsCache[i];
595                 if( rec && rec.doc_id() == id )
596                         return rec;
597         }
598         return null;
599 }
600
601
602 function resultBuildFormatIcons( row, rec, is_mr ) {
603
604         var ress = rec.types_of_resource();
605
606         for( var i in ress ) {
607
608                 var res = ress[i];
609                 if(!res) continue;
610
611                 var link = $n(row, res + "_link");
612                 link.title = res;
613                 var img = link.getElementsByTagName("img")[0];
614                 removeCSSClass( img, config.css.dim );
615
616                 var f = getForm();
617                 if( f != "all" ) {
618                         if( f == modsFormatToMARC(res) ) 
619                                 addCSSClass( img, "dim2_border");
620                 }
621
622                 var args = {};
623                 args[PARAM_OFFSET] = 0;
624
625                 if(is_mr) {
626                         args.page = RRESULT;
627                         args[PARAM_TFORM] = modsFormatToMARC(res);
628                         args[PARAM_MRID] = rec.doc_id();
629
630                 } else {
631                         args.page = RDETAIL
632                         args[PARAM_RID] = rec.doc_id();
633                 }
634
635                 link.setAttribute("href", buildOPACLink(args));
636
637         }
638 }
639
640 function fetchGoogleBooksLink () {
641     if (isbnList && googleBooksLink) {
642         var scriptElement = document.createElement("script");
643         scriptElement.setAttribute("id", "jsonScript");
644         scriptElement.setAttribute("src",
645             "http://books.google.com/books?bibkeys=" + 
646             escape(isbnList) + "&jscmd=viewapi&callback=unhideGoogleBooksLink");
647         scriptElement.setAttribute("type", "text/javascript");
648         // make the request to Google Book Search
649         document.documentElement.firstChild.appendChild(scriptElement);
650     }
651 }
652
653 function resultPageIsDone(pos) {
654
655         return (recordsHandled == getDisplayCount() 
656                 || recordsHandled + getOffset() == getHitCount());
657 }
658
659 var resultCCHeaderApplied = false;
660
661 /* -------------------------------------------------------------------- */
662 /* dynamically add the copy count rows based on the org type 'countsrow' 
663         is the row into which we will add TD's to hold the copy counts 
664         This code generates copy count cells with an id of
665         'copy_count_cell_<depth>_<pagePosition>'  */
666 function resultAddCopyCounts(rec, pagePosition) {
667
668         var r = table.rows[pagePosition + 1];
669         var countsrow = $n(r, config.names.result.counts_row );
670         var ccell = $n(countsrow, config.names.result.count_cell);
671
672         var nodes = orgNodeTrail(findOrgUnit(getLocation()));
673         var node = nodes[0];
674         var type = findOrgType(node.ou_type());
675         ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
676         ccell.title = type.opac_label();
677         //addCSSClass(ccell, config.css.result.cc_cell_even);
678
679         var lastcell = ccell;
680         var lastheadcell = null;
681
682         var cchead = null;
683         var ccheadcell = null;
684         if(!resultCCHeaderApplied && !getLasso()) {
685                 ccrow = $('result_thead_row');
686                 ccheadcell =  ccrow.removeChild($n(ccrow, "result_thead_ccell"));
687                 var t = ccheadcell.cloneNode(true);
688                 lastheadcell = t;
689                 t.appendChild(text(type.opac_label()));
690                 ccrow.appendChild(t);
691                 resultCCHeaderApplied = true;
692         }
693
694         if(nodes[1]) {
695
696                 var x = 1;
697                 var d = findOrgDepth(nodes[1]);
698                 var d2 = findOrgDepth(nodes[nodes.length -1]);
699
700                 for( var i = d; i <= d2 ; i++ ) {
701         
702                         ccell = ccell.cloneNode(true);
703
704                         //if((i % 2)) removeCSSClass(ccell, "copy_count_cell_even");
705                         //else addCSSClass(ccell, "copy_count_cell_even");
706
707                         var node = nodes[x++];
708                         var type = findOrgType(node.ou_type());
709         
710                         ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
711                         ccell.title = type.opac_label();
712                         countsrow.insertBefore(ccell, lastcell);
713                         lastcell = ccell;
714
715                         if(ccheadcell) {
716                                 var t = ccheadcell.cloneNode(true);
717                                 t.appendChild(text(type.opac_label()));
718                                 ccrow.insertBefore(t, lastheadcell);
719                                 lastheadcell = t;
720                         }
721                 }
722         }
723
724         unHideMe($("search_info_table"));
725 }
726
727 /* collect copy counts for a record using method 'methodName' */
728 function resultCollectCopyCounts(rec, pagePosition, methodName) {
729         if(rec == null || rec.doc_id() == null) return;
730
731         var loc = getLasso();
732         if (loc) loc = -loc;
733         else loc= getLocation();
734
735         var req = new Request(methodName, loc, rec.doc_id(), getForm() );
736         req.request.userdata = [ rec, pagePosition ];
737         req.callback(resultHandleCopyCounts);
738         req.send();
739 }
740
741 function resultHandleCopyCounts(r) {
742         runEvt('result', 'copyCountsReceived', r.userdata[0], r.userdata[1], r.getResultObject()); 
743 }
744
745
746 /* XXX Needs to understand Lasso copy counts... */
747 /* display the collected copy counts */
748 function resultDisplayCopyCounts(rec, pagePosition, copy_counts) {
749         if(copy_counts == null || rec == null) return;
750
751         if (getLasso()) {
752                 var copy_counts_lasso = {
753                         transcendant : null,
754                         count : 0,
755                         unshadow : 0,
756                         available : 0,
757                         depth : -1,
758                         org_unit : getLasso()
759                 };
760
761                 for (var i in copy_counts) {
762                         copy_counts_lasso.transcendant = copy_counts[i].transcendant;
763                         copy_counts_lasso.count += parseInt(copy_counts[i].count);
764                         copy_counts_lasso.unshadow += parseInt(copy_counts[i].unshadow);
765                         copy_counts_lasso.available += parseInt(copy_counts[i].available);
766                 }
767
768                 copy_counts = [ copy_counts_lasso ];
769         }
770
771         var i = 0;
772         while(copy_counts[i] != null) {
773                 var cell = $("copy_count_cell_" + i +"_" + pagePosition);
774                 var cts = copy_counts[i];
775                 cell.appendChild(text(cts.available + " / " + cts.count));
776
777                 if(isXUL()) {
778                         /* here we style opac-invisible records for xul */
779
780                         if( cts.depth == 0 ) {
781                                 if(cts.transcendant == null && cts.unshadow == 0) {
782                                         _debug("found an opac-shadowed record: " + rec.doc_id());
783                                         var row = cell.parentNode.parentNode.parentNode.parentNode.parentNode; 
784                                         if( cts.count == 0 ) 
785                                                 addCSSClass( row, 'no_copies' );
786                                         else 
787                                                 addCSSClass( row, 'shadowed' );
788                                 }
789                         }
790                 }
791                 i++;
792         }
793 }
794
795