1 /* $Id: search.js,v 1.45 2007-01-26 18:50:11 quinn Exp $
2 * ---------------------------------------------------
15 var targetsloaded = false;
21 var session_cells = Array('query', 'startrec', 'action_type');
22 var old_session = session_read();
25 var page_window = 5; // Number of pages prior to and after the current page
27 var cur_sort = "relevance";
32 function initialize ()
34 facet_list = get_available_facets();
40 function GetXmlHttpObject()
43 if (window.XMLHttpRequest)
45 objXMLHttp=new XMLHttpRequest()
47 else if (window.ActiveXObject)
49 objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
54 function SendXmlHttpObject(obj, url, handler)
56 obj.onreadystatechange=handler;
61 function session_started()
63 if (xinitSession.readyState != 4)
65 var xml = xinitSession.responseXML;
66 var sesid = xml.getElementsByTagName("session")[0].childNodes[0].nodeValue;
67 assign_text(document.getElementById("status"), 'Live');
69 setTimeout(ping_session, 50000);
72 function start_session()
74 xinitSession = GetXmlHttpObject();
75 var url="search.pz2?";
76 url += "command=init";
77 xinitSession.onreadystatechange=session_started;
78 xinitSession.open("GET", url);
79 xinitSession.send(null);
82 function ping_session()
86 var url = "search.pz2?command=ping&session=" + session;
87 SendXmlHttpObject(xpingSession = GetXmlHttpObject(), url, session_pinged);
90 function session_pinged()
92 if (xpingSession.readyState != 4)
94 var xml = xpingSession.responseXML;
95 var error = xml.getElementsByTagName("error");
99 setTimeout(ping_session, 50000);
102 function update_action (new_action) {
103 document.search.action_type.value = new_action;
107 function make_pager (hits, offset, max) {
110 var start_offset = offset - page_window * max;
111 var div_elem = document.createElement('div');
113 div_elem.className = 'pages';
115 if (start_offset < 0) {
119 for (off = start_offset;
120 off < hits && off < (start_offset + 2 * page_window * max);
123 var p = off / max + 1;
124 var page_elem = create_element('a', p);
125 var newline_node = document.createTextNode(' ');
127 if ((offset >= off) && (offset < (off + max))) {
128 page_elem.className = 'select';
131 page_elem.setAttribute('off', off);
132 page_elem.style.cursor = 'pointer';
133 page_elem.onclick = function () {
134 update_offset(this.getAttribute('off'));
137 div_elem.appendChild(page_elem);
138 div_elem.appendChild(newline_node);
145 function update_offset (offset) {
146 clearTimeout(searchtimer);
147 document.search.startrec.value = offset;
148 update_action('page');
155 function create_element (name, cdata) {
156 var elem_node = document.createElement(name);
157 elem_node.innerHTML = cdata;
163 function clear_cell (cell) {
164 while (cell.hasChildNodes())
165 cell.removeChild(cell.firstChild);
169 function append_text(cell, text) {
170 text_node = document.createTextNode(text);
171 cell.appendChild(text_node);
175 function assign_text (cell, text) {
177 append_text(cell, text);
180 function set_sort_opt(n, opt, str)
182 var txt = document.createTextNode(str);
187 var a = document.createElement('a');
189 a.setAttribute('href', "");
190 a.setAttribute('id', opt);
191 a.onclick = function() { set_sort(this.getAttribute('id')); return false; };
196 function set_sort(sort)
198 if (sort && sort != cur_sort)
205 var t = document.getElementById("sortselect");
207 t.appendChild(document.createTextNode("Sort results by: "));
208 set_sort_opt(t, 'relevance', 'Relevance');
209 t.appendChild(document.createTextNode(" or "));
210 set_sort_opt(t, 'title:1', 'Title');
213 function displayname(name)
215 if (name == 'md-author')
217 else if (name == 'md-subject')
219 else if (name == 'md-date')
221 else if (name == 'md-isbn')
223 else if (name == 'md-publisher')
225 else if (name == 'md-url')
227 else if (name == 'md-title')
229 else if (name == 'md-id')
231 else if (name == 'md-lccn')
233 else if (name == 'recid')
235 else if (name == 'location')
241 function hyperlink_field(name)
243 if (name == 'md-author')
245 else if (name == 'md-subject')
247 else if (name == 'md-url')
253 function paint_details_tr(name, dn)
256 var dname = displayname(name);
257 var ln = create_element('b', dname);
258 var tln = document.createElement('td');
262 var tr = document.createElement('tr');
271 var v2 = v1.replace(/\?.*$/, "");
272 var v3 = v2.replace(/http:\/\//, "");
276 function paint_data_elements(target, node)
278 var nodes = node.childNodes;
282 for (i = 0; i < nodes.length; i++)
284 if (nodes[i].nodeType != 1)
286 var name = nodes[i].nodeName;
287 if (name == 'recid' || name == 'md-title')
289 if (name != lastname && lastname != 'location')
293 var tr = paint_details_tr(lastname, dn);
294 target.appendChild(tr);
296 dn = document.createElement('td');
299 if (name == 'location')
301 dn = document.createElement('td');
302 dn.appendChild(paint_subrecord(nodes[i]));
303 target.appendChild(paint_details_tr('Location', dn));
306 if (!nodes[i].childNodes[0])
308 var value = nodes[i].childNodes[0].nodeValue;
309 if (dn.childNodes[0])
310 dn.appendChild(document.createTextNode('; '));
311 var hyl = hyperlink_field(name);
315 nv = create_element('a', cleanurl(value));
319 nv.target = '_blank';
324 nv.setAttribute('term', value);
325 nv.setAttribute('searchfield', hyl);
326 nv.onclick = function() { hyperlink_search(this); return false; };
329 else if (name == 'md-lccn')
331 nv = document.createElement('span');
332 nv.appendChild(document.createTextNode(value + ' '));
333 var link = create_element('a', 'Show title in LoC');
334 link.setAttribute('target', '_blank');
335 link.setAttribute('href', 'http://catalog.loc.gov/cgi-bin/Pwebrecon.cgi?DB=local&CNT=10&CMD=10+records+per+page&CMD=lccn+' + value);
336 nv.appendChild(link);
340 nv = document.createTextNode(value);
343 if (dn && lastname != 'location')
345 var tr = paint_details_tr(lastname, dn);
346 target.appendChild(tr);
350 function paint_subrecord(node)
352 var table = document.createElement('table');
353 var tbody = document.createElement('tbody');
354 var zurl = node.getAttribute('id');
355 var name = node.getAttribute('name');
359 td = create_element('td', name);
361 td = create_element('td', zurl);
362 tr = paint_details_tr('Source', td);
363 tbody.appendChild(tr);
364 paint_data_elements(tbody, node);
365 table.appendChild(tbody);
369 function paint_details(body, xml)
372 var table = document.createElement('table');
373 var tbody = document.createElement('tbody');
374 table.setAttribute('cellpadding', 2);
375 paint_data_elements(tbody, xml.childNodes[0]);
376 table.appendChild(tbody);
377 body.appendChild(table);
378 body.style.display = 'inline';
381 function show_details()
383 if (xfetchDetails.readyState != 4)
385 var xml = xfetchDetails.responseXML;
386 var error = xml.getElementsByTagName("error");
389 var msg = error[0].childNodes[0].nodeValue;
395 var idn = xml.getElementsByTagName('recid');
398 var id = idn[0].childNodes[0].nodeValue;
402 var nodes = document.getElementsByName('listrecord');
404 for (i = 0; i < nodes.length; i++)
406 var dets = nodes[i].getElementsByTagName('div');
408 dets[0].style.display = 'none';
411 var body = document.getElementById('rec_' + id);
414 paint_details(body, xml);
417 function hyperlink_search(obj)
419 var field = obj.getAttribute('searchfield');
420 var term = obj.getAttribute('term');
421 var queryfield = document.getElementById('query');
422 queryfield.value = field + '=' + term;
426 function fetch_details(id)
436 var url = "search.pz2?session=" + session +
439 SendXmlHttpObject(xfetchDetails = GetXmlHttpObject(), url, show_details);
442 function show_records()
444 if (xshow.readyState != 4)
447 var xml = xshow.responseXML;
448 var body = document.getElementById("body");
449 var hits = xml.getElementsByTagName("hit");
453 if (!hits[0]) // We should never get here with blocking operations
455 assign_text(body, 'No records yet');
456 searchtimer = setTimeout(check_search, 250);
460 var total = Number(xml.getElementsByTagName('total')[0].childNodes[0].nodeValue);
461 var merged = Number(xml.getElementsByTagName('merged')[0].childNodes[0].nodeValue);
462 var start = Number(xml.getElementsByTagName('start')[0].childNodes[0].nodeValue);
463 var num = Number(xml.getElementsByTagName('num')[0].childNodes[0].nodeValue);
464 var clients = Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
465 var pager = make_pager(merged, start,recstoshow);
466 var break_node1 = document.createElement('br');
467 var break_node2 = document.createElement('br');
468 var record_container = document.createElement('div');
469 var interval = create_element('div', 'Records : ' + (start + 1) +
470 ' to ' + (start + num) + ' of ' +
471 merged + ' (total hits: ' +
474 interval.className = 'results';
475 record_container.className = 'records';
477 body.appendChild(pager);
478 body.appendChild(interval);
479 body.appendChild(break_node1);
480 body.appendChild(break_node2);
481 body.appendChild(record_container);
483 for (i = 0; i < hits.length; i++)
485 var tn = hits[i].getElementsByTagName("md-title");
487 var an = hits[i].getElementsByTagName("md-author");
489 var cn = hits[i].getElementsByTagName("count");
491 var idn = hits[i].getElementsByTagName("recid");
493 if (tn[0] && tn[0].childNodes[0]) {
494 title = tn[0].childNodes[0].nodeValue;
498 if (an[0] && an[0].childNodes[0])
499 author = an[0].childNodes[0].nodeValue;
501 count = Number(cn[0].childNodes[0].nodeValue);
502 var id = idn[0].childNodes[0].nodeValue;
504 var record_div = document.createElement('div');
505 record_div.className = 'record';
506 record_div.setAttribute('name', 'listrecord');
508 var record_cell = create_element('a', title);
509 record_cell.setAttribute('href', '#' + id);
510 record_cell.setAttribute('id', id);
511 //record_cell.onclick = function() { fetch_details(this.getAttribute('id')); return false; }
512 record_cell.onclick = function() { fetch_details(this.getAttribute('id')); return false; };
513 record_div.appendChild(record_cell);
516 record_div.appendChild(document.createTextNode(', by '));
517 var al = create_element('a', author);
518 al.setAttribute('href', '#');
519 al.setAttribute('term', author);
520 al.setAttribute('searchfield', 'au');
521 al.onclick = function() { hyperlink_search(this); return false; };
522 record_div.appendChild(al);
525 record_div.appendChild(document.createTextNode(
526 ' (' + count + ')'));
527 var det_div = document.createElement('div');
529 paint_details(det_div, cur_rec);
531 det_div.style.display = 'none';
532 det_div.setAttribute('id', 'rec_' + id);
533 det_div.setAttribute('name', 'details');
534 record_div.appendChild(det_div);
535 record_container.appendChild(record_div);
542 searchtimer = setTimeout(check_search, 1000);
544 searchtimer = setTimeout(check_search, 2000);
548 termtimer = setTimeout(check_termlist, 500);
551 function check_search()
553 clearTimeout(searchtimer);
554 var url = "search.pz2?" +
556 "&start=" + document.search.startrec.value +
557 "&num=" + recstoshow +
558 "&session=" + session +
559 "&sort=" + cur_sort +
561 xshow = GetXmlHttpObject();
562 xshow.onreadystatechange=show_records;
563 xshow.open("GET", url);
568 function refine_query (obj) {
569 var term = obj.getAttribute('term');
570 var cur_termlist = obj.getAttribute('facet');
571 var query_cell = document.getElementById('query');
573 term = term.replace(/[\(\)]/g, '');
575 if (cur_termlist == 'subject')
576 query_cell.value += ' and su="' + term + '"';
577 else if (cur_termlist == 'author')
578 query_cell.value += ' and au="' + term + '"';
579 else if (cur_termlist == 'date')
580 query_cell.value += ' and date="' + term + '"';
585 function clear_termlists()
588 for (i = 0; i < facet_list.length; i++)
589 clear_cell(facet_list[i][1]);
592 function show_termlists()
594 if (xtermlist.readyState != 4)
598 var xml = xtermlist.responseXML;
600 Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
601 var lists = xml.getElementsByTagName("list");
603 for (i = 0; i < lists.length; i++)
605 var listname = lists[i].getAttribute('name');
606 var body = document.getElementById('facet_' + listname + '_terms');
607 if (body.style.display == 'none')
610 var terms = lists[i].getElementsByTagName('term');
612 for (t = 0; t < terms.length; t++)
614 var namen = terms[t].getElementsByTagName("name");
615 var freqn = terms[t].getElementsByTagName("frequency");
617 var term = namen[0].childNodes[0].nodeValue;
618 var freq = freqn[0].childNodes[0].nodeValue;
619 var refine_cell = create_element('a', term + ' (' + freq + ')');
620 refine_cell.setAttribute('href', '#');
621 refine_cell.setAttribute('term', term);
622 refine_cell.setAttribute('facet', listname);
623 refine_cell.onclick = function () {
627 body.appendChild(refine_cell);
631 termtimer = setTimeout(check_termlist, 1000);
634 function check_termlist()
636 var facet_names = '';
638 for (i = 0; i < facet_list.length; i++)
639 if (facet_list[i][1].style.display != 'none')
643 facet_names += facet_list[i][0];
645 var url = "search.pz2?" +
647 "&session=" + session +
648 "&name=" + facet_names +
650 SendXmlHttpObject(xtermlist = GetXmlHttpObject(), url, show_termlists);
655 if (xstat.readyState != 4)
658 var xml = xstat.responseXML;
659 var body = document.getElementById("stat");
660 var nodes = xml.childNodes[0].childNodes;
662 Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
665 stattimer = setTimeout(check_stat, 500);
669 assign_text(body, '(');
670 for (i = 0; i < nodes.length; i++)
672 if (nodes[i].nodeType != 1)
674 var value = nodes[i].childNodes[0].nodeValue;
677 var name = nodes[i].nodeName;
678 append_text(body, ' ' + name + '=' + value);
681 append_text(body, ')');
683 stattimer = setTimeout(check_stat, 2000);
687 function check_stat()
689 var url = "search.pz2?" +
691 "&session=" + session;
692 xstat = GetXmlHttpObject();
693 xstat.onreadystatechange=show_stat;
694 xstat.open("GET", url);
698 function search_started()
700 if (xsearch.readyState != 4)
702 var xml = xsearch.responseXML;
703 var error = xml.getElementsByTagName("error");
706 var msg = error[0].childNodes[0].nodeValue;
711 stattimer = setTimeout(check_stat, 1000);
714 function start_search()
716 clearTimeout(termtimer);
718 clearTimeout(searchtimer);
720 clearTimeout(stattimer);
722 clearTimeout(showtimer);
726 var query = escape(document.getElementById('query').value);
727 var url = "search.pz2?" +
729 "&session=" + session +
731 xsearch = GetXmlHttpObject();
732 xsearch.onreadystatechange=search_started;
733 xsearch.open("GET", url);
735 clear_cell(document.getElementById("body"));
738 document.search.startrec.value = 0;
741 function session_encode ()
746 for (i = 0; i < session_cells.length; i++)
748 var name = session_cells[i];
749 var value = escape(document.getElementById(name).value);
750 session += '&' + name + '=' + value;
757 function session_restore (session)
759 var fields = session.split(/&/);
762 for (i = 1; i < fields.length; i++)
764 var pair = fields[i].split(/=/);
765 var key = pair.shift();
766 var value = pair.join('=');
767 var cell = document.getElementById(key);
775 function session_read ()
777 var ses = window.location.hash.replace(/^#/, '');
782 function session_store (new_value)
784 window.location.hash = '#' + new_value;
788 function update_history ()
790 var session = session_encode();
791 session_store(session);
792 old_session = session;
796 function session_check ()
798 var session = session_read();
799 var action = document.search.action_type.value;
801 clearInterval(url_surveillence);
803 if ( session != unescape(old_session) )
805 session_restore(session);
807 if (action == 'search') {
809 } else if (action == 'page') {
812 alert('Unregocnized action_type: ' + action);
817 url_surveillence = setInterval(session_check, 200);
821 function get_available_facets () {
822 var facet_container = document.getElementById('termlists');
823 var facet_cells = facet_container.childNodes;
824 var facets = Array();
827 for (i = 0; i < facet_cells.length; i++) {
828 var cell = facet_cells.item(i);
830 if (cell.className == 'facet') {
831 var facet_name = cell.id.replace(/^facet_([^_]+)_terms$/, "$1");
832 facets.push(Array(facet_name, cell));
840 function get_facet_container (obj) {
841 return document.getElementById(obj.id + '_terms');
845 function toggle_facet (obj) {
846 var container = get_facet_container(obj);
848 if (obj.className == 'selected') {
849 obj.className = 'unselected';
850 container.style.display = 'inline';
853 obj.className = 'selected';
854 container.style.display = 'none';