3 <title>mikers experimental opensearch portal</title>
7 font-family: verdana,arial,helvetica,sans-serif;
13 text-decoration: none;
21 border: solid lightblue 1px;
26 text-decoration: none;
31 text-decoration: underline;
36 text-decoration: underline;
41 text-decoration: none;
58 border-collapse: collapse;
59 border: solid gray 1px;
63 border-collapse: collapse;
68 border-bottom: 1px dashed darkgrey;
76 function create_requestor () {
79 req = new ActiveXObject("Msxml2.XMLHTTP");
83 req = new ActiveXObject("Microsoft.XMLHTTP");
90 if (!req && typeof XMLHttpRequest!='undefined') {
91 req = new XMLHttpRequest();
95 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
102 var proxy = 'http://gapines.org/opensearch/?fetch=';
105 var search_templates = [];
106 var search_urls = {};
109 var display_mode = 'col';
110 var current_startPage = 1;
111 var current_startIndex = 1;
112 var current_count = 5;
114 function opensearch ( term, reset ) {
117 current_startPage = 1;
121 document.getElementById('next_button').className = 'hide';
123 if (current_startPage == 1)
124 document.getElementById('prev_button').className = 'hide';
126 document.getElementById('prev_button').className = '';
128 var tot = document.getElementById('total');
129 while (tot.lastChild)
130 tot.removeChild(tot.lastChild);
132 var src = document.getElementById('result_sources');
133 while (src.lastChild)
134 src.removeChild(src.lastChild);
136 var tab = document.getElementById('results');
137 while (tab.lastChild)
138 tab.removeChild(tab.lastChild);
142 var sources = new Array();
143 var selector = document.getElementById('sources');
144 for (var i = 0; i < selector.options.length; i++) {
145 if (selector.options[i].selected) {
146 sources.push(selector.options[i].value);
150 search_templates = [];
151 for (var i in sources) {
152 create_search( sources[i] );
155 current_startIndex = (current_count * (current_startPage - 1)) + 1;
158 for (var i in search_templates) {
159 if (!search_templates[i])
165 var url = search_templates[i].replace(/\{searchTerms\}/,encodeURIComponent(term));
166 url = url.replace(/\{startPage\}/,current_startPage);
167 url = url.replace(/\{startIndex\}/,current_startIndex);
168 url = url.replace(/\{count\}/,current_count);
169 url = url.replace(/\{relevanceScale}/,rel_scales[i]);
170 search_urls[i] = proxy + encodeURIComponent(url);
172 src.innerHTML += '<a href="' + url + '">' + url + '</a><br>';
175 for (var i in search_urls) {
176 if (!search_templates[i])
182 document.getElementById('page_label').innerHTML = current_startPage;
185 function perform_search ( source ) {
186 var req = create_requestor();
188 req.onreadystatechange = function () {
189 if (req.readyState != 4)
192 var xml = req.responseXML;
194 var desc = getElementTextNS('','description',xml,0);
195 var xml_link = getElementTextNS('','link',xml,0);
197 var total = getElementFloatNS('openSearch','totalResults',xml,0);
198 var scale = getElementFloatNS('openIll','relevanceScale',xml,0);
200 rel_scales[source] = scale
202 var current_tot = getElementFloatNS('','span',document.getElementById('total').parentNode,0);
203 var tot = document.getElementById('total');
208 if (total > (current_startPage * current_count))
209 document.getElementById('next_button').className = '';
212 tot.innerHTML = current_tot;
214 var list = xml.getElementsByTagName('item');
215 for (var i = 0; i < list.length; i++) {
217 if ( typeof list[i] != 'object')
220 var tab = document.getElementById('results');
221 if (display_mode == 'col') {
222 var col = document.getElementById(source);
224 var row = tab.rows[0];
226 row = tab.insertRow(0);
228 col = document.createElement('td');
229 col.setAttribute('id',source);
230 row.appendChild(col);
232 tab = document.createElement('table');
233 tab.setAttribute('valign','top');
234 tab.setAttribute('class','col_tab');
236 var cap = document.createElement('caption');
237 tab.appendChild(cap);
238 cap.innerHTML = desc + ' -- <a href="' + xml_link + '">XML</a>';
240 col.appendChild(tab);
242 var per = parseInt(100 / search_urls.length);
243 col.setAttribute('valign','top');
244 col.setAttribute('width', + per + '%');
247 tab = col.firstChild;
251 if (!tab.rows.length) {
252 add_result_row(tab, 0, list[i], source);
254 for (var j = 0; j < tab.rows.length; j++) {
255 if ( typeof tab.rows[j] != 'object')
260 rank = getElementFloatNS('openIll','relevance',list[i],0);
262 alert("error getting float relevance: " + e);
266 if ( rank < parseFloat(tab.rows[j].firstChild.firstChild.textContent) ) {
267 if ( (j + 1) == tab.rows.length) {
268 add_result_row(tab, tab.rows.length, list[i], source);
273 add_result_row(tab, j, list[i], source);
280 req.open('GET', proxy + encodeURIComponent(search_urls[source]), true);
285 // retrieve float of an XML document element, including
286 // elements using namespaces
287 function getElementFloatNS(prefix, local, parentElem, index) {
289 if (prefix && isIE) {
290 // IE/Windows way of handling namespaces
291 result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
293 // the namespace versions of this method
294 // (getElementsByTagNameNS()) operate
295 // differently in Safari and Mozilla, but both
296 // return value with just local name, provided
297 // there aren't conflicts with non-namespace element
299 result = parentElem.getElementsByTagName(local)[index];
302 // get text, accounting for possible
303 // whitespace (carriage return) text nodes
304 if (result.childNodes.length > 1) {
305 return parseFloat(result.childNodes[1].nodeValue);
307 return parseFloat(result.textContent);
314 // retrieve text of an XML document element, including
315 // elements using namespaces
316 function getElementTextNS(prefix, local, parentElem, index) {
318 if (prefix && isIE) {
319 // IE/Windows way of handling namespaces
320 result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
322 // the namespace versions of this method
323 // (getElementsByTagNameNS()) operate
324 // differently in Safari and Mozilla, but both
325 // return value with just local name, provided
326 // there aren't conflicts with non-namespace element
328 result = parentElem.getElementsByTagName(local)[index];
331 // get text, accounting for possible
332 // whitespace (carriage return) text nodes
333 if (result.childNodes.length > 1) {
334 return result.childNodes[1].nodeValue;
336 return result.textContent;
343 function add_result_row (tab, index, xml, source) {
344 var img = images[source];
345 var rank,title,tlink,desc;
348 rank = getElementFloatNS('openIll','relevance',xml,0);
350 alert("error getting relevance: " + e);
355 title = xml.getElementsByTagName('title')[0].textContent;
361 tlink = xml.getElementsByTagName('link')[0].textContent;
367 description = xml.getElementsByTagName('description')[0].textContent;
372 var row = tab.insertRow(index);
373 row.className = 'res_tr';
374 row.innerHTML = '<td style="padding: 4px"><div style="display: none; visibility: hidden;">' + rank +
375 '</div><span class="title_link"><a href="' + tlink + '">' + title +
376 '</a></span><br/><span class="desc_text">' + description + '</span></td>' +
377 '<td><img title="' + parseInt(rank) + '% Relevant" width="32" height="32" src="' + img + '"></td>';
380 function create_search ( s ) {
381 var req = create_requestor();
383 req.open('GET',proxy + encodeURIComponent(s),false);
387 var xml = req.responseXML;
388 search_templates[s] = xml.getElementsByTagName('Url')[0].textContent;
389 var i = xml.getElementsByTagName('Image');
391 images[s] = i[0].textContent;
393 alert('BAD XML!\n\n' + e + '\n\n' + req.responseText);
394 search_templates[s] = null;
404 <form onsubmit="opensearch(document.getElementById('term').value, true); return false;">
407 <td>Keyword Search: </td>
408 <td><input type="text" id="term" value="javascript"/></td>
413 <select id="sources" multiple="multiple" size=5>
414 <option value="http://gapines.org/opensearch.xml" selected>GPLS Pines</option>
415 <option value="http://rsinger.library.gatech.edu/opensearch/osdd-gil.xml" selected>GIL Universal Catalog</option>
416 <option value="http://search.athenscounty.lib.oh.us/cgi-bin/koha/opensearchdescription">NPL/Koha</option>
417 <option value="http://www.webdevref.com/blog/opensearchdescription.xml">WebDefRef</option>
421 <td>Hits per Source: </td>
423 <select onchange="current_count=this.options[this.selectedIndex].value;">
424 <option value="5" selected>5</option>
425 <option value="10">10</option>
426 <option value="25">25</option>
430 <td>Display mode: </td>
432 <select onchange="display_mode=this.options[this.selectedIndex].value;">
433 <option value="int">Integrated</option>
434 <option value="col" selected>Columns</option>
435 </select> (Use "Columns" when searching unranked sources)
438 <td colspan="2"><input type="submit" value="Go!"/></td>
443 <div id="result_sources"></div>
445 <div>Current page: <span id="page_label"></span> --
446 <button class='hide' id='prev_button' onclick="if (this.className != 'hide') {current_startPage -= 1; opensearch(document.getElementById('term').value);}">Previous Page</button>
448 <button class='hide' id='next_button' onclick="if (this.className != 'hide') {current_startPage += 1; opensearch(document.getElementById('term').value);}">Next Page</button>
450 <div>Total results: <span id="total"/></div>
451 <h1>Search Results</h1>
455 <table class="res_table" id="results"></table>