]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/extras/opensearchportal.html
adding dynamic column support
[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 caption {
22         border: solid black 1px;
23 }
24
25 .header {
26         border: solid lightblue 1px;
27         background-color: lightblue;
28 }
29
30 a {
31         color: blue;
32         text-decoration: none;
33 }
34
35 a:hover {
36         color: blue;
37         text-decoration: underline;
38 }
39
40 a:active {
41         color: red;
42         text-decoration: underline;
43 }
44
45 a:visited {
46         color: blue;
47         text-decoration: none;
48 }
49
50 .title_link {
51         font-size: medium;
52         font-weight: bold;
53 }
54
55 .desc_text {
56         font-size: small;
57 }
58
59 .hide {
60         color: lightgray;
61 }
62
63 .col_tab {
64         border-collapse: collapse;
65         border: solid gray 1px;
66 }
67
68 .res_table {
69         border-collapse: collapse;
70 }
71
72 #col_res {
73         max-width: 300px !important;
74         min-width: 200px !important;
75 }
76
77 #int_res {
78         max-width: 100% !important;
79 }
80
81 #int_res_hide {
82         max-width: 100% !important;
83         min-width: 400px !important;
84 }
85
86 .res_tr {
87         border-bottom: 1px dashed darkgrey;
88 }
89
90 .noshow {
91         display: none;
92         visibility: hidden;
93 }
94
95                 </style>
96                 <script>
97
98 var isIE = false;
99
100 function create_requestor () {
101         var req;
102         try { 
103                 req = new ActiveXObject("Msxml2.XMLHTTP");
104                 isIE = true;
105         } catch (e) {
106                 try { 
107                         req = new ActiveXObject("Microsoft.XMLHTTP");
108                         isIE = true;
109                 } catch (E) {
110                         req = false;
111                 }
112         }
113
114         if (!req && typeof XMLHttpRequest!='undefined') {
115                 req = new XMLHttpRequest();
116         }
117         
118         if(!req) {
119                 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
120                 return null;
121         }
122
123         return req;
124 }
125
126 var proxy = 'http://gapines.org/opensearch/?fetch=';
127
128 var insearch=false;
129
130 var images = [];
131 var search_templates = [];
132 var search_urls = {};
133 var rel_scales = {};
134
135 var current_startPage = 1;
136 var current_startIndex = 1;
137 var current_count = 5;
138
139 function opensearch ( term, reset, single_source ) {
140
141         if (reset) {
142                 current_startPage = 1;
143                 rel_scales = {};
144         }
145
146         if (single_source) {
147
148                 create_search(single_source);
149                 var turi = search_templates[single_source].replace(/\{searchTerms\}/,encodeURIComponent(term));
150                 turi = turi.replace(/\{startPage\}/,current_startPage);
151                 turi = turi.replace(/\{startIndex\}/,current_startIndex);
152                 turi = turi.replace(/\{count\}/,current_count);
153                 turi = turi.replace(/\{relevanceScale}/,'0');
154                 search_urls[single_source] = proxy + encodeURIComponent(turi);
155
156                 rel_scales
157                 var cur_src = document.getElementById('result_sources');
158                 for (var i = 1; i < cur_src.childNodes.length; i++) {
159                         if (cur_src.childNodes[i].textContent == turi)
160                                 return;
161                 }
162                 cur_src.innerHTML += '<a name="' + single_source + '" href="' + turi + '">' + turi + '</a><br>';
163                 perform_search(single_source);
164                 return;
165         }
166
167         document.getElementById('next_button').className = 'hide';
168
169         if (current_startPage == 1)
170                 document.getElementById('prev_button').className = 'hide';
171         else 
172                 document.getElementById('prev_button').className = '';
173
174         var tot = document.getElementById('total');
175         while (tot.lastChild)
176                         tot.removeChild(tot.lastChild);
177
178         var src = document.getElementById('result_sources');
179         while (src.lastChild)
180                         src.removeChild(src.lastChild);
181
182         document.getElementById('int_res_hide').className = 'noshow';
183         document.getElementById('col_res_hide').className = 'noshow';
184
185         var tab = document.getElementById('int_res');
186         while (tab.lastChild)
187                         tab.removeChild(tab.lastChild);
188
189         tab = document.getElementById('col_res');
190         while (tab.lastChild)
191                         tab.removeChild(tab.lastChild);
192
193         search_count = 0;
194
195         var sources = new Array();
196         var selector = document.getElementsByName('source');
197         for (var i = 0; i < selector.length; i++) {
198                 if (selector[i].checked) {
199                         sources.push(selector[i].value);
200                 }
201         }
202
203         search_templates = [];
204         for (var i in sources) {
205                 create_search( sources[i] );
206         }
207
208         current_startIndex = (current_count * (current_startPage - 1)) + 1; 
209
210         search_urls = [];
211         for (var i in search_templates) {
212                 if (!search_templates[i])
213                         continue;
214
215                 if (!rel_scales[i])
216                         rel_scales[i] = 0;
217
218                 var url = search_templates[i].replace(/\{searchTerms\}/,encodeURIComponent(term));
219                 url = url.replace(/\{startPage\}/,current_startPage);
220                 url = url.replace(/\{startIndex\}/,current_startIndex);
221                 url = url.replace(/\{count\}/,current_count);
222                 url = url.replace(/\{relevanceScale}/,rel_scales[i]);
223                 search_urls[i] = proxy + encodeURIComponent(url);
224
225                 src.innerHTML += '<a name="' + i + '" href="' + url + '">' + url + '</a><br>';
226         }
227
228         for (var i in search_urls) {
229                 if (!search_templates[i])
230                         continue;
231
232                 perform_search(i);
233         }
234
235         document.getElementById('page_label').innerHTML = current_startPage;
236 }
237
238 function perform_search ( source ) {
239         var req = create_requestor();
240
241         req.onreadystatechange = function () {
242                 if (req.readyState != 4)
243                         return;
244
245                 var xml = req.responseXML;
246
247                 var desc  = getElementTextNS('','description',xml,0);
248                 var xml_link  = getElementTextNS('','link',xml,0);
249
250                 var total  = getElementFloatNS('openSearch','totalResults',xml,0);
251                 var integratible = (getElementNS('openIll','relevance',xml,0) != null);
252                 var scale = getElementFloatNS('openIll','relevanceScale',xml,0);
253
254                 rel_scales[source]  = scale;
255                 
256                 var tot = document.getElementById('total');
257                 var current_tot = parseFloat(tot.textContent);
258                 var res_type = document.getElementById('res_type');
259
260                 if (res_type.options[res_type.selectedIndex].value == 'col')
261                         integratible = 0;
262
263                 if (!current_tot)
264                         current_tot = 0;
265
266                 if (total > (current_startPage * current_count))
267                         document.getElementById('next_button').className = '';
268
269                 current_tot += total
270                 tot.innerHTML = current_tot;
271
272                 var list = xml.getElementsByTagName('item');
273                 for (var i = 0; i < list.length; i++) {
274
275                         if ( typeof list[i] != 'object')
276                                         continue;
277
278                         var tab;
279                         if (!integratible) {
280                                 tab = document.getElementById('col_res');
281                                 document.getElementById('col_res_hide').className = '';
282                                 var col = document.getElementById(source);
283                                 if (!col) {
284                                         var row = tab.rows[0];
285                                         if (!row)
286                                                 row = tab.insertRow(0);
287
288                                         col = document.createElement('td');
289                                         col.setAttribute('id',source);
290                                         col.setAttribute('name',source);
291                                         row.appendChild(col);
292
293                                         tab = document.createElement('table');
294                                         tab.setAttribute('valign','top');
295                                         tab.setAttribute('class','col_tab');
296
297                                         var cap = document.createElement('caption');
298                                         tab.appendChild(cap);
299                                         cap.innerHTML = desc + ' -- <a href="' + xml_link + '">XML</a>';
300
301                                         col.appendChild(tab);
302
303                                         var per = parseInt(100 / (search_urls.length * 2)) - 1;
304                                         col.setAttribute('valign','top');
305                                         col.setAttribute('width', + per + '%');
306
307                                 } else {
308                                         tab = col.firstChild;
309                                 }
310                         } else {
311                                 tab = document.getElementById('int_res');
312                                 document.getElementById('int_res_hide').className = '';
313                         }
314
315                         if (!tab.rows.length) {
316                                 add_result_row(tab, 0, list[i], source);
317                         } else {
318                                 for (var j = 0; j < tab.rows.length; j++) {
319                                         if ( typeof tab.rows[j] != 'object')
320                                                 continue;
321
322                                         var rank;
323                                         try {
324                                                 rank = getElementFloatNS('openIll','relevance',list[i],0);
325                                         } catch (e) {
326                                                 alert("error getting float relevance: " + e);
327                                                 rank = 0;
328                                         }
329
330                                         if ( rank < parseFloat(tab.rows[j].firstChild.firstChild.textContent) ) {
331                                                 if ( (j + 1) == tab.rows.length) {
332                                                         add_result_row(tab, tab.rows.length, list[i], source);
333                                                         break
334                                                 }
335                                                 continue;
336                                         }
337                                         add_result_row(tab, j, list[i], source);
338                                         break;
339                                 }
340                         }
341                 }
342         };
343
344         req.open('GET', proxy + encodeURIComponent(search_urls[source]), true);
345         req.send(null);
346 }
347
348
349 // retrieve float of an XML document element, including
350 // elements using namespaces
351 function getElementFloatNS(prefix, local, parentElem, index) {
352     var result = getElementNS(prefix, local, parentElem, index);
353     if (result) {
354         // get text, accounting for possible
355         // whitespace (carriage return) text nodes 
356         if (result.childNodes.length > 1) {
357             return parseFloat(result.childNodes[1].nodeValue);
358         } else {
359             return parseFloat(result.textContent);              
360         }
361     } else {
362         return 0;
363     }
364 }
365
366 function getElementNS(prefix, local, parentElem, index) {
367     var result = "";
368     if (prefix && isIE) {
369         // IE/Windows way of handling namespaces
370         return parentElem.getElementsByTagName(prefix + ":" + local)[index];
371     } else {
372         // the namespace versions of this method 
373         // (getElementsByTagNameNS()) operate
374         // differently in Safari and Mozilla, but both
375         // return value with just local name, provided 
376         // there aren't conflicts with non-namespace element
377         // names
378         return parentElem.getElementsByTagName(local)[index];
379     }
380 }
381
382 // retrieve text of an XML document element, including
383 // elements using namespaces
384 function getElementTextNS(prefix, local, parentElem, index) {
385     var result = getElementNS(prefix, local, parentElem, index);
386     if (result) {
387         // get text, accounting for possible
388         // whitespace (carriage return) text nodes 
389         if (result.childNodes.length > 1) {
390             return result.childNodes[1].nodeValue;
391         } else {
392             return result.firstChild.nodeValue;                 
393         }
394     } else {
395         return '';
396     }
397 }
398
399 function add_result_row (tab, index, xml, source) {
400         var img = images[source];
401         var rank,title,tlink,desc;
402
403         try {
404                 rank = getElementFloatNS('openIll','relevance',xml,0);
405         } catch (e) {
406                 alert("error getting relevance: " + e);
407                 rank = '0';
408         }
409         
410         try {
411                 title = getElementTextNS('','title',xml,0);
412         } catch (e) {
413                 title = '';
414         }
415         
416         try {
417                 tlink = getElementTextNS('','link',xml,0);
418         } catch (e) {
419                 tlink = '';
420         }
421
422         try {
423                 description = getElementTextNS('','description',xml,0);
424                 if (description.length > 1024)
425                         description = description.substring(1,1024);
426         } catch (e) {
427                 description = '';
428         }
429
430         var row = tab.insertRow(index);
431         row.setAttribute('name',source);
432         row.className = 'res_tr';
433         row.innerHTML = '<td style="padding: 4px"><div style="display: none; visibility: hidden;">' + rank +
434                                                  '</div><span class="title_link"><a href="' + tlink + '">' + title +
435                                                  '</a></span><br/><span class="desc_text">' + description + '</span></td>' +
436                                                  '<td><img title="' + parseInt(rank) + '% Relevant" width="32" height="32" src="' + img + '"></td>';
437 }
438
439 function create_search ( s ) {
440         var req = create_requestor();
441
442         req.open('GET',proxy +  encodeURIComponent(s),false);
443         req.send(null);
444
445         try {
446                 var xml = req.responseXML;
447                 search_templates[s] = xml.getElementsByTagName('Url')[0].textContent;
448                 var i =  xml.getElementsByTagName('Image');
449                 if (i.length)
450                         images[s] = i[0].textContent;
451                 return search_templates[s];
452         } catch (e) {
453                 alert('BAD XML!\n\n' + e + '\n\n' + req.responseText);
454                 search_templates[s] = null;
455                 images[s] = null;
456         }
457
458 }
459
460 function remove_by_name( src ) {
461         var list = document.getElementsByName(src);
462
463         var len = list.length;
464
465         while (list.length)
466                 list[0].parentNode.removeChild(list[0]);
467 }
468
469                 </script>
470         </head>
471         <body>
472                 <br/>
473                 <form>
474                 <table style="border-collapse: collapse; margin: 5px;" width="100%">
475                         <tr style="border-bottom: dotted black 1px;" valign="top">
476                                 <td align="right">Keyword Search: </td>
477                                 <td align="left">
478                                         <input type="text" id="term" value="javascript"/>
479                                         <input type="submit" value="Go!" onclick="insearch=true; opensearch(document.getElementById('term').value, true); return false;"/>
480                                 </td>
481                                 <td align="left">Hits per Source for each page: 
482                                         <select onchange="current_count=this.options[this.selectedIndex].value;">
483                                                 <option value="5" selected>5</option>
484                                                 <option value="10">10</option>
485                                                 <option value="25">25</option>
486                                         </select>
487                                 </td>
488                                 <td align="left">Display style: 
489                                         <select id="res_type">
490                                                 <option value="int" selected>Merged Results</option>
491                                                 <option value="col">Seperate Columns</option>
492                                         </select>
493                                 </td>
494                         </tr>
495                         <tr style="border-bottom: dotted black 1px;" valign="top">
496                                 <td align="right">Sources: </td>
497                                 <td colspan=2>
498                                         <table width="100%" style="border-collapse: collapse;">
499                                                 <tr>
500                                                         <td>
501                                                                 <label class="source_input">
502                                                                         <input
503                                                                                 onclick="
504                                                                                         if(insearch) {
505                                                                                                 if(this.checked) {
506                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
507                                                                                                 } else {
508                                                                                                         remove_by_name(this.value);
509                                                                                                 }
510                                                                                         }"
511                                                                                 name="source"
512                                                                                 type="checkbox"
513                                                                                 value="http://gapines.org/opensearch.xml"
514                                                                                 checked>GPLS Pines
515                                                                 </label>
516                                                         </td>
517                                                         <td>
518                                                                 <label class="source_input">
519                                                                         <input
520                                                                                 onclick="
521                                                                                         if(insearch) {
522                                                                                                 if(this.checked) {
523                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
524                                                                                                 } else {
525                                                                                                         remove_by_name(this.value);
526                                                                                                 }
527                                                                                         }"
528                                                                                 name="source"
529                                                                                 type="checkbox"
530                                                                                 value="http://rsinger.library.gatech.edu/opensearch/osdd-gil.xml"
531                                                                                 checked>GIL Universal Catalog
532                                                                 </label>
533                                                         </td>
534                                                         <td>
535                                                                 <label class="source_input">
536                                                                         <input
537                                                                                 onclick="
538                                                                                         if(insearch) {
539                                                                                                 if(this.checked) {
540                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
541                                                                                                 } else {
542                                                                                                         remove_by_name(this.value);
543                                                                                                 }
544                                                                                         }"
545                                                                                 name="source"
546                                                                                 type="checkbox"
547                                                                                 value="http://search.athenscounty.lib.oh.us/cgi-bin/koha/opensearchdescription">NPL/Koha
548                                                                 </label>
549                                                         </td>
550                                                         <td>
551                                                                 <label class="source_input">
552                                                                         <input
553                                                                                 onclick="
554                                                                                         if(insearch) {
555                                                                                                 if(this.checked) {
556                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
557                                                                                                 } else {
558                                                                                                         remove_by_name(this.value);
559                                                                                                 }
560                                                                                         }"
561                                                                                 name="source"
562                                                                                 type="checkbox"
563                                                                                 value="http://www.koders.com/search/KodersSourceCodeSearchDescription.xml">Koders Source Code
564                                                                 </label>
565                                                         </td>
566                                                         <td>
567                                                 </tr>
568                                                 <tr>
569                                                         <td>
570                                                                 <label class="source_input">
571                                                                         <input
572                                                                                 onclick="
573                                                                                         if(insearch) {
574                                                                                                 if(this.checked) {
575                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
576                                                                                                 } else {
577                                                                                                         remove_by_name(this.value);
578                                                                                                 }
579                                                                                         }"
580                                                                                 name="source"
581                                                                                 type="checkbox"
582                                                                                 value="http://cnx.rice.edu/content/opensearchdescription">rice.edu Connexions
583                                                                 </label>
584                                                         </td>
585                                                         <td>
586                                                                 <label class="source_input">
587                                                                         <input
588                                                                                 onclick="
589                                                                                         if(insearch) {
590                                                                                                 if(this.checked) {
591                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
592                                                                                                 } else {
593                                                                                                         remove_by_name(this.value);
594                                                                                                 }
595                                                                                         }"
596                                                                                 name="source"
597                                                                                 type="checkbox"
598                                                                                 value="http://redlightgreen.com/ucwprod/web/opensearchDescription.xml">RedLightGreen
599                                                                 </label>
600                                                         </td>
601                                                         <td>
602                                                                 <label class="source_input">
603                                                                         <input
604                                                                                 onclick="
605                                                                                         if(insearch) {
606                                                                                                 if(this.checked) {
607                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
608                                                                                                 } else {
609                                                                                                         remove_by_name(this.value);
610                                                                                                 }
611                                                                                         }"
612                                                                                 name="source"
613                                                                                 type="checkbox"
614                                                                                 value="http://www.itpapers.com/itpaperssearchdescription.xml">ITPapers
615                                                                 </label>
616                                                         </td>
617                                         <!-- <input name="source" type="checkbox" value="http://www.webdevref.com/blog/opensearchdescription.xml">WebDefRef -->
618                                                 </tr>
619                                         </table>
620                                 </td>
621                         </tr>
622                         <tr>
623                                 <td>Total results: </td>
624                                 <td colspan=2 id="total"></td>
625                         </tr>
626                         <tr>
627                                 <td>Current page: </td>
628                                 <td id="page_label"></td>
629                                 <td>
630                                         <button
631                                                 class='hide'
632                                                 id='prev_button'
633                                                 onclick="
634                                                         if (this.className != 'hide') {
635                                                                 current_startPage -= 1;
636                                                                 opensearch(document.getElementById('term').value);
637                                                         }
638                                                         return false;">Previous Page
639                                         </button> ...
640                                         <button
641                                                 class='hide'
642                                                 id='next_button'
643                                                 onclick="
644                                                         if (this.className != 'hide') {
645                                                                 current_startPage += 1;
646                                                                 opensearch(document.getElementById('term').value);
647                                                         }
648                                                         return false;">Next Page
649                                         </button>
650                                 </td>
651                         </tr>
652                 </table>
653                 </form>
654
655                 <hr/>
656                 <br/>
657                 <table id="results" width="100%">
658                         <tr>
659                                 <td id="int_res_hide" class="noshow" width="100%">
660                                         <table width="100%">
661                                                 <caption class="header">Merged search results</caption>
662                                                 <tr>
663                                                         <td width="100%">
664                                                                 <table id='int_res' class="res_table" width="100%"></table>
665                                                         </td>
666                                                 </tr>
667                                         </table>
668                                 </td>
669                                 <td id='col_res_hide' class="noshow">
670                                         <table>
671                                                 <caption class="header">Unranked search results</caption>
672                                                 <tr>
673                                                         <td>
674                                                                 <table id='col_res' class="res_table"></table>
675                                                         </td>
676                                                 </tr>
677                                         </table>
678                                 </td>
679                         </tr>
680                 </table>
681                 <div id="result_sources"></div>
682                 <br/>
683         </body>
684 </html>