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