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;
67 border-bottom: 1px dashed darkgrey;
75 function create_requestor () {
78 req = new ActiveXObject("Msxml2.XMLHTTP");
82 req = new ActiveXObject("Microsoft.XMLHTTP");
89 if (!req && typeof XMLHttpRequest!='undefined') {
90 req = new XMLHttpRequest();
94 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
101 var proxy = 'http://gapines.org/opensearch/?fetch=';
104 var search_templates = [];
105 var search_urls = {};
108 var display_mode = 'col';
109 var current_startPage = 1;
110 var current_startIndex = 1;
111 var current_count = 5;
113 function opensearch ( term, reset ) {
116 current_startPage = 1;
118 document.getElementById('next_button').className = 'hide';
120 if (current_startPage == 1)
121 document.getElementById('prev_button').className = 'hide';
123 document.getElementById('prev_button').className = '';
125 var tot = document.getElementById('total');
126 while (tot.lastChild)
127 tot.removeChild(tot.lastChild);
129 var src = document.getElementById('result_sources');
130 while (src.lastChild)
131 src.removeChild(src.lastChild);
133 var tab = document.getElementById('results');
134 while (tab.lastChild)
135 tab.removeChild(tab.lastChild);
139 var sources = new Array();
140 var selector = document.getElementById('sources');
141 for (var i = 0; i < selector.options.length; i++) {
142 if (selector.options[i].selected) {
143 sources.push(selector.options[i].value);
147 search_templates = [];
148 for (var i in sources) {
149 create_search( sources[i] );
152 current_startIndex = (current_count * (current_startPage - 1)) + 1;
155 for (var i in search_templates) {
156 if (!search_templates[i])
162 var url = search_templates[i].replace(/\{searchTerms\}/,encodeURIComponent(term));
163 url = url.replace(/\{startPage\}/,current_startPage);
164 url = url.replace(/\{startIndex\}/,current_startIndex);
165 url = url.replace(/\{count\}/,current_count);
166 url = url.replace(/\{relevanceScale}/,rel_scales[i]);
167 search_urls[i] = proxy + encodeURIComponent(url);
169 src.innerHTML += '<a href="' + url + '">' + url + '</a><br>';
172 for (var i in search_urls) {
173 if (!search_templates[i])
179 document.getElementById('page_label').innerHTML = current_startPage;
182 function perform_search ( source ) {
183 var req = create_requestor();
185 req.onreadystatechange = function () {
186 if (req.readyState != 4)
189 var xml = req.responseXML;
191 var desc = getElementTextNS('','description',xml,0);
192 var xml_link = getElementTextNS('','link',xml,0);
194 var total = getElementFloatNS('openSearch','totalResults',xml,0);
195 var scale = getElementFloatNS('openIll','relevanceScale',xml,0);
197 rel_scales[source] = scale
199 var current_tot = getElementFloatNS('','span',document.getElementById('total').parentNode,0);
200 var tot = document.getElementById('total');
205 if (total > (current_startPage * current_count))
206 document.getElementById('next_button').className = '';
209 tot.innerHTML = current_tot;
211 var list = xml.getElementsByTagName('item');
212 for (var i = 0; i < list.length; i++) {
214 if ( typeof list[i] != 'object')
217 var tab = document.getElementById('results');
218 if (display_mode == 'col') {
219 var col = document.getElementById(source);
221 var row = tab.rows[0];
223 row = tab.insertRow(0);
225 col = document.createElement('td');
226 col.setAttribute('id',source);
227 row.appendChild(col);
229 tab = document.createElement('table');
230 tab.setAttribute('valign','top');
231 tab.setAttribute('class','col_tab');
233 var cap = document.createElement('caption');
234 tab.appendChild(cap);
235 cap.innerHTML = desc + ' -- <a href="' + xml_link + '">XML</a>';
237 col.appendChild(tab);
239 var per = parseInt(100 / search_urls.length);
240 col.setAttribute('valign','top');
241 col.setAttribute('width', + per + '%');
244 tab = col.firstChild;
248 if (!tab.rows.length) {
249 add_result_row(tab, 0, list[i], source);
251 for (var j = 0; j < tab.rows.length; j++) {
252 if ( typeof tab.rows[j] != 'object')
257 rank = getElementFloatNS('openIll','relevance',list[i],0);
259 alert("error getting float relevance: " + e);
263 if ( rank < parseFloat(tab.rows[j].firstChild.firstChild.textContent) ) {
264 if ( (j + 1) == tab.rows.length) {
265 add_result_row(tab, tab.rows.length, list[i], source);
270 add_result_row(tab, j, list[i], source);
277 req.open('GET', proxy + encodeURIComponent(search_urls[source]), true);
282 // retrieve float of an XML document element, including
283 // elements using namespaces
284 function getElementFloatNS(prefix, local, parentElem, index) {
286 if (prefix && isIE) {
287 // IE/Windows way of handling namespaces
288 result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
290 // the namespace versions of this method
291 // (getElementsByTagNameNS()) operate
292 // differently in Safari and Mozilla, but both
293 // return value with just local name, provided
294 // there aren't conflicts with non-namespace element
296 result = parentElem.getElementsByTagName(local)[index];
299 // get text, accounting for possible
300 // whitespace (carriage return) text nodes
301 if (result.childNodes.length > 1) {
302 return parseFloat(result.childNodes[1].nodeValue);
304 return parseFloat(result.textContent);
311 // retrieve text of an XML document element, including
312 // elements using namespaces
313 function getElementTextNS(prefix, local, parentElem, index) {
315 if (prefix && isIE) {
316 // IE/Windows way of handling namespaces
317 result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
319 // the namespace versions of this method
320 // (getElementsByTagNameNS()) operate
321 // differently in Safari and Mozilla, but both
322 // return value with just local name, provided
323 // there aren't conflicts with non-namespace element
325 result = parentElem.getElementsByTagName(local)[index];
328 // get text, accounting for possible
329 // whitespace (carriage return) text nodes
330 if (result.childNodes.length > 1) {
331 return result.childNodes[1].nodeValue;
333 return result.textContent;
340 function add_result_row (tab, index, xml, source) {
341 var img = images[source];
342 var rank,title,tlink,desc;
345 rank = getElementFloatNS('openIll','relevance',xml,0);
347 alert("error getting relevance: " + e);
352 title = xml.getElementsByTagName('title')[0].textContent;
358 tlink = xml.getElementsByTagName('link')[0].textContent;
364 description = xml.getElementsByTagName('description')[0].textContent;
369 var row = tab.insertRow(index);
370 row.className = 'res_tr';
371 row.innerHTML = '<td style="padding: 4px"><div style="display: none; visibility: hidden;">' + rank +
372 '</div><span class="title_link"><a href="' + tlink + '">' + title +
373 '</a></span><br/><span class="desc_text">' + description + '</span></td>' +
374 '<td><img title="' + parseInt(rank) + '% Relevant" width="32" height="32" src="' + img + '"></td>';
377 function create_search ( s ) {
378 var req = create_requestor();
380 req.open('GET',proxy + encodeURIComponent(s),false);
384 var xml = req.responseXML;
385 search_templates[s] = xml.getElementsByTagName('Url')[0].textContent;
386 var i = xml.getElementsByTagName('Image');
388 images[s] = i[0].textContent;
390 alert('BAD XML!\n\n' + e + '\n\n' + req.responseText);
391 search_templates[s] = null;
401 <form onsubmit="opensearch(document.getElementById('term').value, true); return false;">
404 <td>Keyword Search: </td>
405 <td><input type="text" id="term" value="javascript"/></td>
410 <select id="sources" multiple="multiple" size=5>
411 <option value="http://gapines.org/opensearch.xml" selected>GPLS Pines</option>
412 <option value="http://rsinger.library.gatech.edu/opensearch/osdd-gil.xml" selected>GIL Universal Catalog</option>
413 <option value="http://search.athenscounty.lib.oh.us/cgi-bin/koha/opensearchdescription">NPL/Koha</option>
414 <option value="http://www.webdevref.com/blog/opensearchdescription.xml">WebDefRef</option>
418 <td>Hits per Source: </td>
420 <select onchange="current_count=this.options[this.selectedIndex].value;">
421 <option value="5" selected>5</option>
422 <option value="10">10</option>
423 <option value="25">25</option>
427 <td>Display mode: </td>
429 <select onchange="display_mode=this.options[this.selectedIndex].value;">
430 <option value="int">Integrated</option>
431 <option value="col" selected>Columns</option>
432 </select> (Use "Columns" when searching unranked sources)
435 <td colspan="2"><input type="submit" value="Go!"/></td>
440 <div id="result_sources"></div>
442 <div>Current page: <span id="page_label"></span> --
443 <button class='hide' id='prev_button' onclick="if (this.className != 'hide') {current_startPage -= 1; opensearch(document.getElementById('term').value);}">Previous Page</button>
445 <button class='hide' id='next_button' onclick="if (this.className != 'hide') {current_startPage += 1; opensearch(document.getElementById('term').value);}">Next Page</button>
447 <div>Total results: <span id="total"/></div>
448 <h1>Search Results</h1>
452 <table class="res_table" id="results"></table>