2 AbstractRecordResultPage.prototype = new Page();
3 AbstractRecordResultPage.prototype.constructor = AbstractRecordResultPage;
4 AbstractRecordResultPage.baseClass = Page.constructor;
7 /* constructor for our singleton object */
8 function AbstractRecordResultPage() {}
11 /* initialize all of the UI components and set up data structures */
12 AbstractRecordResultPage.prototype.init = function() {
14 debug( "Initing an AbstractRecordResultPage" );
16 /* included page chunks */
17 this.searchBar = new SearchBarChunk();
20 this.recordBox = getById("record_result_box");
22 this.authorBox = new Box();
23 this.authorBox.init("Relevant Authors", true, true, 15);
24 this.authorBox.sortByKey();
26 this.subjectBox = new Box();
27 this.subjectBox.init("Relevant Subjects", true, true, 15);
28 this.subjectBox.sortByCount();
30 this.seriesBox = new Box();
31 this.seriesBox.init("Relevant Series", true, true, 15);
32 this.seriesBox.sortByKey();
34 this.sidebarBox = getById("record_sidebar_box");
36 this.sidebarBox.appendChild(this.buildNavBox());
37 this.sidebarBox.appendChild(elem("br"));
40 this.hitsPerPage = 10; /* how many hits are displayed per page */
44 this.statusBar = getById("top_status_bar_table");
45 this.theadDrawn = false;
46 this.bigOlBox = getById("big_ol_box");
52 /** Resets data structures for a new search */
53 AbstractRecordResultPage.prototype.resetPage = function() {
54 this.searchBar.reset();
55 var spot = getById("progress_bar_location");
56 var spot2 = getById("progress_bar_percent_location");
59 spot.removeChild(spot.lastChild);
61 /* progress items for each record and it's hit count listing */
62 this.progressBar = new ProgressBar(parseInt(this.hitsPerPage) * 2);
63 spot.appendChild(this.progressBar.getNode());
65 if(spot2 && this.progressBar)
66 spot2.appendChild(this.progressBar.percentDiv);
69 RemoteRequest.cancelAll();
71 this.requestBatch = new RequestBatch();
72 this.finalized = false;
73 this.builtLinks = false;
75 this.hitsPerPageSelector = getById('hits_per_page');
78 this.hitsPerPageSelector.onchange = function() {
81 var hits_obj = obj.hitsPerPageSelector.options[
82 obj.hitsPerPageSelector.selectedIndex];
89 debug("Hits per page set to " + hits );
91 obj.hitsPerPage = parseInt(hits);
94 var location = globalSelectedLocation;
95 if(location == null) location = globalLocation.id();
97 url_redirect(obj.URLRefresh());
102 for( var i in this.hitsPerPageSelector.options ) {
104 var hits_obj = obj.hitsPerPageSelector.options[i];
105 if(hits_obj == null) continue;
106 var hits = hits_obj.value;
108 if( this.hitsPerPage == parseInt(hits) )
109 this.hitsPerPageSelector.options[i].selected = true;
115 AbstractRecordResultPage.prototype.resetSearch = function() {
116 this.recordIDs = new Array();
117 this.ranks = new Array();
118 this.hitCount = 0; /* hits for the current search */
119 this.searchOffset = 0; /* the offset for the search display */
124 AbstractRecordResultPage.prototype.gatherIDs = function(result) {
125 if(result == null) return;
127 this.hitCount = parseInt(result.count);
129 if(result.ids.length < 1) {
135 /* the 'ids' field consist of [record, rank] */
136 /* gather all of the ID's */
137 if( result.ids && typeof result.ids == 'object'
138 && result.ids[0] != null
139 && result.ids[0].constructor == Array ) {
141 for( var i in result.ids ) {
142 if(result.ids[i]==null || result.ids[i][0] == null) break;
143 var offset = parseInt(i) + parseInt(this.searchOffset);
144 this.recordIDs[offset] = result.ids[i][0];
145 var rank = parseFloat(result.ids[i][1]);
147 rank = 0.00000001; /* protect divide by 0 */
148 this.ranks[offset] = rank;
150 debug("adding ranks[" + offset + "] = " + result.ids[i][1] +
151 " \nrecordIDs["+offset+"], result.ids["+i+"][0]");
157 for( var i in result.ids ) {
158 if(result.ids[i]==null) break;
159 var offset = parseInt(i) + parseInt(this.searchOffset);
160 this.recordIDs[offset] = result.ids[i];
161 debug("adding recordIDs["+offset+"], result.ids["+i+"]");
170 AbstractRecordResultPage.prototype.complete = function() {
175 AbstractRecordResultPage.prototype.displayRecord =
176 function( record, search_id, page_id ) {
178 if(record == null) return;
179 debug("Displaying record " + record.doc_id());
181 if(!instanceOf(record, Fieldmapper)) {
182 debug(" * Received bogus record " + js2JSON(record));
187 this.buildNextLinks();
191 this.progressBar.manualNext();
193 var id = parseInt(page_id);
194 var title_row = table_row_find_or_create(this.recordBox, id * 3 + 1 );
195 var author_row = table_row_find_or_create(this.recordBox, id * 3 + 2 );
196 var misc_row = table_row_find_or_create(this.recordBox, id * 3 + 3 );
198 add_css_class(misc_row, "record_misc_row");
199 add_css_class(title_row, "record_title_row");
202 var c = misc_row.insertCell(0);
204 /* shove in a div for each of the types of resource */
205 for( var i = 0; i!= 9; i++) {
206 var div = createAppElement("div");
207 div.innerHTML = " ";
208 add_css_class(div, "record_resource_div");
211 //var options_cell = misc_row.insertCell(1);
213 c.className = "record_misc_cell";
214 var resources = record.types_of_resource();
216 for( var i in resources ) {
219 if(instanceOf(this,MRResultPage)) {
220 var prefix = "http://" + globalRootURL + ":" + globalPort + globalRootPath;
221 var res = modsFormatToMARC(resources[i]);
223 {href: prefix + "?target=record_result&mrid=" +
224 record.doc_id() + "&format=" + res +
225 "&page=0&location=" + this.searchLocation +
226 "&depth=" + this.searchDepth} );
228 this.buildResourcePic( c, resources[i], a);
231 author_row.id = "record_result_author_row_" + id;
232 title_row.id = "record_result_title_row_" + id;
234 /* build the appropriate context node for this result */
235 var menu_name = "record_result_row_" + page_id;
236 var menu = globalMenuManager.buildMenu(menu_name);
238 this.addMenuItems( menu, record );
240 globalMenuManager.setContext(title_row, menu);
241 globalMenuManager.setContext(author_row, menu);
242 globalMenuManager.setContext(misc_row, menu);
244 getDocument().body.appendChild(menu.getNode());
246 //var optionsLink = this.buildExtendedLinks(record, page_id);
248 // options_cell.appendChild(optionsLink);
249 /* ------------------------------------ */
252 var pic_cell = title_row.insertCell(0);
253 this.buildRecordImage( pic_cell, record, page_id, record.title());
255 var title_cell = title_row.insertCell(title_row.cells.length);
256 title_cell.id = "record_result_title_box_" + id;
257 add_css_class( title_cell, "record_result_title_box");
259 var author_cell = author_row.insertCell(author_row.cells.length);
260 author_cell.id = "record_result_author_box_" + id;
261 add_css_class(author_cell, "record_result_author_box");
264 /* limit the length of the title and author lines */
268 if( record.title() ) {
269 if(record.title().length > tlength) {
270 record.title(record.title().substr(0,tlength));
271 record.title(record.title() + "...");
273 title = normalize(record.title());
278 if( record.author() ) {
279 if(record.author().length > tlength) {
280 record.author( record.author().substr(0,tlength));
281 record.author(record.author() + "...");
283 author = normalize(record.author());
286 title_cell.appendChild(this.mkLink(record.doc_id(), "title", title, record.title() ));
287 author_cell.innerHTML = " ";
288 author_cell.appendChild(this.mkLink(record.doc_id(), "author", author ));
291 if(instanceOf(this, RecordResultPage)) {
292 var span = createAppElement("span");
293 span.style.marginLeft = "10px";
295 if(record.pubdate() || record.edition())
296 span.appendChild(createAppTextNode(" -- "));
299 span.appendChild(createAppTextNode(" " + record.pubdate()));
302 span.appendChild(createAppTextNode(" " + record.edition()));
304 author_cell.appendChild(span);
306 var marcb = elem( "a",
307 { href:"javascript:void(0)",
308 style: "text-decoration:underline;"
309 }, null, "View MARC" );
311 debug("Setting up view marc callback with record " + record.doc_id());
312 var func = buildViewMARCWindow(record);
313 marcb.onclick = func;
315 marcd = elem( "div", { style: "float:right;font-size:x-small;" } );
316 marcd.appendChild(marcb);
321 if(instanceOf(this, RecordResultPage)) {
323 var holds = elem( "a",
325 href:"javascript:void(0)",
326 style: "text-decoration:underline"
327 }, {}, "Place Hold" );
331 if(instanceOf(this, RecordResultPage))
335 var user = UserSession.instance();
336 if(user.verifySession()) {
337 win = new HoldsWindow(record.doc_id(),
338 type, user.userObject, user.userObject, user.session_id);
340 win = new HoldsWindow(record.doc_id(),
341 type, null, null, null);
345 holds.onclick = function() { win.toggle(holds); }
346 holddiv = elem("div");
348 //if(instanceOf(this,RecordResultPage))
349 holddiv.setAttribute("style", "float:right");
351 holddiv.appendChild(holds);
352 //var space = elem("span", {style:"padding:5px"},null, " ");
353 //c.appendChild(space)
354 //c.appendChild(mktext(" "))
355 //c.appendChild(holddiv)
358 var tab = elem("table",{style:"float:right"});
359 var tr = tab.insertRow(0);
360 var tc = tr.insertCell(0);
361 var tc2 = tr.insertCell(1);
362 var tc3 = tr.insertCell(2);
363 tc.setAttribute("nowrap", "nowrap");
364 tc3.setAttribute("nowrap", "nowrap");
366 if(holddiv) tc.appendChild(holddiv);
367 tc2.appendChild(mktext(" "));
368 if(marcd) tc3.appendChild(marcd);
374 var classname = "result_even";
375 if((page_id % 2) != 0)
376 classname = "result_odd";
378 add_css_class(title_row, classname);
379 add_css_class(author_row, classname);
380 add_css_class(misc_row, classname);
382 /* now grab the record authors and subjects */
384 this.authorBox.addItem( this.mkAuthorLink(author) , author);
387 /* gather the subjects. subjects are either a string or an array of
388 [subject, broader topic]. currently, they're all just treated like
390 var arr = record.subject();
392 for( var sub in arr ) {
393 if(x++ > 5) break; /* too many subjects makes things real sluggish */
397 /* only taking first part of subject (non-topic, etc.) */
398 if( ss.constructor == Array)
401 if( ss.constructor != Array )
405 var s = normalize(ss[i]);
406 this.subjectBox.addItem( this.mkSubjectLink(s), s );
410 var series = record.series();
411 for( var s in series ) {
412 debug("Found series entry: " + series[s] );
413 var ss = normalize(series[s]);
414 this.seriesBox.addItem( this.mkSeriesLink(ss), ss );
417 /* requestBatch will only have one request in it when the current
418 record is the last record requested */
419 if( this.requestBatch.pending() < 2 )
422 debug("Finished displaying record " + record.doc_id());
425 AbstractRecordResultPage.prototype.mkAuthorLink = function(auth) {
426 var href = createAppElement("a");
427 add_css_class(href,"record_result_sidebar_link");
429 href.setAttribute("href",
430 "?target=mr_result&mr_search_type=author&page=0&mr_search_query=" +
431 encodeURIComponent(auth) +
432 "&mr_search_depth=" + this.searchDepth +
433 "&mr_search_location=" + this.searchLocation +
434 "&location=" + this.searchLocation +
435 "&format=" + this.format +
436 "&depth=" + this.searchDepth);
438 href.appendChild(createAppTextNode(auth));
439 href.title = "Author search for " + auth;
443 AbstractRecordResultPage.prototype.mkSeriesLink = function(series) {
444 var href = createAppElement("a");
445 add_css_class(href,"record_result_sidebar_link");
447 debug("Series: " + series + " : " + encodeURIComponent(series));
449 href.setAttribute("href",
450 "?target=mr_result&mr_search_type=series&page=0&mr_search_query=" +
451 encodeURIComponent(series) +
452 "&mr_search_depth=" + this.searchDepth +
453 "&mr_search_location=" + this.searchLocation +
454 "&location=" + this.searchLocation +
455 "&format=" + this.format +
456 "&depth=" + this.searchDepth);
458 href.appendChild(createAppTextNode(series));
459 href.title = "Series search for " + series;
463 AbstractRecordResultPage.prototype.mkSubjectLink = function(sub) {
464 var href = createAppElement("a");
465 add_css_class(href,"record_result_sidebar_link");
466 href.setAttribute("href",
467 "?target=mr_result&mr_search_type=subject&page=0&mr_search_query=" +
468 encodeURIComponent(sub) +
469 "&mr_search_depth=" + this.searchDepth +
470 "&mr_search_location=" + this.searchLocation +
471 "&location=" + this.searchLocation +
472 "&format=" + this.format +
473 "&depth=" + this.searchDepth);
475 href.appendChild(createAppTextNode(sub));
476 href.title = "Subject search for " + sub;
480 AbstractRecordResultPage.prototype.finalizePage = function() {
484 this.finalized = true;
487 this.subjectBox.finalize();
488 this.authorBox.finalize();
489 this.seriesBox.finalize();
491 this.sidebarBox.appendChild(this.subjectBox.getNode());
492 this.sidebarBox.appendChild(createAppElement("br"));
494 this.sidebarBox.appendChild(this.authorBox.getNode());
495 this.sidebarBox.appendChild(createAppElement("br"));
497 this.sidebarBox.appendChild(this.seriesBox.getNode());
498 this.sidebarBox.appendChild(createAppElement("br"));
500 // showMe(this.buttonsBox);
502 var ses = UserSession.instance().getSessionId();
503 var box = this.sidebarBox;
506 Survey.retrieveOpacRandom(ses,
508 sur.setSubmitCallback(
509 function() { alert("Thanks!"); return true; });
510 box.appendChild( sur.getNode() );
511 sur.setHidden(false);
515 Survey.retrieveOpacRandomGlobal(
517 sur.setSubmitCallback(
518 function() { alert("Thanks!"); return true; });
519 box.appendChild( sur.getNode() );
520 sur.setHidden(false);
526 if(this.hitCount < 1) {
527 if(this.progressBar) this.progressBar.stop();
530 /* in case we're hidden */
531 showMe(this.bigOlBox);
532 showMe(getById("hit_count_cell_2"));
537 AbstractRecordResultPage.prototype.displayCopyCounts =
538 function(copy_counts, search_id, page_id) {
540 this.progressBar.manualNext();
541 var titlerow = getById("record_result_title_row_" + page_id );
542 var authorrow = getById("record_result_author_row_" + page_id );
544 var tcell = getById("record_result_title_box_" + page_id );
546 if(!this.theadDrawn) {
547 var trow = getById("record_result_thead_row");
548 for( var i in copy_counts) {
549 var cell = trow.insertCell(trow.cells.length);
550 add_css_class(cell,"record_result_thead_header");
552 findOrgType(findOrgUnit(
553 copy_counts[i].org_unit).ou_type()).opac_label();
555 this.theadDrawn = true;
558 for( var i in copy_counts) {
559 var cell = createAppElement("td");
560 add_css_class(cell, "copy_count_cell");
561 cell.innerHTML = copy_counts[i].available + " / " + copy_counts[i].count;
562 cell.setAttribute("rowspan","3");
564 cell.title = " Availabie Copies / Total Copies";
565 titlerow.appendChild(cell);
568 if(page_id == (parseInt(this.hitsPerPage) - 1) ) {
569 if(this.progressBar) this.progressBar.stop();
570 if(this.hitCount < 1)
574 if( (page_id == ((parseInt(this.hitCount) - 1 ) - parseInt(this.searchOffset))) ||
575 (page_id == (parseInt(this.hitsPerPage) - 1) ))
576 if(this.progressBar) this.progressBar.stop();
581 AbstractRecordResultPage.prototype.noHits = function() {
582 var hcell = getById("hit_count_cell");
583 //hcell.appendChild(createAppElement("br"));
584 hcell.appendChild(createAppTextNode("0 hits were returned for you search"));
588 AbstractRecordResultPage.prototype.buildNextLinks = function() {
592 this.builtLinks = true;
598 debug("Building links");
599 if( this.searchOffset < (parseInt(this.hitCount) - this.hitsPerPage)) {
600 next = createAppElement("a");
601 add_css_class(next,"record_next_button");
602 add_css_class(next,"record_next_button_active");
603 next.href = "javascript:globalPage.next();";
605 next = createAppElement("span");
606 add_css_class(next,"record_next_button_inactive");
609 if(this.searchOffset > 0) {
610 prev = createAppElement("a");
611 add_css_class(prev,"record_next_button");
612 add_css_class(prev,"record_next_button_active");
613 prev.href = "javascript:globalPage.prev();";
615 prev = createAppElement("span");
616 add_css_class(prev,"record_next_button_inactive");
619 next.appendChild(createAppTextNode("Next"));
620 prev.appendChild(createAppTextNode("Previous"));
623 var i = this.searchOffset;
624 var max = parseInt(i) + this.hitsPerPage;
625 if( max > this.hitCount )
628 var hcell = getById("hit_count_cell");
629 var hcell2 = getById("hit_count_cell_2");
634 var ident = "Titles";
635 if(instanceOf(this, MRResultPage))
636 ident = "Title Groups";
639 createAppTextNode( "Displaying " + ident + " " +
640 ( parseInt(i) + 1 ) + " to " + max + " of " + this.hitCount));
642 hcell.appendChild(createAppTextNode(" "));
643 hcell.appendChild(createAppTextNode(" "));
644 hcell.appendChild(createAppTextNode(" "));
646 hcell.appendChild(prev);
647 var span = createAppElement("span");
648 span.appendChild(createAppTextNode(" ... "));
649 hcell.appendChild(span);
650 hcell.appendChild(next);
652 hcell2.innerHTML = hcell.innerHTML;
659 AbstractRecordResultPage.prototype.buildResourcePic = function(c, resource, parent) {
660 return buildResourcePic(c, resource, parent);
663 function buildResourcePic(c, resource, parent) {
665 var pic = createAppElement("img");
667 if(resource.indexOf("sound recording") != -1)
668 resource = "sound recording";
669 pic.setAttribute("src", "/images/" + resource + ".jpg");
670 pic.setAttribute("border", "0");
671 pic.className = "record_resource_pic";
672 pic.setAttribute("width", "20");
673 pic.setAttribute("height", "20");
674 pic.setAttribute("title", resource);
689 case "sound recording":
693 case "software, multimedia":
705 case "mixed material":
709 case "notated music":
713 case "three dimensional object":
721 c.childNodes[index].innerHTML = "";
724 parent.appendChild(pic);
725 c.childNodes[index].appendChild(parent);
727 c.childNodes[index].appendChild(pic);
731 AbstractRecordResultPage.prototype.buildRecordImage = function(pic_cell, record, page_id, title) {
733 debug("Building record image for " + page_id);
736 var isbn = record.isbn();
738 isbn = isbn.replace(/^\s+/,"");
739 var idx = isbn.indexOf(" ");
741 isbn = isbn.substring(0, idx);
747 pic_cell.setAttribute("rowspan","3");
748 pic_cell.rowSpan = 3;
750 pic_cell.noWrap = 'nowrap';
751 pic_cell.setAttribute("nowrap", "nowrap");
753 pic_cell.width = "60";
754 pic_cell.className = "record_image_cell";
758 if( this.ranks.length > 0 ) {
759 var x = (parseInt(this.page) * parseInt(this.hitsPerPage)) + parseInt(page_id);
760 var per = parseInt(this.ranks[x] / this.ranks[0] * 100.0);
762 debug("Per is " + per);
763 per = 100 - parseInt(per);
765 rankBox = createAppElement("div");
766 add_css_class(rankBox, "relevance_box");
768 var d = createAppElement("div");
769 d.setAttribute("height", per + "%");
770 d.style.height = per + "%";
772 add_css_class(d, "relevance");
773 rankBox.appendChild(d);
775 rankBox.setAttribute("title", parseInt((100 - parseInt(per))) + "% Relevant");
778 /* use amazon for now */
779 //var img_src = "http://images.amazon.com/images/P/" +isbn + ".01.MZZZZZZZ.jpg";
780 //var img_src = "http://www.thecontentserver.com/bin/cntsvr.dll?GetImage&SysID=Content&CustID=Cafe&Return=1&Type=S&Key=" + isbn ;
782 var img_src = buildISBNSrc(cleanISBN(record.isbn()));
783 var big_div = createAppElement("div");
784 add_css_class(big_div, "record_image_big hide_me");
786 var big_pic = createAppElement("img");
787 var pic = createAppElement("img");
789 big_pic.setAttribute("src", img_src);
790 big_pic.setAttribute("border", "0");
791 pic.setAttribute("src", img_src);
792 add_css_class(big_pic, "record_image");
793 add_css_class(pic, "record_image");
795 pic.setAttribute("width", "45");
796 pic.setAttribute("height", "50");
797 pic.style.width = "45";
798 pic.style.height = "50";
801 big_div.style.left = 0;
804 var anch = this.mkLink(record.doc_id(), "img", title );
805 anch.appendChild(big_pic);
806 big_div.appendChild(anch);
807 pic_cell.appendChild(big_div);
809 pic_cell.appendChild(pic);
812 pic_cell.appendChild(rankBox);
814 pic.onmouseover = function() {showMe(big_div);}
815 big_div.onmouseout = function(){hideMe(big_div);}