]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/extras/opensearchportal.html
ui fixes
[working/Evergreen.git] / Open-ILS / src / extras / opensearchportal.html
1 <html>
2         <head>
3                 <title>mikers experimental opensearch portal</title>
4                 <style>
5
6 * {
7         font-family: verdana,arial,helvetica,sans-serif;
8         font-size: small;
9 }
10
11 #result_sources a {
12         font-size: 8px;
13         color: grey;
14         text-decoration: none;
15 }
16
17 td {
18         vertical-align: top;
19 }
20
21 .source_input {
22         border: dotted blue 1px;
23 }
24
25 caption {
26         border: solid black 1px;
27 }
28
29 .header {
30         border: solid lightblue 1px;
31         background-color: lightblue;
32 }
33
34 a {
35         color: blue;
36         text-decoration: none;
37 }
38
39 a:hover {
40         color: blue;
41         text-decoration: underline;
42 }
43
44 a:active {
45         color: red;
46         text-decoration: underline;
47 }
48
49 a:visited {
50         color: blue;
51         text-decoration: none;
52 }
53
54 .title_link {
55         font-size: medium;
56         font-weight: bold;
57 }
58
59 .desc_text {
60         font-size: small;
61 }
62
63 .hide {
64         color: lightgray;
65 }
66
67 .col_tab {
68         border-collapse: collapse;
69         border: solid gray 1px;
70 }
71
72 .res_table {
73         border-collapse: collapse;
74 }
75
76 #col_res {
77         max-width: 300px !important;
78         min-width: 200px !important;
79 }
80
81 #int_res {
82         max-width: 100% !important;
83 }
84
85 #int_res_hide {
86         max-width: 100% !important;
87         min-width: 400px !important;
88 }
89
90 .res_tr {
91         border-bottom: 1px dashed darkgrey;
92 }
93
94 .noshow {
95         display: none;
96         visibility: hidden;
97 }
98
99                 </style>
100                 <script>
101
102 var isIE = false;
103
104 function create_requestor () {
105         var req;
106         try { 
107                 req = new ActiveXObject("Msxml2.XMLHTTP");
108                 isIE = true;
109         } catch (e) {
110                 try { 
111                         req = new ActiveXObject("Microsoft.XMLHTTP");
112                         isIE = true;
113                 } catch (E) {
114                         req = false;
115                 }
116         }
117
118         if (!req && typeof XMLHttpRequest!='undefined') {
119                 req = new XMLHttpRequest();
120         }
121         
122         if(!req) {
123                 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
124                 return null;
125         }
126
127         return req;
128 }
129
130 var proxy = 'http://gapines.org/opensearch/?fetch=';
131
132 var images = [];
133 var search_templates = [];
134 var search_urls = {};
135 var rel_scales = {};
136
137 var current_startPage = 1;
138 var current_startIndex = 1;
139 var current_count = 5;
140
141 function opensearch ( term, reset ) {
142
143         if (reset) {
144                 current_startPage = 1;
145                 rel_scales = {};
146         }
147
148         document.getElementById('next_button').className = 'hide';
149
150         if (current_startPage == 1)
151                 document.getElementById('prev_button').className = 'hide';
152         else 
153                 document.getElementById('prev_button').className = '';
154
155         var tot = document.getElementById('total');
156         while (tot.lastChild)
157                         tot.removeChild(tot.lastChild);
158
159         var src = document.getElementById('result_sources');
160         while (src.lastChild)
161                         src.removeChild(src.lastChild);
162
163         document.getElementById('int_res_hide').className = 'noshow';
164         document.getElementById('col_res_hide').className = 'noshow';
165
166         var tab = document.getElementById('int_res');
167         while (tab.lastChild)
168                         tab.removeChild(tab.lastChild);
169
170         tab = document.getElementById('col_res');
171         while (tab.lastChild)
172                         tab.removeChild(tab.lastChild);
173
174         search_count = 0;
175
176         var sources = new Array();
177         var selector = document.getElementsByName('source');
178         for (var i = 0; i < selector.length; i++) {
179                 if (selector[i].checked) {
180                         sources.push(selector[i].value);
181                 }
182         }
183
184         search_templates = [];
185         for (var i in sources) {
186                 create_search( sources[i] );
187         }
188
189         current_startIndex = (current_count * (current_startPage - 1)) + 1; 
190
191         search_urls = [];
192         for (var i in search_templates) {
193                 if (!search_templates[i])
194                         continue;
195
196                 if (!rel_scales[i])
197                         rel_scales[i] = 0;
198
199                 var url = search_templates[i].replace(/\{searchTerms\}/,encodeURIComponent(term));
200                 url = url.replace(/\{startPage\}/,current_startPage);
201                 url = url.replace(/\{startIndex\}/,current_startIndex);
202                 url = url.replace(/\{count\}/,current_count);
203                 url = url.replace(/\{relevanceScale}/,rel_scales[i]);
204                 search_urls[i] = proxy + encodeURIComponent(url);
205
206                 src.innerHTML += '<a href="' + url + '">' + url + '</a><br>';
207         }
208
209         for (var i in search_urls) {
210                 if (!search_templates[i])
211                         continue;
212
213                 perform_search(i);
214         }
215
216         document.getElementById('page_label').innerHTML = current_startPage;
217 }
218
219 function perform_search ( source ) {
220         var req = create_requestor();
221
222         req.onreadystatechange = function () {
223                 if (req.readyState != 4)
224                         return;
225
226                 var xml = req.responseXML;
227
228                 var desc  = getElementTextNS('','description',xml,0);
229                 var xml_link  = getElementTextNS('','link',xml,0);
230
231                 var total  = getElementFloatNS('openSearch','totalResults',xml,0);
232                 var integratible = (getElementNS('openIll','relevance',xml,0) != null);
233                 var scale = getElementFloatNS('openIll','relevanceScale',xml,0);
234
235                 rel_scales[source]  = scale;
236                 
237                 var current_tot = getElementFloatNS('','span',document.getElementById('total').parentNode,0);
238                 var tot = document.getElementById('total');
239
240                 if (!current_tot)
241                         current_tot = 0;
242
243                 if (total > (current_startPage * current_count))
244                         document.getElementById('next_button').className = '';
245
246                 current_tot += total
247                 tot.innerHTML = current_tot;
248
249                 var list = xml.getElementsByTagName('item');
250                 for (var i = 0; i < list.length; i++) {
251
252                         if ( typeof list[i] != 'object')
253                                         continue;
254
255                         var tab;
256                         if (!integratible) {
257                                 tab = document.getElementById('col_res');
258                                 document.getElementById('col_res_hide').className = '';
259                                 var col = document.getElementById(source);
260                                 if (!col) {
261                                         var row = tab.rows[0];
262                                         if (!row)
263                                                 row = tab.insertRow(0);
264
265                                         col = document.createElement('td');
266                                         col.setAttribute('id',source);
267                                         row.appendChild(col);
268
269                                         tab = document.createElement('table');
270                                         tab.setAttribute('valign','top');
271                                         tab.setAttribute('class','col_tab');
272
273                                         var cap = document.createElement('caption');
274                                         tab.appendChild(cap);
275                                         cap.innerHTML = desc + ' -- <a href="' + xml_link + '">XML</a>';
276
277                                         col.appendChild(tab);
278
279                                         var per = parseInt(100 / (search_urls.length * 2)) - 1;
280                                         col.setAttribute('valign','top');
281                                         col.setAttribute('width', + per + '%');
282
283                                 } else {
284                                         tab = col.firstChild;
285                                 }
286                         } else {
287                                 tab = document.getElementById('int_res');
288                                 document.getElementById('int_res_hide').className = '';
289                         }
290
291                         if (!tab.rows.length) {
292                                 add_result_row(tab, 0, list[i], source);
293                         } else {
294                                 for (var j = 0; j < tab.rows.length; j++) {
295                                         if ( typeof tab.rows[j] != 'object')
296                                                 continue;
297
298                                         var rank;
299                                         try {
300                                                 rank = getElementFloatNS('openIll','relevance',list[i],0);
301                                         } catch (e) {
302                                                 alert("error getting float relevance: " + e);
303                                                 rank = 0;
304                                         }
305
306                                         if ( rank < parseFloat(tab.rows[j].firstChild.firstChild.textContent) ) {
307                                                 if ( (j + 1) == tab.rows.length) {
308                                                         add_result_row(tab, tab.rows.length, list[i], source);
309                                                         break
310                                                 }
311                                                 continue;
312                                         }
313                                         add_result_row(tab, j, list[i], source);
314                                         break;
315                                 }
316                         }
317                 }
318         };
319
320         req.open('GET', proxy + encodeURIComponent(search_urls[source]), true);
321         req.send(null);
322 }
323
324
325 // retrieve float of an XML document element, including
326 // elements using namespaces
327 function getElementFloatNS(prefix, local, parentElem, index) {
328     var result = getElementNS(prefix, local, parentElem, index);
329     if (result) {
330         // get text, accounting for possible
331         // whitespace (carriage return) text nodes 
332         if (result.childNodes.length > 1) {
333             return parseFloat(result.childNodes[1].nodeValue);
334         } else {
335             return parseFloat(result.textContent);              
336         }
337     } else {
338         return 0;
339     }
340 }
341
342 function getElementNS(prefix, local, parentElem, index) {
343     var result = "";
344     if (prefix && isIE) {
345         // IE/Windows way of handling namespaces
346         return parentElem.getElementsByTagName(prefix + ":" + local)[index];
347     } else {
348         // the namespace versions of this method 
349         // (getElementsByTagNameNS()) operate
350         // differently in Safari and Mozilla, but both
351         // return value with just local name, provided 
352         // there aren't conflicts with non-namespace element
353         // names
354         return parentElem.getElementsByTagName(local)[index];
355     }
356 }
357
358 // retrieve text of an XML document element, including
359 // elements using namespaces
360 function getElementTextNS(prefix, local, parentElem, index) {
361     var result = getElementNS(prefix, local, parentElem, index);
362     if (result) {
363         // get text, accounting for possible
364         // whitespace (carriage return) text nodes 
365         if (result.childNodes.length > 1) {
366             return result.childNodes[1].nodeValue;
367         } else {
368             return result.firstChild.nodeValue;                 
369         }
370     } else {
371         return '';
372     }
373 }
374
375 function add_result_row (tab, index, xml, source) {
376         var img = images[source];
377         var rank,title,tlink,desc;
378
379         try {
380                 rank = getElementFloatNS('openIll','relevance',xml,0);
381         } catch (e) {
382                 alert("error getting relevance: " + e);
383                 rank = '0';
384         }
385         
386         try {
387                 title = getElementTextNS('','title',xml,0);
388         } catch (e) {
389                 title = '';
390         }
391         
392         try {
393                 tlink = getElementTextNS('','link',xml,0);
394         } catch (e) {
395                 tlink = '';
396         }
397
398         try {
399                 description = getElementTextNS('','description',xml,0);
400                 if (description.length > 1024)
401                         description = description.substring(1,1024);
402         } catch (e) {
403                 description = '';
404         }
405
406         var row = tab.insertRow(index);
407         row.className = 'res_tr';
408         row.innerHTML = '<td style="padding: 4px"><div style="display: none; visibility: hidden;">' + rank +
409                                                  '</div><span class="title_link"><a href="' + tlink + '">' + title +
410                                                  '</a></span><br/><span class="desc_text">' + description + '</span></td>' +
411                                                  '<td><img title="' + parseInt(rank) + '% Relevant" width="32" height="32" src="' + img + '"></td>';
412 }
413
414 function create_search ( s ) {
415         var req = create_requestor();
416
417         req.open('GET',proxy +  encodeURIComponent(s),false);
418         req.send(null);
419
420         try {
421                 var xml = req.responseXML;
422                 search_templates[s] = xml.getElementsByTagName('Url')[0].textContent;
423                 var i =  xml.getElementsByTagName('Image');
424                 if (i.length)
425                         images[s] = i[0].textContent;
426         } catch (e) {
427                 alert('BAD XML!\n\n' + e + '\n\n' + req.responseText);
428                 search_templates[s] = null;
429                 images[s] = null;
430         }
431
432 }
433
434                 </script>
435         </head>
436         <body>
437                 <br/>
438                 <form>
439                 <table>
440                         <tr valign="top">
441                                 <td align="left">Keyword Search: 
442                                         <input type="text" id="term" value="javascript"/>
443                                         <input type="submit" value="Go!" onclick="opensearch(document.getElementById('term').value, true); return false;"/>
444                                 </td>
445                                 <td align="right">Hits per Source: 
446                                         <select onchange="current_count=this.options[this.selectedIndex].value;">
447                                                 <option value="5" selected>5</option>
448                                                 <option value="10">10</option>
449                                                 <option value="25">25</option>
450                                         </select>
451                                 </td>
452                         </tr>
453                         <tr valign="top">
454                                 <td colspan=2>Sources:  
455                                         <label class="source_input"><input name="source" type="checkbox" value="http://gapines.org/opensearch.xml" checked>GPLS Pines</label>
456                                         <label class="source_input"><input name="source" type="checkbox" value="http://rsinger.library.gatech.edu/opensearch/osdd-gil.xml" checked>GIL Universal Catalog</label>
457                                         <label class="source_input"><input name="source" type="checkbox" value="http://search.athenscounty.lib.oh.us/cgi-bin/koha/opensearchdescription">NPL/Koha</label>
458                                         <label class="source_input"><input name="source" type="checkbox" value="http://www.koders.com/search/KodersSourceCodeSearchDescription.xml">Koders Source Code</label>
459                                         <label class="source_input"><input name="source" type="checkbox" value="http://cnx.rice.edu/content/opensearchdescription">rice.edu Connexions</label>
460                                         <label class="source_input"><input name="source" type="checkbox" value="http://redlightgreen.com/ucwprod/web/opensearchDescription.xml">RedLightGreen</label>
461                                         <label class="source_input"><input name="source" type="checkbox" value="http://www.itpapers.com/itpaperssearchdescription.xml">ITPapers</label>
462                                         <!-- <input name="source" type="checkbox" value="http://www.webdevref.com/blog/opensearchdescription.xml">WebDefRef -->
463                                 </td>
464                         </tr>
465                 </table>
466                 </form>
467
468                 <div>Total results: <span id="total"/></div>
469                 <div>Current page: <span id="page_label"></span> -- 
470                         <button class='hide' id='prev_button' onclick="if (this.className != 'hide') {current_startPage -= 1; opensearch(document.getElementById('term').value);}">Previous Page</button>
471                         ...
472                         <button class='hide' id='next_button' onclick="if (this.className != 'hide') {current_startPage += 1; opensearch(document.getElementById('term').value);}">Next Page</button>
473                 </div>
474                 <hr/>
475                 <br/>
476                 <table id="results" width="100%">
477                         <tr>
478                                 <td id="int_res_hide" class="noshow" width="100%">
479                                         <table width="100%">
480                                                 <caption class="header">Merged search results</caption>
481                                                 <tr>
482                                                         <td width="100%">
483                                                                 <table id='int_res' class="res_table" width="100%"></table>
484                                                         </td>
485                                                 </tr>
486                                         </table>
487                                 </td>
488                                 <td id='col_res_hide' class="noshow">
489                                         <table>
490                                                 <caption class="header">Unranked search results</caption>
491                                                 <tr>
492                                                         <td>
493                                                                 <table id='col_res' class="res_table"></table>
494                                                         </td>
495                                                 </tr>
496                                         </table>
497                                 </td>
498                         </tr>
499                 </table>
500                 <div id="result_sources"></div>
501                 <br/>
502         </body>
503 </html>