]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/result_common.js
updated to new spell check method
[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         var phrase = getTerm();
260         var words = phrase.split(/ /);
261
262         var newterm = "";
263
264         for( var w = 0; w < words.length; w++ ) {
265                 var word = words[w];
266                 var blob = grep(res, function(i){return (i.word == word);})[0];
267                 if( blob.word == word ) {
268                         if( blob.suggestions ) {
269                                 newterm += " " + blob.suggestions[0];
270                                 unHideMe($('did_you_mean'));
271                         } else {
272                                 newterm += " " + word;
273                         }
274                 }
275         }
276
277         var arg = {};
278         arg[PARAM_TERM] = newterm;
279         $('spell_check_link').setAttribute('href', buildOPACLink(arg));
280         $('spell_check_link').appendChild(text(newterm));
281 }
282
283
284 function resultPaginate() {
285         var o = getOffset();
286
287         if( !(( (o+1) + getDisplayCount()) >= getHitCount()) ) {
288
289                 var args = {};
290                 args[PARAM_OFFSET]      = o + getDisplayCount();
291                 args[PARAM_SORT]                = SORT;
292                 args[PARAM_SORT_DIR] = SORT_DIR;
293                 args[PARAM_RLIST]               = new CGI().param(PARAM_RLIST);
294
295                 G.ui.result.next_link.setAttribute("href", buildOPACLink(args)); 
296                 addCSSClass(G.ui.result.next_link, config.css.result.nav_active);
297
298                 args[PARAM_OFFSET] = getHitCount() - (getHitCount() % getDisplayCount());
299
300                 /* when hit count is divisible by display count, we have to adjust */
301                 if( getHitCount() % getDisplayCount() == 0 ) 
302                         args[PARAM_OFFSET] -= getDisplayCount();
303
304                 G.ui.result.end_link.setAttribute("href", buildOPACLink(args)); 
305                 addCSSClass(G.ui.result.end_link, config.css.result.nav_active);
306         }
307
308         if( o > 0 ) {
309
310                 var args = {};
311                 args[PARAM_SORT]                = SORT;
312                 args[PARAM_SORT_DIR] = SORT_DIR;
313                 args[PARAM_RLIST]               = new CGI().param(PARAM_RLIST);
314
315                 args[PARAM_OFFSET] = o - getDisplayCount();
316                 G.ui.result.prev_link.setAttribute( "href", buildOPACLink(args)); 
317                 addCSSClass(G.ui.result.prev_link, config.css.result.nav_active);
318
319                 args[PARAM_OFFSET] = 0;
320                 G.ui.result.home_link.setAttribute( "href", buildOPACLink(args)); 
321                 addCSSClass(G.ui.result.home_link, config.css.result.nav_active);
322         }
323
324         if(getDisplayCount() < getHitCount())
325                 unHideMe($('start_end_links_span'));
326
327         showCanvas();
328         try{searchTimer.stop()}catch(e){}
329 }
330
331 function buildunAPISpan (span, type, id) {
332         var cgi = new CGI();
333         var d = new Date();
334
335         addCSSClass(span,'unapi-id');
336
337         span.setAttribute(
338                 'title',
339                 'tag:' + cgi.server_name + ',' +
340                         d.getFullYear() +
341                         ':' + type + '/' + id
342         );
343 }
344
345 /* display the record info in the record display table 'pos' is the 
346                 zero based position the record should have in the display table */
347 function resultDisplayRecord(rec, pos, is_mr) {
348
349         if(rec == null) rec = new mvr(); /* so the page won't die if there was an error */
350         recordsHandled++;
351         recordsCache.push(rec);
352
353         var r = table.rows[pos + 1];
354
355         
356         try {
357                 var rank = parseFloat(ranks[pos + getOffset()]);
358                 rank            = parseInt( rank * 100 );
359                 var relspan = $n(r, "relevancy_span");
360                 relspan.appendChild(text(rank));
361                 unHideMe(relspan.parentNode);
362         } catch(e){ }
363
364         var pic = $n(r, config.names.result.item_jacket);
365         pic.setAttribute("src", buildISBNSrc(cleanISBN(rec.isbn())));
366
367         var title_link = $n(r, config.names.result.item_title);
368         var author_link = $n(r, config.names.result.item_author);
369
370         if( is_mr )  {
371                 var onlyrec = onlyrecord[ getOffset() + pos ];
372                 if(onlyrec) {
373                         buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', onlyrec);
374
375                         var args = {};
376                         args.page = RDETAIL;
377                         args[PARAM_OFFSET] = 0;
378                         args[PARAM_RID] = onlyrec;
379                         args[PARAM_MRID] = rec.doc_id();
380                         pic.parentNode.setAttribute("href", buildOPACLink(args));
381                         title_link.setAttribute("href", buildOPACLink(args));
382                         title_link.appendChild(text(normalize(truncate(rec.title(), 65))));
383                         
384                 } else {
385                         buildunAPISpan($n(r,'unapi'), 'metabib-metarecord', rec.doc_id());
386
387                         buildTitleLink(rec, title_link); 
388                         var args = {};
389                         args.page = RRESULT;
390                         args[PARAM_OFFSET] = 0;
391                         args[PARAM_MRID] = rec.doc_id();
392                         pic.parentNode.setAttribute("href", buildOPACLink(args));
393                 }
394
395         } else {
396                 buildunAPISpan($n(r,'unapi'), 'biblio-record_entry', rec.doc_id());
397
398                 buildTitleDetailLink(rec, title_link); 
399                 var args = {};
400                 args.page = RDETAIL;
401                 args[PARAM_OFFSET] = 0;
402                 args[PARAM_RID] = rec.doc_id();
403                 pic.parentNode.setAttribute("href", buildOPACLink(args));
404
405                 unHideMe($n(r,'place_hold_span'));
406                 $n(r,'place_hold_link').setAttribute(
407                         'href','javascript:holdsDrawEditor({record:"'+rec.doc_id()+'",type:"T"});');
408         }
409
410         buildSearchLink(STYPE_AUTHOR, rec.author(), author_link);
411
412         if(! is_mr ) {
413         
414                 if(!isNull(rec.edition()))      {
415                         unHideMe( $n(r, "result_table_extra_span"));
416                         $n(r, "result_table_edition_span").appendChild( text( rec.edition()) );
417                 }
418                 if(!isNull(rec.pubdate())) {
419                         unHideMe( $n(r, "result_table_extra_span"));
420                         unHideMe($n(r, "result_table_pub_span"));
421                         $n(r, "result_table_pub_span").appendChild( text( rec.pubdate() ));
422                 }
423                 if(!isNull(rec.publisher()) ) {
424                         unHideMe( $n(r, "result_table_extra_span"));
425                         unHideMe($n(r, "result_table_pub_span"));
426                         $n(r, "result_table_pub_span").appendChild( text( " " + rec.publisher() ));
427                 }
428
429                 if(!isNull(rec.physical_description()) ) {
430                         unHideMe( $n(r, "result_table_extra_span"));
431                         var t = " " + rec.physical_description();
432                         //$n(r, "result_table_phys_span").appendChild( text(t.replace(/:.*/g,'')));
433                         $n(r, "result_table_phys_span").appendChild( text(t));
434                 }
435
436         }
437
438         resultBuildFormatIcons( r, rec, is_mr );
439
440         unHideMe(r);
441         
442         runEvt("result", "recordDrawn", rec.doc_id(), title_link);
443
444         /*
445         if(resultPageIsDone())  {
446                 runEvt('result', 'allRecordsReceived', recordsCache);
447         }
448         */
449 }
450
451 function _resultFindRec(id) {
452         for( var i = 0; i != recordsCache.length; i++ ) {
453                 var rec = recordsCache[i];
454                 if( rec && rec.doc_id() == id )
455                         return rec;
456         }
457         return null;
458 }
459
460
461 function resultBuildFormatIcons( row, rec, is_mr ) {
462
463         var ress = rec.types_of_resource();
464
465         for( var i in ress ) {
466
467                 var res = ress[i];
468                 if(!res) continue;
469
470                 var link = $n(row, res + "_link");
471                 link.title = res;
472                 var img = link.getElementsByTagName("img")[0];
473                 removeCSSClass( img, config.css.dim );
474
475                 var f = getForm();
476                 if( f != "all" ) {
477                         if( f == modsFormatToMARC(res) ) 
478                                 addCSSClass( img, "dim2_border");
479                 }
480
481                 var args = {};
482                 args[PARAM_OFFSET] = 0;
483
484                 if(is_mr) {
485                         args.page = RRESULT;
486                         args[PARAM_TFORM] = modsFormatToMARC(res);
487                         args[PARAM_MRID] = rec.doc_id();
488
489                 } else {
490                         args.page = RDETAIL
491                         args[PARAM_RID] = rec.doc_id();
492                 }
493
494                 link.setAttribute("href", buildOPACLink(args));
495
496         }
497 }
498
499
500 function resultPageIsDone(pos) {
501         return (recordsHandled == getDisplayCount() 
502                 || recordsHandled + getOffset() == getHitCount());
503 }
504
505 var resultCCHeaderApplied = false;
506
507 /* -------------------------------------------------------------------- */
508 /* dynamically add the copy count rows based on the org type 'countsrow' 
509         is the row into which we will add TD's to hold the copy counts 
510         This code generates copy count cells with an id of
511         'copy_count_cell_<depth>_<pagePosition>'  */
512 function resultAddCopyCounts(rec, pagePosition) {
513
514         var r = table.rows[pagePosition + 1];
515         var countsrow = $n(r, config.names.result.counts_row );
516         var ccell = $n(countsrow, config.names.result.count_cell);
517
518         var nodes = orgNodeTrail(findOrgUnit(getLocation()));
519         var node = nodes[0];
520         var type = findOrgType(node.ou_type());
521         ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
522         ccell.title = type.opac_label();
523         //addCSSClass(ccell, config.css.result.cc_cell_even);
524
525         var lastcell = ccell;
526         var lastheadcell = null;
527
528         var cchead = null;
529         var ccheadcell = null;
530         if(!resultCCHeaderApplied) {
531                 ccrow = $('result_thead_row');
532                 ccheadcell =  ccrow.removeChild($n(ccrow, "result_thead_ccell"));
533                 var t = ccheadcell.cloneNode(true);
534                 lastheadcell = t;
535                 t.appendChild(text(type.opac_label()));
536                 ccrow.appendChild(t);
537                 resultCCHeaderApplied = true;
538         }
539
540         if(nodes[1]) {
541
542                 var x = 1;
543                 var d = findOrgDepth(nodes[1]);
544                 var d2 = findOrgDepth(nodes[nodes.length -1]);
545
546                 for( var i = d; i <= d2 ; i++ ) {
547         
548                         ccell = ccell.cloneNode(true);
549
550                         //if((i % 2)) removeCSSClass(ccell, "copy_count_cell_even");
551                         //else addCSSClass(ccell, "copy_count_cell_even");
552
553                         var node = nodes[x++];
554                         var type = findOrgType(node.ou_type());
555         
556                         ccell.id = "copy_count_cell_" + type.depth() + "_" + pagePosition;
557                         ccell.title = type.opac_label();
558                         countsrow.insertBefore(ccell, lastcell);
559                         lastcell = ccell;
560
561                         if(ccheadcell) {
562                                 var t = ccheadcell.cloneNode(true);
563                                 t.appendChild(text(type.opac_label()));
564                                 ccrow.insertBefore(t, lastheadcell);
565                                 lastheadcell = t;
566                         }
567                 }
568         }
569
570         unHideMe($("search_info_table"));
571 }
572
573 /* collect copy counts for a record using method 'methodName' */
574 function resultCollectCopyCounts(rec, pagePosition, methodName) {
575         if(rec == null || rec.doc_id() == null) return;
576         var req = new Request(methodName, getLocation(), rec.doc_id(), getForm() );
577         req.request.userdata = [ rec, pagePosition ];
578         req.callback(resultHandleCopyCounts);
579         req.send();
580 }
581
582 function resultHandleCopyCounts(r) {
583         runEvt('result', 'copyCountsReceived', r.userdata[0], r.userdata[1], r.getResultObject()); 
584 }
585
586
587 /* display the collected copy counts */
588 function resultDisplayCopyCounts(rec, pagePosition, copy_counts) {
589         if(copy_counts == null || rec == null) return;
590         var i = 0;
591         while(copy_counts[i] != null) {
592                 var cell = $("copy_count_cell_" + i +"_" + pagePosition);
593                 var cts = copy_counts[i];
594                 cell.appendChild(text(cts.available + " / " + cts.count));
595
596                 if(isXUL()) {
597                         /* here we style opac-invisible records for xul */
598
599                         if( cts.depth == 0 ) {
600                                 if(!cts.unshadow) {
601                                         _debug("found an opac-shadowed record: " + rec.doc_id());
602                                         var row = cell.parentNode.parentNode.parentNode.parentNode.parentNode; 
603                                         if( cts.count == 0 ) 
604                                                 addCSSClass( row, 'no_copies' );
605                                         else 
606                                                 addCSSClass( row, 'shadowed' );
607                                 }
608                         }
609                 }
610
611                 i++;
612         }
613 }
614
615