Simplifying.
[pazpar2-moved-to-github.git] / www / demo / search.js
1 /* $Id: search.js,v 1.10 2007-01-10 09:19:05 sondberg Exp $
2  * ---------------------------------------------------
3  * Javascript container
4  */
5
6 var xmlHttp
7 var xinitSession;
8 var xloadTargets;
9 var xsearch;
10 var xshow;
11 var xstat;
12 var xtermlist;
13 var session = false;
14 var targetsloaded = false;
15 var shown;
16 var searchtimer;
17 var showtimer;
18 var termtimer;
19 var stattimer;
20 var session_cells = Array('query', 'startrec', 'action_type');
21 var old_session = session_read();
22 var url_surveillence;
23 var recstoshow = 15;
24 var page_window = 5;  // Number of pages prior to and after the current page
25 var facet_list;
26 var cur_facet = 0;
27
28 function initialize ()
29 {
30     facet_list = get_available_facets();
31     start_session();
32     session_check();
33 }
34
35
36 function GetXmlHttpObject()
37
38     var objXMLHttp=null
39     if (window.XMLHttpRequest)
40       {
41       objXMLHttp=new XMLHttpRequest()
42       }
43     else if (window.ActiveXObject)
44       {
45       objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
46       }
47     return objXMLHttp
48
49
50 function SendXmlHttpObject(obj, url, handler)
51 {
52     obj.onreadystatechange=handler;
53     obj.open("GET", url);
54     obj.send(null);
55 }
56
57 function session_started()
58 {
59     if (xinitSession.readyState != 4)
60         return;
61     var xml = xinitSession.responseXML;
62     var sesid = xml.getElementsByTagName("session")[0].childNodes[0].nodeValue;
63     document.getElementById("status").innerHTML = "Live";
64     session = sesid;
65     setTimeout(ping_session, 50000);
66 }
67
68 function start_session()
69 {
70     xinitSession = GetXmlHttpObject();
71     var url="search.pz2?";
72     url += "command=init";
73     xinitSession.onreadystatechange=session_started;
74     xinitSession.open("GET", url);
75     xinitSession.send(null);
76 }
77
78 function ping_session()
79 {
80     if (!session)
81         return;
82     var url = "search.pz2?command=ping&session=" + session;
83     SendXmlHttpObject(xpingSession = GetXmlHttpObject(), url, session_pinged);
84 }
85
86 function session_pinged()
87 {
88     if (xpingSession.readyState != 4)
89         return;
90     var xml = xpingSession.responseXML;
91     var error = xml.getElementsByTagName("error");
92     if (error[0])
93     {
94         var msg = error[0].childNodes[0].nodeValue;
95         alert(msg);
96         location = "?";
97         return;
98     }
99     setTimeout(ping_session, 50000);
100 }
101
102 function targets_loaded()
103 {
104     if (xloadTargets.readyState != 4)
105         return;
106     var xml = xloadTargets.responseXML;
107     var error = xml.getElementsByTagName("error");
108     if (error[0])
109     {
110         var msg = error[0].childNodes[0].nodeValue;
111         alert(msg);
112         return;
113     }
114     document.getElementById("targetstatus").innerHTML = "Targets loaded";
115 }
116
117 function load_targets()
118 {
119     var fn = document.getElementById("targetfilename").value;
120     clearTimeout(termtimer);
121     clearTimeout(searchtimer);
122     clearTimeout(stattimer);
123     clearTimeout(showtimer);
124     document.getElementById("stat").innerHTML = "";
125     if (!fn)
126     {
127         alert("Please enter a target definition file name");
128         return;
129     }
130     var url="search.pz2?" +
131         "command=load" +
132         "&session=" + session +
133         "&name=" + fn;
134     document.getElementById("targetstatus").innerHTML = "Loading targets...";
135     xloadTargets = GetXmlHttpObject();
136     xloadTargets.onreadystatechange=targets_loaded;
137     xloadTargets.open("GET", url);
138     xloadTargets.send(null);
139 }
140
141
142 function update_action (new_action) {
143     document.search.action_type.value = new_action;
144 }
145
146
147 function make_pager (hits, offset, max) {
148     var html = '';
149     var off;
150
151     for (off = offset - page_window * max;
152          off < hits && off < (offset + page_window * max); 
153          off += max) {
154
155         var class = '';
156         
157         if (off < 0)
158             off = 0; 
159             
160         var p = off / max + 1;
161
162         if ((offset >= off) && (offset < (off + max)))
163             class = ' class="select"';
164
165         html += '<a href="#" ' + class +
166                 'onclick="update_offset(' + off + ')">' + p + '</a>\n';
167     }
168
169     return html;
170 }
171
172
173 function update_offset (offset) {
174     document.search.startrec.value = offset;
175     update_action('page');
176     check_search();
177     update_history();
178     return false;
179 }
180
181
182 function show_records()
183 {
184     if (xshow.readyState != 4)
185         return;
186     var i;
187     var xml = xshow.responseXML;
188     var body = document.getElementById("body");
189     var hits = xml.getElementsByTagName("hit");
190     if (!hits[0]) // We should never get here with blocking operations
191     {
192         body.innerHTML = "No records yet";
193         searchtimer = setTimeout(check_search, 250);
194     }
195     else
196     {
197
198         var total = Number(xml.getElementsByTagName('total')[0].childNodes[0].nodeValue);
199         var merged = Number(xml.getElementsByTagName('merged')[0].childNodes[0].nodeValue);
200         var start = Number(xml.getElementsByTagName('start')[0].childNodes[0].nodeValue);
201         var num = Number(xml.getElementsByTagName('num')[0].childNodes[0].nodeValue);
202         var clients = Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
203         body.innerHTML = '<div class="pages">' +
204                          make_pager(merged, start, recstoshow) +
205                          '</div>';
206                          
207         body.innerHTML += '<div class="results">Records : ' + (start + 1) +
208                           ' to ' + (start + num) + ' of ' + merged +
209                           ' (total hits: ' + total + ')</div><br/><br/>';
210
211 /*
212         if (start + num < merged)
213             body.innerHTML += ' <a href="" ' +
214                 'onclick="document.search.startrec.value=' + (start + recstoshow) +
215                 ";update_action('page')" +
216                 ';check_search(); update_history(); return false;">Next</a>';
217
218         if (start > 0)
219             body.innerHTML += ' <a href="" ' +
220                 'onclick="document.search.startrec.value=' + (start - recstoshow) +
221                 ";update_action('page')" +
222                 ';check_search(); update_history();return false;">Previous</a>';
223
224         body.innerHTML += '<br/>';
225 */
226         body.innerHTML += '<div class="records">';
227
228         for (i = 0; i < hits.length; i++)
229         {
230             var mk = hits[i].getElementsByTagName("md-title");
231             var html = '<a href="#" class="record">';
232             var field = '';
233
234             if (mk[0]) {
235                 field = mk[0].childNodes[0].nodeValue;
236             }
237
238             html += field + '</a>';
239             body.innerHTML += html;
240         }
241
242         body.innerHTML += '</div>';
243         shown++;
244         if (clients > 0)
245         {
246             if (shown < 5)
247                 searchtimer = setTimeout(check_search, 1000);
248             else
249                 searchtimer = setTimeout(check_search, 2000);
250         }
251     }
252     if (!termtimer)
253         termtimer = setTimeout(check_termlist, 500);
254 }
255
256 function check_search()
257 {
258     clearTimeout(searchtimer);
259     var url = "search.pz2?" +
260         "command=show" +
261         "&start=" + document.search.startrec.value +
262         "&num=" + recstoshow +
263         "&session=" + session +
264         "&block=1";
265     xshow = GetXmlHttpObject();
266     xshow.onreadystatechange=show_records;
267     xshow.open("GET", url);
268     xshow.send(null);
269 }
270
271
272 function refine_query (obj) {
273     var query_cell = document.getElementById('query');
274     var term = obj.innerHTML;
275     
276     term = term.replace(/[\(\)]/g, '');
277     if (cur_termlist == 'subject')
278         query_cell.value += ' and su=(' + term + ')';
279     else if (cur_termlist == 'author')
280         query_cell.value += ' and au=(' + term + ')';
281     start_search();
282 }
283
284
285
286 function show_termlist()
287 {
288     if (xtermlist.readyState != 4)
289         return;
290
291     var i;
292     var xml = xtermlist.responseXML;
293     var body = facet_list[cur_facet][1];
294     var hits = xml.getElementsByTagName("term");
295     var clients =
296         Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
297
298     cur_facet++;
299
300     if (cur_facet >= facet_list.length)
301         cur_facet = 0;
302
303     if (!hits[0])
304     {
305         termtimer = setTimeout(check_termlist, 500);
306     }
307     else
308     {
309         body.innerHTML = '';
310         
311         for (i = 0; i < hits.length; i++)
312         {
313             var namen = hits[i].getElementsByTagName("name");
314             if (namen[0])
315                 body.innerHTML += '<a href="#" onclick="refine_query(this)">' +
316                                   namen[0].childNodes[0].nodeValue +
317                                   '</a>';
318         }
319
320         if (clients > 0)
321             termtimer = setTimeout(check_termlist, 1000);
322     }
323 }
324
325 function check_termlist()
326 {
327     var facet_name = facet_list[cur_facet][0];
328     var url = "search.pz2?" +
329         "command=termlist" +
330         "&session=" + session +
331         "&name=" + facet_name;
332     xtermlist = GetXmlHttpObject();
333     xtermlist.onreadystatechange=show_termlist;
334     xtermlist.open("GET", url);
335     xtermlist.send(null);
336 }
337
338 function show_stat()
339 {
340     if (xstat.readyState != 4)
341         return;
342     var i;
343     var xml = xstat.responseXML;
344     var body = document.getElementById("stat");
345     var nodes = xml.childNodes[0].childNodes;
346     var clients =
347         Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
348     if (!nodes[0])
349     {
350         stattimer  = setTimeout(check_stat, 500);
351     }
352     else
353     {
354         body.innerHTML = "(";
355         for (i = 0; i < nodes.length; i++)
356         {
357             if (nodes[i].nodeType != 1)
358                 continue;
359             var value = nodes[i].childNodes[0].nodeValue;
360             if (value == 0)
361                 continue;
362             var name = nodes[i].nodeName;
363             body.innerHTML += ' ' + name + '=' + value;
364         }
365         body.innerHTML += ')';
366         if (clients > 0)
367             stattimer = setTimeout(check_stat, 2000);
368     }
369 }
370
371 function check_stat()
372 {
373     var url = "search.pz2?" +
374         "command=stat" +
375         "&session=" + session;
376     xstat = GetXmlHttpObject();
377     xstat.onreadystatechange=show_stat;
378     xstat.open("GET", url);
379     xstat.send(null);
380 }
381
382 function search_started()
383 {
384     if (xsearch.readyState != 4)
385         return;
386     var xml = xsearch.responseXML;
387     var error = xml.getElementsByTagName("error");
388     if (error[0])
389     {
390         var msg = error[0].childNodes[0].nodeValue;
391         alert(msg);
392         return;
393     }
394     check_search();
395     stattimer = setTimeout(check_stat, 1000);
396 }
397
398 function start_search()
399 {
400     clearTimeout(termtimer);
401     termtimer = 0;
402     clearTimeout(searchtimer);
403     searchtimer = 0;
404     clearTimeout(stattimer);
405     stattimer = 0;
406     clearTimeout(showtimer);
407     showtimer = 0;
408     if (!targets_loaded)
409     {
410         alert("Please load targets first");
411         return;
412     }
413     var query = escape(document.getElementById('query').value);
414     var url = "search.pz2?" +
415         "command=search" +
416         "&session=" + session +
417         "&query=" + query;
418     xsearch = GetXmlHttpObject();
419     xsearch.onreadystatechange=search_started;
420     xsearch.open("GET", url);
421     xsearch.send(null);
422 //    document.getElementById("termlist").innerHTML = '';
423     document.getElementById("body").innerHTML = '';
424     update_history();
425     shown = 0;
426     document.search.startrec.value = 0;
427 }
428
429
430 function session_encode ()
431 {
432     var i;
433     var session = '';
434
435     for (i = 0; i < session_cells.length; i++)
436     {
437         var name = session_cells[i];
438         var value = escape(document.getElementById(name).value);
439         session += '&' + name + '=' + value;
440     }
441
442     return session;
443 }
444
445
446 function session_restore (session)
447 {
448     var fields = session.split(/&/);
449     var i;
450
451     for (i = 1; i < fields.length; i++)
452     {
453         var pair = fields[i].split(/=/);
454         var key = pair.shift();
455         var value = pair.join('=');
456         var cell = document.getElementById(key);
457
458         cell.value = value;
459     }
460     
461 }
462
463
464 function session_read ()
465 {
466     var ses = window.location.hash.replace(/^#/, '');
467     return ses;
468 }
469
470
471 function session_store (new_value)
472 {
473     window.location.hash = '#' + new_value;
474 }
475
476
477 function update_history ()
478 {
479     var session = session_encode();
480     session_store(session);
481     old_session = session;
482 }
483
484
485 function session_check ()
486 {
487     var session = session_read();
488     var action = document.search.action_type.value;
489
490     clearInterval(url_surveillence);
491
492     if ( session != unescape(old_session) )
493     {
494         session_restore(session);
495
496         if (action == 'search') {
497             start_search();
498         } else if (action == 'page') {
499             check_search();
500         } else {
501             alert('Unregocnized action_type: ' + action);
502             return;
503         }
504     }
505     
506     url_surveillence = setInterval(session_check, 200);
507 }
508
509
510 function get_available_facets () {
511     var facet_container = document.getElementById('termlists');
512     var facet_cells = facet_container.childNodes;
513     var facets = Array();
514     var i;
515
516     for (i = 0; i < facet_cells.length; i++) {
517         var cell = facet_cells.item(i);
518
519         if (cell.className == 'facet') {
520             var facet_name = cell.id.replace(/^facet_([^_]+)_terms$/, "$1");
521             facets.push(Array(facet_name, cell));
522         }
523     }
524
525     return facets;
526 }
527
528
529 function get_facet_container (obj) {
530     return document.getElementById(obj.id + '_terms');
531 }
532
533
534 function toggle_facet (obj) {
535     var container = get_facet_container(obj);
536
537     if (obj.className == 'selected') {
538         obj.className = 'unselected';
539         container.style.display = 'inline';
540     } else {
541         obj.className = 'selected';
542         container.style.display = 'none';
543     }
544 }