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