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