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