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);
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;
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);
466 var pic = $n(r, config.names.result.item_jacket);
467 pic.setAttribute("src", buildISBNSrc(currentISBN));
469 var title_link = $n(r, config.names.result.item_title);
470 var author_link = $n(r, config.names.result.item_author);
473 var onlyrec = onlyrecord[ getOffset() + pos ];
475 buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', onlyrec);
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))));
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');
494 new openils.BibTemplate({
496 record : '' + onlyrec + '[10]',
497 org_unit : here.shortname()
504 buildunAPISpan($n(r,'unapi'), 'metabib-metarecord', rec.doc_id());
506 buildTitleLink(rec, title_link);
509 args[PARAM_OFFSET] = 0;
510 args[PARAM_MRID] = rec.doc_id();
511 pic.parentNode.setAttribute("href", buildOPACLink(args));
514 unHideMe($n(r,'place_hold_span'));
515 $n(r,'place_hold_link').setAttribute(
516 'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"M"});');
519 buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', rec.doc_id());
521 buildTitleDetailLink(rec, title_link);
524 args[PARAM_OFFSET] = 0;
525 args[PARAM_RID] = rec.doc_id();
526 pic.parentNode.setAttribute("href", buildOPACLink(args));
528 unHideMe($n(r,'place_hold_span'));
529 $n(r,'place_hold_link').setAttribute(
530 'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"T"});');
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();
541 new openils.BibTemplate({
543 record : '' + onlyrec + '[10]',
544 org_unit : here.shortname()
551 buildSearchLink(STYPE_AUTHOR, rec.author(), author_link);
555 if(!isNull(rec.edition())) {
556 unHideMe( $n(r, "result_table_extra_span"));
557 $n(r, "result_table_edition_span").appendChild( text( rec.edition()) );
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() ));
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() ));
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));
579 resultBuildFormatIcons( r, rec, is_mr );
583 runEvt("result", "recordDrawn", rec.doc_id(), title_link);
586 if(resultPageIsDone()) {
587 runEvt('result', 'allRecordsReceived', recordsCache);
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 )
602 function resultBuildFormatIcons( row, rec, is_mr ) {
604 var ress = rec.types_of_resource();
606 for( var i in ress ) {
611 var link = $n(row, res + "_link");
613 var img = link.getElementsByTagName("img")[0];
614 removeCSSClass( img, config.css.dim );
618 if( f == modsFormatToMARC(res) )
619 addCSSClass( img, "dim2_border");
623 args[PARAM_OFFSET] = 0;
627 args[PARAM_TFORM] = modsFormatToMARC(res);
628 args[PARAM_MRID] = rec.doc_id();
632 args[PARAM_RID] = rec.doc_id();
635 link.setAttribute("href", buildOPACLink(args));
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);
653 function resultPageIsDone(pos) {
655 return (recordsHandled == getDisplayCount()
656 || recordsHandled + getOffset() == getHitCount());
659 var resultCCHeaderApplied = false;
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) {
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);
672 var nodes = orgNodeTrail(findOrgUnit(getLocation()));
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);
679 var lastcell = ccell;
680 var lastheadcell = 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);
689 t.appendChild(text(type.opac_label()));
690 ccrow.appendChild(t);
691 resultCCHeaderApplied = true;
697 var d = findOrgDepth(nodes[1]);
698 var d2 = findOrgDepth(nodes[nodes.length -1]);
700 for( var i = d; i <= d2 ; i++ ) {
702 ccell = ccell.cloneNode(true);
704 //if((i % 2)) removeCSSClass(ccell, "copy_count_cell_even");
705 //else addCSSClass(ccell, "copy_count_cell_even");
707 var node = nodes[x++];
708 var type = findOrgType(node.ou_type());
710 ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
711 ccell.title = type.opac_label();
712 countsrow.insertBefore(ccell, lastcell);
716 var t = ccheadcell.cloneNode(true);
717 t.appendChild(text(type.opac_label()));
718 ccrow.insertBefore(t, lastheadcell);
724 unHideMe($("search_info_table"));
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;
731 var loc = getLasso();
733 else loc= getLocation();
735 var req = new Request(methodName, loc, rec.doc_id(), getForm() );
736 req.request.userdata = [ rec, pagePosition ];
737 req.callback(resultHandleCopyCounts);
741 function resultHandleCopyCounts(r) {
742 runEvt('result', 'copyCountsReceived', r.userdata[0], r.userdata[1], r.getResultObject());
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;
752 var copy_counts_lasso = {
758 org_unit : getLasso()
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);
768 copy_counts = [ copy_counts_lasso ];
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));
778 /* here we style opac-invisible records for xul */
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;
785 addCSSClass( row, 'no_copies' );
787 addCSSClass( row, 'shadowed' );