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