3 <title>mikers experimental opensearch portal</title>
7 font-family: verdana,arial,helvetica,sans-serif;
13 text-decoration: none;
24 border: solid lightblue 1px;
29 text-decoration: none;
34 text-decoration: underline;
39 text-decoration: underline;
44 text-decoration: none;
61 border-collapse: collapse;
62 border: solid gray 1px;
66 border-collapse: collapse;
72 border-bottom: 1px dashed darkgrey;
85 function create_requestor () {
88 req = new ActiveXObject("Msxml2.XMLHTTP");
92 req = new ActiveXObject("Microsoft.XMLHTTP");
99 if (!req && typeof XMLHttpRequest!='undefined') {
100 req = new XMLHttpRequest();
104 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
111 var proxy = 'http://gapines.org/opensearch/?fetch=';
114 var search_templates = [];
115 var search_urls = {};
118 var current_startPage = 1;
119 var current_startIndex = 1;
120 var current_count = 5;
122 function opensearch ( term, reset ) {
125 current_startPage = 1;
129 document.getElementById('next_button').className = 'hide';
131 if (current_startPage == 1)
132 document.getElementById('prev_button').className = 'hide';
134 document.getElementById('prev_button').className = '';
136 var tot = document.getElementById('total');
137 while (tot.lastChild)
138 tot.removeChild(tot.lastChild);
140 var src = document.getElementById('result_sources');
141 while (src.lastChild)
142 src.removeChild(src.lastChild);
144 document.getElementById('int_res_hide').className = 'noshow';
145 document.getElementById('col_res_hide').className = 'noshow';
147 var tab = document.getElementById('int_res');
148 while (tab.lastChild)
149 tab.removeChild(tab.lastChild);
151 tab = document.getElementById('col_res');
152 while (tab.lastChild)
153 tab.removeChild(tab.lastChild);
157 var sources = new Array();
158 var selector = document.getElementsByName('source');
159 for (var i = 0; i < selector.length; i++) {
160 if (selector[i].checked) {
161 sources.push(selector[i].value);
165 search_templates = [];
166 for (var i in sources) {
167 create_search( sources[i] );
170 current_startIndex = (current_count * (current_startPage - 1)) + 1;
173 for (var i in search_templates) {
174 if (!search_templates[i])
180 var url = search_templates[i].replace(/\{searchTerms\}/,encodeURIComponent(term));
181 url = url.replace(/\{startPage\}/,current_startPage);
182 url = url.replace(/\{startIndex\}/,current_startIndex);
183 url = url.replace(/\{count\}/,current_count);
184 url = url.replace(/\{relevanceScale}/,rel_scales[i]);
185 search_urls[i] = proxy + encodeURIComponent(url);
187 src.innerHTML += '<a href="' + url + '">' + url + '</a><br>';
190 for (var i in search_urls) {
191 if (!search_templates[i])
197 document.getElementById('page_label').innerHTML = current_startPage;
200 function perform_search ( source ) {
201 var req = create_requestor();
203 req.onreadystatechange = function () {
204 if (req.readyState != 4)
207 var xml = req.responseXML;
209 var desc = getElementTextNS('','description',xml,0);
210 var xml_link = getElementTextNS('','link',xml,0);
212 var total = getElementFloatNS('openSearch','totalResults',xml,0);
213 var integratible = (getElementNS('openIll','relevance',xml,0) != null);
214 var scale = getElementFloatNS('openIll','relevanceScale',xml,0);
216 rel_scales[source] = scale;
218 var current_tot = getElementFloatNS('','span',document.getElementById('total').parentNode,0);
219 var tot = document.getElementById('total');
224 if (total > (current_startPage * current_count))
225 document.getElementById('next_button').className = '';
228 tot.innerHTML = current_tot;
230 var list = xml.getElementsByTagName('item');
231 for (var i = 0; i < list.length; i++) {
233 if ( typeof list[i] != 'object')
238 tab = document.getElementById('col_res');
239 document.getElementById('col_res_hide').className = '';
240 var col = document.getElementById(source);
242 var row = tab.rows[0];
244 row = tab.insertRow(0);
246 col = document.createElement('td');
247 col.setAttribute('id',source);
248 row.appendChild(col);
250 tab = document.createElement('table');
251 tab.setAttribute('valign','top');
252 tab.setAttribute('class','col_tab');
254 var cap = document.createElement('caption');
255 tab.appendChild(cap);
256 cap.innerHTML = desc + ' -- <a href="' + xml_link + '">XML</a>';
258 col.appendChild(tab);
260 var per = parseInt(100 / search_urls.length);
261 col.setAttribute('valign','top');
262 col.setAttribute('width', + per + '%');
265 tab = col.firstChild;
268 tab = document.getElementById('int_res');
269 document.getElementById('int_res_hide').className = '';
272 if (!tab.rows.length) {
273 add_result_row(tab, 0, list[i], source);
275 for (var j = 0; j < tab.rows.length; j++) {
276 if ( typeof tab.rows[j] != 'object')
281 rank = getElementFloatNS('openIll','relevance',list[i],0);
283 alert("error getting float relevance: " + e);
287 if ( rank < parseFloat(tab.rows[j].firstChild.firstChild.textContent) ) {
288 if ( (j + 1) == tab.rows.length) {
289 add_result_row(tab, tab.rows.length, list[i], source);
294 add_result_row(tab, j, list[i], source);
301 req.open('GET', proxy + encodeURIComponent(search_urls[source]), true);
306 // retrieve float of an XML document element, including
307 // elements using namespaces
308 function getElementFloatNS(prefix, local, parentElem, index) {
309 var result = getElementNS(prefix, local, parentElem, index);
311 // get text, accounting for possible
312 // whitespace (carriage return) text nodes
313 if (result.childNodes.length > 1) {
314 return parseFloat(result.childNodes[1].nodeValue);
316 return parseFloat(result.textContent);
323 function getElementNS(prefix, local, parentElem, index) {
325 if (prefix && isIE) {
326 // IE/Windows way of handling namespaces
327 return parentElem.getElementsByTagName(prefix + ":" + local)[index];
329 // the namespace versions of this method
330 // (getElementsByTagNameNS()) operate
331 // differently in Safari and Mozilla, but both
332 // return value with just local name, provided
333 // there aren't conflicts with non-namespace element
335 return parentElem.getElementsByTagName(local)[index];
339 // retrieve text of an XML document element, including
340 // elements using namespaces
341 function getElementTextNS(prefix, local, parentElem, index) {
342 var result = getElementNS(prefix, local, parentElem, index);
344 // get text, accounting for possible
345 // whitespace (carriage return) text nodes
346 if (result.childNodes.length > 1) {
347 return result.childNodes[1].nodeValue;
349 return result.textContent;
356 function add_result_row (tab, index, xml, source) {
357 var img = images[source];
358 var rank,title,tlink,desc;
361 rank = getElementFloatNS('openIll','relevance',xml,0);
363 alert("error getting relevance: " + e);
368 title = xml.getElementsByTagName('title')[0].textContent;
374 tlink = xml.getElementsByTagName('link')[0].textContent;
380 description = xml.getElementsByTagName('description')[0].textContent;
385 var row = tab.insertRow(index);
386 row.className = 'res_tr';
387 row.innerHTML = '<td style="padding: 4px"><div style="display: none; visibility: hidden;">' + rank +
388 '</div><span class="title_link"><a href="' + tlink + '">' + title +
389 '</a></span><br/><span class="desc_text">' + description + '</span></td>' +
390 '<td><img title="' + parseInt(rank) + '% Relevant" width="32" height="32" src="' + img + '"></td>';
393 function create_search ( s ) {
394 var req = create_requestor();
396 req.open('GET',proxy + encodeURIComponent(s),false);
400 var xml = req.responseXML;
401 search_templates[s] = xml.getElementsByTagName('Url')[0].textContent;
402 var i = xml.getElementsByTagName('Image');
404 images[s] = i[0].textContent;
406 alert('BAD XML!\n\n' + e + '\n\n' + req.responseText);
407 search_templates[s] = null;
417 <form onsubmit="opensearch(document.getElementById('term').value, true); return false;">
420 <td>Keyword Search: </td>
422 <input type="text" id="term" value="javascript"/>
423 <input type="submit" value="Go!"/>
425 <td>Hits per Source: </td>
427 <select onchange="current_count=this.options[this.selectedIndex].value;">
428 <option value="5" selected>5</option>
429 <option value="10">10</option>
430 <option value="25">25</option>
435 <td colspan=4>Sources:
436 <input name="source" type="checkbox" value="http://gapines.org/opensearch.xml" checked>GPLS Pines
437 <input name="source" type="checkbox" value="http://rsinger.library.gatech.edu/opensearch/osdd-gil.xml" checked>GIL Universal Catalog
438 <input name="source" type="checkbox" value="http://search.athenscounty.lib.oh.us/cgi-bin/koha/opensearchdescription">NPL/Koha
439 <input name="source" type="checkbox" value="http://www.webdevref.com/blog/opensearchdescription.xml">WebDefRef
445 <div>Total results: <span id="total"/></div>
446 <div>Current page: <span id="page_label"></span> --
447 <button class='hide' id='prev_button' onclick="if (this.className != 'hide') {current_startPage -= 1; opensearch(document.getElementById('term').value);}">Previous Page</button>
449 <button class='hide' id='next_button' onclick="if (this.className != 'hide') {current_startPage += 1; opensearch(document.getElementById('term').value);}">Next Page</button>
455 <td id="int_res_hide" class="noshow">
457 <caption>Merged search results</caption>
460 <table id='int_res' class="res_table"></table>
465 <td id='col_res_hide' class="noshow">
467 <caption>Unranked search results</caption>
470 <table id='col_res' class="res_table"></table>
477 <div id="result_sources"></div>