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