2 var recordsHandled = 0;
6 var googleBooksLink = true;
8 var resultFetchAllRecords = false;
9 var resultCompiledSearch = null;
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,fetchChiliFreshReviews);
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);
27 function resultSBSubmit(){searchBarSubmit();}
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;
39 /* generic search method */
40 function resultCollectSearchIds( type, method, handler ) {
42 var sort = (getSort() == SORT_TYPE_REL) ? null : getSort();
43 var sortdir = (sort) ? ((getSortDir()) ? getSortDir() : SORT_DIR_ASC) : null;
50 var form = parseForm(getForm());
51 item_type = form.item_type;
52 item_form = form.item_form;
55 item_type = (getItemType()) ? getItemType().split(/,/) : null;
56 item_form = (getItemForm()) ? getItemForm().split(/,/) : null;
59 var limit = (resultFetchAllRecords) ? 1000 : getDisplayCount();
61 if( getOffset() > 0 ) {
62 if( getHitCount() > 0 && (getOffset() + getDisplayCount()) > getHitCount() )
63 limit = getHitCount() - getOffset();
66 var lasso = getLasso();
68 if (lasso) args.org_unit = -lasso;
69 else args.org_unit = getLocation();
71 args.depth = getDepth();
73 args.offset = getOffset();
74 args.visibility_limit = 3000;
75 args.default_class = getStype();
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;
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(/,/);
93 _debug('Search args: ' + js2JSON(args));
94 _debug('Raw query: ' + getTerm());
96 var req = new Request(method, args, getTerm(), 1);
97 req.callback(handler);
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() {
109 var lasso = getLasso();
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 ) {
119 tmporg = findOrgUnit(tmporg.parent_ou());
121 unHideMe($('including_results_for'));
122 $('including_results_location').appendChild(text(tmporg.name()));
127 try{searchTimer.stop()}catch(e){}
129 //if( findCurrentPage() == MRESULT ) {
130 if( findCurrentPage() == MRESULT ||
132 (findCurrentPage() == RRESULT &&
134 getRtype() == RTYPE_TITLE ||
135 getRtype() == RTYPE_AUTHOR ||
136 getRtype() == RTYPE_SUBJECT ||
137 getRtype() == RTYPE_SERIES ||
138 getRtype() == RTYPE_KEYWORD
143 if(getHitCount() <= lowHitCount && getTerm())
144 runEvt('result', 'lowHits');
147 if(getHitCount() == 0) {
148 runEvt('result', 'zeroHits');
153 var pages = getHitCount() / getDisplayCount();
154 if(pages % 1) pages = parseInt(pages) + 1;
158 var cpage = (getOffset()/getDisplayCount()) + 1;
160 G.ui.result.current_page.appendChild(text(cpage));
161 G.ui.result.num_pages.appendChild(text(pages + ")")); /* the ) is dumb */
163 $('current_page2').appendChild(text(cpage));
164 $('num_pages2').appendChild(text(pages + ")")); /* the ) is dumb */
166 /* set the offsets */
167 var offsetEnd = getDisplayCount() + getOffset();
168 if( getDisplayCount() > (getHitCount() - getOffset()))
169 offsetEnd = getHitCount();
171 G.ui.result.offset_end.appendChild(text(offsetEnd));
172 G.ui.result.offset_start.appendChild(text(getOffset() + 1));
174 $('offset_end2').appendChild(text(offsetEnd));
175 $('offset_start2').appendChild(text(getOffset() + 1));
177 G.ui.result.result_count.appendChild(text(getHitCount()));
178 unHideMe(G.ui.result.info);
180 $('result_count2').appendChild(text(getHitCount()));
181 unHideMe($('result_info_div2'));
184 function resultLowHits() {
186 unHideMe($('result_low_hits'));
187 if(getHitCount() > 0)
188 unHideMe($('result_low_hits_msg'));
191 for(var key in resultCompiledSearch.searches)
192 words.push(resultCompiledSearch.searches[key].term);
194 var sreq = new Request(CHECK_SPELL, words.join(' '));
195 sreq.callback(resultSuggestSpelling);
198 for(var key in resultCompiledSearch.searches) {
199 var areq = new Request(FETCH_CROSSREF, key, resultCompiledSearch.searches[key].term);
200 areq.callback(resultLowHitXRef);
204 if( !(getForm() == null || getForm() == 'all' || getForm() == "") ) {
206 a[PARAM_FORM] = "all";
207 $('low_hits_remove_format_link').setAttribute('href',buildOPACLink(a));
208 unHideMe($('low_hits_remove_format'));
211 resultSuggestSearchClass();
213 if(getTerm()) resultExpandSearch(); /* advanced search */
216 var lowHitsXRefSet = {};
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'));
224 var res = r.getResultObject();
226 arr.concat(res.also);
227 if(arr && arr.length > 0) {
228 unHideMe($('low_hits_cross_ref'));
231 while( word = arr.shift() ) {
233 if (lowHitsXRefSet[word] == 1) continue;
234 lowHitsXRefSet[word] = 1;
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(' '));
248 function resultZeroHits() {
250 unHideMe($('result_low_hits'));
251 unHideMe($('result_zero_hits_msg'));
252 //if(getTerm()) resultExpandSearch(); /* advanced search */
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'));
262 var bottom = getDepth();
263 while( top < bottom ) {
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);
274 function resultSuggestSearchClass() {
275 var stype = getStype();
276 if(stype == STYPE_KEYWORD) return;
278 unHideMe($('low_hits_search_type'));
279 if(stype != STYPE_TITLE) {
280 ref = $('low_hits_title_search');
282 a[PARAM_STYPE] = STYPE_TITLE;
283 ref.setAttribute('href',buildOPACLink(a));
285 if(stype != STYPE_AUTHOR) {
286 ref = $('low_hits_author_search');
288 a[PARAM_STYPE] = STYPE_AUTHOR;
289 ref.setAttribute('href',buildOPACLink(a));
291 if(stype != STYPE_SUBJECT) {
292 ref = $('low_hits_subject_search');
294 a[PARAM_STYPE] = STYPE_SUBJECT;
295 ref.setAttribute('href',buildOPACLink(a));
297 if(stype != STYPE_KEYWORD) {
298 ref = $('low_hits_keyword_search');
300 a[PARAM_STYPE] = STYPE_KEYWORD;
301 ref.setAttribute('href',buildOPACLink(a));
303 if(stype != STYPE_SERIES) {
304 ref = $('low_hits_series_search');
306 a[PARAM_STYPE] = STYPE_SERIES;
307 ref.setAttribute('href',buildOPACLink(a));
311 function resultSuggestSpelling(r) {
312 var res = r.getResultObject();
313 var phrase = getTerm();
314 var words = phrase.split(/ /);
318 for( var w = 0; w < words.length; w++ ) {
320 var blob = grep(res, function(i){return (i.word == word);});
321 if( blob ) blob = blob[0];
323 if( blob.word == word ) {
324 if( blob.suggestions && blob.suggestions[0] ) {
325 newterm += " " + blob.suggestions[0];
326 unHideMe($('did_you_mean'));
328 newterm += " " + word;
334 arg[PARAM_TERM] = newterm;
335 $('spell_check_link').setAttribute('href', buildOPACLink(arg));
336 $('spell_check_link').appendChild(text(newterm));
340 function resultPaginate() {
343 if( !( ((o) + getDisplayCount()) >= getHitCount()) ) {
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);
351 G.ui.result.next_link.setAttribute("href", buildOPACLink(args));
352 addCSSClass(G.ui.result.next_link, config.css.result.nav_active);
354 $('next_link2').setAttribute("href", buildOPACLink(args));
355 addCSSClass($('next_link2'), config.css.result.nav_active);
357 args[PARAM_OFFSET] = getHitCount() - (getHitCount() % getDisplayCount());
359 /* when hit count is divisible by display count, we have to adjust */
360 if( getHitCount() % getDisplayCount() == 0 )
361 args[PARAM_OFFSET] -= getDisplayCount();
364 G.ui.result.end_link.setAttribute("href", buildOPACLink(args));
365 addCSSClass(G.ui.result.end_link, config.css.result.nav_active);
367 $('end_link2').setAttribute("href", buildOPACLink(args));
368 addCSSClass($('end_link2'), config.css.result.nav_active);
375 args[PARAM_SORT] = SORT;
376 args[PARAM_SORT_DIR] = SORT_DIR;
377 args[PARAM_RLIST] = new CGI().param(PARAM_RLIST);
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);
383 $('prev_link2').setAttribute( "href", buildOPACLink(args));
384 addCSSClass($('prev_link2'), config.css.result.nav_active);
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);
390 $('search_home_link2').setAttribute( "href", buildOPACLink(args));
391 addCSSClass($('search_home_link2'), config.css.result.nav_active);
394 if(getDisplayCount() < getHitCount()) {
395 unHideMe($('start_end_links_span'));
396 unHideMe($('start_end_links_span2'));
400 try{searchTimer.stop()}catch(e){}
403 function buildunAPISpan (span, type, id) {
407 addCSSClass(span,'unapi-id');
411 'tag:' + cgi.server_name + ',' +
413 ':' + type + '/' + id
417 function unhideGoogleBooksLink (data) {
418 for ( var i in data ) {
419 //if (data[i].preview == 'noview') continue;
421 var gbspan = $n(document.documentElement, 'googleBooksLink-' + i);
422 var gba = $n(gbspan, "googleBooks-link");
428 removeCSSClass( gbspan, 'hide_me' );
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) {
436 if(rec == null) rec = new mvr(); /* so the page won't die if there was an error */
438 recordsCache.push(rec);
440 var r = table.rows[pos + 1];
441 var currentISBN = cleanISBN(rec.isbn());
443 if (googleBooksLink) {
444 var gbspan = $n(r, "googleBooksLink");
448 gbspan.getAttribute('name') + '-' + currentISBN
451 if (isbnList) isbnList += ', ';
452 isbnList += currentISBN;
456 if (currentISBN && chilifresh && chilifresh != '(none)') {
457 var cfrow = $n(r, "chilifreshReview");
459 removeCSSClass( cfrow, 'hide_me' );
461 var cflink = $n(r, "chilifreshReviewLink");
465 'isbn_' + currentISBN
468 var cfdiv = $n(r, "chilifreshReviewResult");
472 'chili_review_' + currentISBN
479 var rank = parseFloat(ranks[pos + getOffset()]);
480 rank = parseInt( rank * 100 );
481 var relspan = $n(r, "relevancy_span");
482 relspan.appendChild(text(rank));
483 unHideMe(relspan.parentNode);
487 var pic = $n(r, config.names.result.item_jacket);
488 pic.setAttribute("src", buildISBNSrc(currentISBN));
490 var title_link = $n(r, config.names.result.item_title);
491 var author_link = $n(r, config.names.result.item_author);
494 var onlyrec = onlyrecord[ getOffset() + pos ];
496 buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', onlyrec);
500 args[PARAM_OFFSET] = 0;
501 args[PARAM_RID] = onlyrec;
502 args[PARAM_MRID] = rec.doc_id();
503 pic.parentNode.setAttribute("href", buildOPACLink(args));
504 title_link.setAttribute("href", buildOPACLink(args));
505 title_link.appendChild(text(normalize(truncate(rec.title(), 65))));
507 var here = findOrgUnit(getLocation());
508 if (findOrgType(here.ou_type()).can_have_vols()) { // show the callnumber list
509 dojo.require('openils.BibTemplate');
510 var l_cn_list = $n(r,'local_callnumber_list');
515 new openils.BibTemplate({
517 record : '' + onlyrec + '[10]',
518 org_unit : here.shortname()
525 buildunAPISpan($n(r,'unapi'), 'metabib-metarecord', rec.doc_id());
527 buildTitleLink(rec, title_link);
530 args[PARAM_OFFSET] = 0;
531 args[PARAM_MRID] = rec.doc_id();
532 pic.parentNode.setAttribute("href", buildOPACLink(args));
535 unHideMe($n(r,'place_hold_span'));
536 $n(r,'place_hold_link').setAttribute(
537 'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"M"});');
540 buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', rec.doc_id());
542 buildTitleDetailLink(rec, title_link);
545 args[PARAM_OFFSET] = 0;
546 args[PARAM_RID] = rec.doc_id();
547 pic.parentNode.setAttribute("href", buildOPACLink(args));
549 unHideMe($n(r,'place_hold_span'));
550 $n(r,'place_hold_link').setAttribute(
551 'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"T"});');
553 var here = findOrgUnit(getLocation());
554 if (findOrgType(here.ou_type()).can_have_vols()) { // show the callnumber list
555 dojo.require('openils.BibTemplate');
556 var l_cn_list = $n(r,'local_callnumber_list');
557 var onlyrec = rec.doc_id();
562 new openils.BibTemplate({
564 record : '' + onlyrec + '[10]',
565 org_unit : here.shortname()
572 buildSearchLink(STYPE_AUTHOR, rec.author(), author_link);
576 if(!isNull(rec.edition())) {
577 unHideMe( $n(r, "result_table_extra_span"));
578 $n(r, "result_table_edition_span").appendChild( text( rec.edition()) );
580 if(!isNull(rec.pubdate())) {
581 unHideMe( $n(r, "result_table_extra_span"));
582 unHideMe($n(r, "result_table_pub_span"));
583 $n(r, "result_table_pub_span").appendChild( text( rec.pubdate() ));
585 if(!isNull(rec.publisher()) ) {
586 unHideMe( $n(r, "result_table_extra_span"));
587 unHideMe($n(r, "result_table_pub_span"));
588 $n(r, "result_table_pub_span").appendChild( text( " " + rec.publisher() ));
591 if(!isNull(rec.physical_description()) ) {
592 unHideMe( $n(r, "result_table_extra_span"));
593 var t = " " + rec.physical_description();
594 //$n(r, "result_table_phys_span").appendChild( text(t.replace(/:.*/g,'')));
595 $n(r, "result_table_phys_span").appendChild( text(t));
600 resultBuildFormatIcons( r, rec, is_mr );
604 runEvt("result", "recordDrawn", rec.doc_id(), title_link);
607 if(resultPageIsDone()) {
608 runEvt('result', 'allRecordsReceived', recordsCache);
613 function _resultFindRec(id) {
614 for( var i = 0; i != recordsCache.length; i++ ) {
615 var rec = recordsCache[i];
616 if( rec && rec.doc_id() == id )
623 function resultBuildFormatIcons( row, rec, is_mr ) {
625 var ress = rec.types_of_resource();
627 for( var i in ress ) {
632 var link = $n(row, res + "_link");
634 var img = link.getElementsByTagName("img")[0];
635 removeCSSClass( img, config.css.dim );
639 if( f == modsFormatToMARC(res) )
640 addCSSClass( img, "dim2_border");
644 args[PARAM_OFFSET] = 0;
648 args[PARAM_TFORM] = modsFormatToMARC(res);
649 args[PARAM_MRID] = rec.doc_id();
653 args[PARAM_RID] = rec.doc_id();
656 link.setAttribute("href", buildOPACLink(args));
661 function fetchGoogleBooksLink () {
662 if (isbnList && googleBooksLink) {
663 var scriptElement = document.createElement("script");
664 scriptElement.setAttribute("id", "jsonScript");
665 scriptElement.setAttribute("src",
666 "http://books.google.com/books?bibkeys=" +
667 escape(isbnList) + "&jscmd=viewapi&callback=unhideGoogleBooksLink");
668 scriptElement.setAttribute("type", "text/javascript");
669 // make the request to Google Book Search
670 document.documentElement.firstChild.appendChild(scriptElement);
674 function fetchChiliFreshReviews() {
675 if (chilifresh && chilifresh != '(none)') {
676 try { chili_init(); } catch(E) { dump(E + '\n'); }
680 function resultPageIsDone(pos) {
682 return (recordsHandled == getDisplayCount()
683 || recordsHandled + getOffset() == getHitCount());
686 var resultCCHeaderApplied = false;
688 /* -------------------------------------------------------------------- */
689 /* dynamically add the copy count rows based on the org type 'countsrow'
690 is the row into which we will add TD's to hold the copy counts
691 This code generates copy count cells with an id of
692 'copy_count_cell_<depth>_<pagePosition>' */
693 function resultAddCopyCounts(rec, pagePosition) {
695 var r = table.rows[pagePosition + 1];
696 var countsrow = $n(r, config.names.result.counts_row );
697 var ccell = $n(countsrow, config.names.result.count_cell);
699 var nodes = orgNodeTrail(findOrgUnit(getLocation()));
701 var type = findOrgType(node.ou_type());
702 ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
703 ccell.title = type.opac_label();
704 //addCSSClass(ccell, config.css.result.cc_cell_even);
706 var lastcell = ccell;
707 var lastheadcell = null;
710 var ccheadcell = null;
711 if(!resultCCHeaderApplied && !getLasso()) {
712 ccrow = $('result_thead_row');
713 ccheadcell = ccrow.removeChild($n(ccrow, "result_thead_ccell"));
714 var t = ccheadcell.cloneNode(true);
716 t.appendChild(text(type.opac_label()));
717 ccrow.appendChild(t);
718 resultCCHeaderApplied = true;
724 var d = findOrgDepth(nodes[1]);
725 var d2 = findOrgDepth(nodes[nodes.length -1]);
727 for( var i = d; i <= d2 ; i++ ) {
729 ccell = ccell.cloneNode(true);
731 //if((i % 2)) removeCSSClass(ccell, "copy_count_cell_even");
732 //else addCSSClass(ccell, "copy_count_cell_even");
734 var node = nodes[x++];
735 var type = findOrgType(node.ou_type());
737 ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
738 ccell.title = type.opac_label();
739 countsrow.insertBefore(ccell, lastcell);
743 var t = ccheadcell.cloneNode(true);
744 t.appendChild(text(type.opac_label()));
745 ccrow.insertBefore(t, lastheadcell);
751 unHideMe($("search_info_table"));
754 /* collect copy counts for a record using method 'methodName' */
755 function resultCollectCopyCounts(rec, pagePosition, methodName) {
756 if(rec == null || rec.doc_id() == null) return;
758 var loc = getLasso();
760 else loc= getLocation();
762 var req = new Request(methodName, loc, rec.doc_id(), getForm() );
763 req.request.userdata = [ rec, pagePosition ];
764 req.callback(resultHandleCopyCounts);
768 function resultHandleCopyCounts(r) {
769 runEvt('result', 'copyCountsReceived', r.userdata[0], r.userdata[1], r.getResultObject());
773 /* XXX Needs to understand Lasso copy counts... */
774 /* display the collected copy counts */
775 function resultDisplayCopyCounts(rec, pagePosition, copy_counts) {
776 if(copy_counts == null || rec == null) return;
779 var copy_counts_lasso = {
785 org_unit : getLasso()
788 for (var i in copy_counts) {
789 copy_counts_lasso.transcendant = copy_counts[i].transcendant;
790 copy_counts_lasso.count += parseInt(copy_counts[i].count);
791 copy_counts_lasso.unshadow += parseInt(copy_counts[i].unshadow);
792 copy_counts_lasso.available += parseInt(copy_counts[i].available);
795 copy_counts = [ copy_counts_lasso ];
799 while(copy_counts[i] != null) {
800 var cell = $("copy_count_cell_" + i +"_" + pagePosition);
801 var cts = copy_counts[i];
802 cell.appendChild(text(cts.available + " / " + cts.count));
805 /* here we style opac-invisible records for xul */
807 if( cts.depth == 0 ) {
808 if(cts.transcendant == null && cts.unshadow == 0) {
809 _debug("found an opac-shadowed record: " + rec.doc_id());
810 var row = cell.parentNode.parentNode.parentNode.parentNode.parentNode;
812 addCSSClass( row, 'no_copies' );
814 addCSSClass( row, 'shadowed' );