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