Adds per-target medium type to CF stylesheet
[pazpar2-moved-to-github.git] / www / demo / search.js
1 /* $Id: search.js,v 1.53 2007-04-11 02:11:29 quinn 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 xfetchDetails;
14 var session = false;
15 var targetsloaded = false;
16 var shown;
17 var searchtimer;
18 var showtimer;
19 var termtimer;
20 var stattimer;
21 var session_cells = Array('query', 'startrec', 'action_type');
22 var old_session = session_read();
23 var url_surveillence;
24 var recstoshow = 20;
25 var page_window = 5;  // Number of pages prior to and after the current page
26 var facet_list;
27 var cur_sort = "relevance";
28 var searched = 0;
29 var cur_id = -1;
30 var cur_rec = 0;
31 var filter = '';
32
33 function initialize ()
34 {
35     facet_list = get_available_facets();
36     start_session();
37     session_check();
38     set_sort();
39 }
40
41 function GetXmlHttpObject()
42
43     var objXMLHttp=null
44     if (window.XMLHttpRequest)
45       {
46       objXMLHttp=new XMLHttpRequest()
47       }
48     else if (window.ActiveXObject)
49       {
50       objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
51       }
52     return objXMLHttp
53
54
55 function SendXmlHttpObject(obj, url, handler)
56 {
57     obj.onreadystatechange=handler;
58     obj.open("GET", url);
59     obj.send(null);
60 }
61
62 function session_started()
63 {
64     if (xinitSession.readyState != 4)
65         return;
66     var xml = xinitSession.responseXML;
67     var sesid = xml.getElementsByTagName("session")[0].childNodes[0].nodeValue;
68     assign_text(document.getElementById("status"), 'Live');
69     session = sesid;
70     setTimeout(ping_session, 50000);
71 }
72
73 function start_session()
74 {
75     xinitSession = GetXmlHttpObject();
76     var url="search.pz2?";
77     url += "command=init";
78     xinitSession.onreadystatechange=session_started;
79     xinitSession.open("GET", url);
80     xinitSession.send(null);
81 }
82
83 function ping_session()
84 {
85     if (!session)
86         return;
87     var url = "search.pz2?command=ping&session=" + session;
88     SendXmlHttpObject(xpingSession = GetXmlHttpObject(), url, session_pinged);
89 }
90
91 function session_pinged()
92 {
93     if (xpingSession.readyState != 4)
94         return;
95     var xml = xpingSession.responseXML;
96     var error = xml.getElementsByTagName("error");
97     if (error[0])
98         location = "?";
99     else
100         setTimeout(ping_session, 50000);
101 }
102
103 function update_action (new_action) {
104     document.search.action_type.value = new_action;
105 }
106
107
108 function make_pager (hits, offset, max) {
109     var html = '';
110     var off;
111     var start_offset = offset - page_window * max;
112     var div_elem = document.createElement('div');
113     
114     div_elem.className = 'pages';
115
116     if (start_offset < 0) {
117         start_offset = 0;
118     }
119
120     for (off = start_offset;
121          off < hits && off < (start_offset + 2 * page_window * max); 
122          off += max) {
123         
124         var p = off / max + 1;
125         var page_elem = create_element('a', p);
126         var newline_node = document.createTextNode(' ');
127
128         if ((offset >= off) && (offset < (off + max))) {
129             page_elem.className = 'select';
130         }
131
132         page_elem.setAttribute('off', off);
133         page_elem.style.cursor = 'pointer';
134         page_elem.onclick = function () {
135             update_offset(this.getAttribute('off'));
136         };
137
138         div_elem.appendChild(page_elem);
139         div_elem.appendChild(newline_node);
140     }
141
142     return div_elem;
143 }
144
145
146 function update_offset (offset) {
147     clearTimeout(searchtimer);
148     document.search.startrec.value = offset;
149     update_action('page');
150     check_search();
151     update_history();
152     return false;
153 }
154
155
156 function create_element (name, cdata) {
157     var elem_node = document.createElement(name);
158     elem_node.innerHTML = cdata;
159
160     return elem_node;
161 }
162
163
164 function clear_cell (cell) {
165     while (cell.hasChildNodes())
166         cell.removeChild(cell.firstChild);
167 }
168
169
170 function append_text(cell, text) {
171     text_node = document.createTextNode(text);
172     cell.appendChild(text_node);
173 }
174
175
176 function assign_text (cell, text) {
177     clear_cell(cell);
178     append_text(cell, text);
179 }
180
181 function set_sort_opt(n, opt, str)
182 {
183     var txt = document.createTextNode(str);
184     if (opt == cur_sort)
185         n.appendChild(txt);
186     else
187     {
188         var a = document.createElement('a');
189         a.appendChild(txt);
190         a.setAttribute('href', "");
191         a.setAttribute('id', opt);
192         a.onclick = function() { set_sort(this.getAttribute('id')); return false; };
193         n.appendChild(a);
194     }
195 }
196
197 function set_sort(sort)
198 {
199     if (sort && sort != cur_sort)
200     {
201         cur_sort = sort;
202         if (searched)
203             check_search();
204     }
205
206     var t = document.getElementById("sortselect");
207     clear_cell(t);
208     t.appendChild(document.createTextNode("Sort results by: "));
209     set_sort_opt(t, 'relevance', 'Relevance');
210     t.appendChild(document.createTextNode(" or "));
211     set_sort_opt(t, 'title:1', 'Title');
212 }
213
214 function displayname(name)
215 {
216     if (name == 'md-author')
217         return 'Author';
218     else if (name == 'md-subject')
219         return 'Subject';
220     else if (name == 'md-date')
221         return 'Date';
222     else if (name == 'md-isbn')
223         return 'ISBN';
224     else if (name == 'md-publisher')
225         return 'Publisher';
226     else if (name == 'md-url')
227         return 'URL';
228     else if (name == 'md-title')
229         return '@';
230     else if (name == 'md-id')
231         return 'Local ID';
232     else if (name == 'md-description')
233         return 'Description';
234     else if (name == 'md-lccn')
235         return 'LCCN';
236     else if (name == 'recid')
237         return '@';
238     else if (name == 'location')
239         return '@';
240     else
241         return name;
242 }
243
244 function hyperlink_field(name)
245 {
246     if (name == 'md-author')
247         return 'au';
248     else if (name == 'md-subject')
249         return 'su';
250     else if (name == 'md-url')
251         return 'URL';
252     else
253         return 0;
254 }
255
256 function  paint_details_tr(name, dn)
257 {
258     //emit a table row
259     var dname = displayname(name);
260     var ln = create_element('b', dname);
261     var tln = document.createElement('td');
262     tln.width = '90';
263     tln.vAlign = 'top';
264     tln.appendChild(ln);
265     var tr = document.createElement('tr');
266     tr.appendChild(tln);
267     tr.appendChild(dn);
268     return tr;
269 }
270
271 function cleanurl(v)
272 {
273     var v1 = v;
274     var v2 = v1.replace(/\?.*$/, "");
275     var v3 = v2.replace(/http:\/\//, "");
276     return v3;
277 }
278
279 function paint_data_elements(target, node)
280 {
281     var nodes = node.childNodes;
282     var dn = 0;
283     var lastname = '';
284     var i;
285     for (i = 0; i < nodes.length; i++)
286     {
287         if (nodes[i].nodeType != 1)
288             continue;
289         var name = nodes[i].nodeName;
290         if (name == 'recid' || name == 'md-title')
291             continue;
292         if (name != lastname && lastname != 'location') 
293         {
294             if (dn)
295             {
296                 var tr = paint_details_tr(lastname, dn);
297                 target.appendChild(tr);
298             }
299             dn = document.createElement('td');
300             lastname = name;
301         }
302         if (name == 'location')
303         {
304             dn = document.createElement('td');
305             dn.appendChild(paint_subrecord(nodes[i]));
306             target.appendChild(paint_details_tr('Location', dn)); 
307             continue;
308         }
309         if (!nodes[i].childNodes[0])
310                 continue;
311         var value = nodes[i].childNodes[0].nodeValue;
312         if (dn.childNodes[0])
313             dn.appendChild(document.createTextNode('; '));
314         var hyl = hyperlink_field(name);
315         var nv;
316         if (hyl)
317         {
318             nv = create_element('a', cleanurl(value));
319             if (hyl == 'URL')
320             {
321                 nv.href = value;
322                 nv.target = '_blank';
323             }
324             else
325             {
326                 nv.href = '#';
327                 nv.setAttribute('term', value);
328                 nv.setAttribute('searchfield', hyl);
329                 nv.onclick = function() { hyperlink_search(this); return false; };
330             }
331         }
332         else if (name == 'md-lccn')
333         {
334             nv = document.createElement('span');
335             nv.appendChild(document.createTextNode(value + ' '));
336             var link = create_element('a', 'Show title in LoC');
337                 link.setAttribute('target', '_blank');
338                 link.setAttribute('href', 'http://catalog.loc.gov/cgi-bin/Pwebrecon.cgi?DB=local&CNT=10&CMD=10+records+per+page&CMD=lccn+' + value);
339             nv.appendChild(link);
340
341         }
342         else if (name == 'md-isbn')
343         {
344             nv = document.createElement('span');
345             nv.appendChild(document.createTextNode(value + ' '));
346             var link = create_element('a', 'search OpenWorldCat');
347                 link.setAttribute('target', '_blank');
348                 link.setAttribute('href', 'http://www.worldcat.org/search?q=isbn%3A' + value);
349             nv.appendChild(link);
350         }
351         else
352             nv = document.createTextNode(value);
353         dn.appendChild(nv);
354     }
355     if (dn && lastname != 'location')
356     {
357         var tr = paint_details_tr(lastname, dn);
358         target.appendChild(tr);
359     }
360 }
361
362 function paint_subrecord(node)
363 {
364     var table = document.createElement('table');
365     var tbody = document.createElement('tbody');
366     var zurl = node.getAttribute('id');
367     var name = node.getAttribute('name');
368     var tr;
369     var td;
370     if (name)
371         td = create_element('td', name);
372     else
373         td = create_element('td', zurl);
374     tr = paint_details_tr('Source', td);
375     tbody.appendChild(tr);
376     paint_data_elements(tbody, node);
377     table.appendChild(tbody);
378     return table;
379 }
380
381 function paint_details(body, xml)
382 {
383     clear_cell(body);
384     var table = document.createElement('table');
385     var tbody = document.createElement('tbody');
386     table.setAttribute('cellpadding', 2);
387     paint_data_elements(tbody, xml.childNodes[0]);
388     table.appendChild(tbody);
389     body.appendChild(table);
390     body.style.display = 'inline';
391 }
392
393 function show_details()
394 {
395     if (xfetchDetails.readyState != 4)
396         return;
397     var xml = xfetchDetails.responseXML;
398     var error = xml.getElementsByTagName("error");
399     if (error[0])
400     {
401         var msg = error[0].childNodes[0].nodeValue;
402         alert(msg);
403         location = "?";
404         return;
405     }
406
407     var idn = xml.getElementsByTagName('recid');
408     if (!idn[0])
409         return;
410     var id = idn[0].childNodes[0].nodeValue;
411     cur_id = id;
412     cur_rec = xml;
413
414     var nodes = document.getElementsByName('listrecord');
415     var i;
416     for (i = 0; i < nodes.length; i++)
417     {
418         var dets = nodes[i].getElementsByTagName('div');
419         if (dets[0])
420             dets[0].style.display = 'none';
421     }
422
423     var body = document.getElementById('rec_' + id);
424     if (!body)
425         return;
426     paint_details(body, xml);
427 }
428
429 function hyperlink_search(obj)
430 {
431     var field = obj.getAttribute('searchfield');
432     var term = obj.getAttribute('term');
433     var queryfield  = document.getElementById('query');
434     queryfield.value = field + '="' + term + '"';
435     start_search();
436 }
437
438 function fetch_details(id)
439 {
440     cur_id = -1;
441     if (id == cur_id)
442     {
443         cur_id = -1;
444         return;
445     }
446     if (!session)
447         return;
448     var url = "search.pz2?session=" + session +
449         "&command=record" +
450         "&id=" + id;
451     SendXmlHttpObject(xfetchDetails = GetXmlHttpObject(), url, show_details);
452 }
453
454 function show_records()
455 {
456     if (xshow.readyState != 4)
457         return;
458     var i;
459     var xml = xshow.responseXML;
460     var body = document.getElementById("body");
461     var hits = xml.getElementsByTagName("hit");
462
463     clear_cell(body);
464
465     if (!hits[0]) // We should never get here with blocking operations
466     {
467         assign_text(body, 'No records yet');
468         searchtimer = setTimeout(check_search, 250);
469     }
470     else
471     {
472         var total = Number(xml.getElementsByTagName('total')[0].childNodes[0].nodeValue);
473         var merged = Number(xml.getElementsByTagName('merged')[0].childNodes[0].nodeValue);
474         var start = Number(xml.getElementsByTagName('start')[0].childNodes[0].nodeValue);
475         var num = Number(xml.getElementsByTagName('num')[0].childNodes[0].nodeValue);
476         var clients = Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
477         var pager = make_pager(merged, start,recstoshow);
478         var break_node1 = document.createElement('br');
479         var break_node2 = document.createElement('br');
480         var record_container = document.createElement('div');
481         var interval = create_element('div', 'Records : ' + (start + 1) +
482                                              ' to ' + (start + num) + ' of ' +
483                                              merged + ' (total hits: ' +
484                                              total + ')');
485         searched = 1;
486         interval.className = 'results';
487         record_container.className = 'records';
488
489         body.appendChild(pager);
490         body.appendChild(interval);
491         body.appendChild(break_node1);
492         body.appendChild(break_node2);
493         body.appendChild(record_container);
494
495         for (i = 0; i < hits.length; i++)
496         {
497             var tn = hits[i].getElementsByTagName("md-title");
498             var title = '';
499             var an = hits[i].getElementsByTagName("md-author");
500             var author = '';
501             var cn = hits[i].getElementsByTagName("count");
502             var count = 1;
503             var idn = hits[i].getElementsByTagName("recid");
504
505             if (tn[0] && tn[0].childNodes[0]) {
506                 title = tn[0].childNodes[0].nodeValue;
507             } else {
508                 title = 'N/A';
509             }
510             if (an[0] && an[0].childNodes[0])
511                     author = an[0].childNodes[0].nodeValue;
512             if (cn[0])
513                 count = Number(cn[0].childNodes[0].nodeValue);
514             var id = idn[0].childNodes[0].nodeValue;
515             
516             var record_div = document.createElement('div');
517             record_div.className = 'record';
518             record_div.setAttribute('name', 'listrecord');
519
520             var record_cell = create_element('a', title);
521             record_cell.setAttribute('href', '#' + id);
522             record_cell.setAttribute('id', id);
523             //record_cell.onclick = function() { fetch_details(this.getAttribute('id')); return false; }
524             record_cell.onclick = function() { fetch_details(this.getAttribute('id')); return false; };
525             record_div.appendChild(record_cell);
526             if (author)
527             {
528                 record_div.appendChild(document.createTextNode(' by '));
529                 var al = create_element('a', author);
530                 al.setAttribute('href', '#');
531                 al.setAttribute('term', author);
532                 al.setAttribute('searchfield', 'au');
533                 al.onclick = function() { hyperlink_search(this); return false; };
534                 record_div.appendChild(al);
535             }
536             if (count > 1)
537                 record_div.appendChild(document.createTextNode(
538                         ' (' + count + ')'));
539             var det_div = document.createElement('div');
540             if (id == cur_id)
541                 paint_details(det_div, cur_rec);
542             else
543                 det_div.style.display = 'none';
544             det_div.setAttribute('id', 'rec_' + id);
545             det_div.setAttribute('name', 'details');
546             record_div.appendChild(det_div);
547             record_container.appendChild(record_div);
548         }
549
550         shown++;
551         if (clients > 0)
552         {
553             if (shown < 5)
554                 searchtimer = setTimeout(check_search, 1000);
555             else
556                 searchtimer = setTimeout(check_search, 2000);
557         }
558     }
559     if (!termtimer)
560         termtimer = setTimeout(check_termlist, 500);
561 }
562
563 function check_search()
564 {
565     clearTimeout(searchtimer);
566     var url = "search.pz2?" +
567         "command=show" +
568         "&start=" + document.search.startrec.value +
569         "&num=" + recstoshow +
570         "&session=" + session +
571         "&sort=" + cur_sort +
572         "&block=1";
573     xshow = GetXmlHttpObject();
574     xshow.onreadystatechange=show_records;
575     xshow.open("GET", url);
576     xshow.send(null);
577 }
578
579
580 function refine_query (obj) {
581     var term = obj.getAttribute('term');
582     var cur_termlist = obj.getAttribute('facet');
583     var query_cell = document.getElementById('query');
584     var id = obj.getAttribute('target_id');
585     
586     term = term.replace(/[\(\)]/g, '');
587     
588     if (cur_termlist == 'subject')
589         query_cell.value += ' and su="' + term + '"';
590     else if (cur_termlist == 'author')
591         query_cell.value += ' and au="' + term + '"';
592     else if (cur_termlist == 'date')
593         query_cell.value += ' and date="' + term + '"';
594     else if (cur_termlist == 'xtargets')
595         filter ='pz:id=' +  id;
596
597     start_search();
598 }
599
600 function clear_termlists()
601 {
602     var i;
603     for (i = 0; i < facet_list.length; i++)
604         clear_cell(facet_list[i][1]);
605 }
606
607 function show_termlists()
608 {
609     if (xtermlist.readyState != 4)
610         return;
611
612     var i;
613     var xml = xtermlist.responseXML;
614     var clients =
615         Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
616     var lists = xml.getElementsByTagName("list");
617
618     for (i = 0; i < lists.length; i++)
619     {
620         var listname = lists[i].getAttribute('name');
621         var body = document.getElementById('facet_' + listname + '_terms');
622         if (body.style.display == 'none')
623             continue;
624         clear_cell(body);
625         var terms = lists[i].getElementsByTagName('term');
626         var t;
627         for (t = 0; t < terms.length; t++)
628         {
629             var namen = terms[t].getElementsByTagName("name");
630             var freqn = terms[t].getElementsByTagName("frequency");
631             var idn = terms[t].getElementsByTagName("id");
632             if (namen[0])
633             {
634                 var term = namen[0].childNodes[0].nodeValue;
635                 var freq = freqn[0].childNodes[0].nodeValue;
636                 var id;
637                 if (idn[0])
638                     id = idn[0].childNodes[0].nodeValue;
639                 var refine_cell = create_element('a', term + ' (' + freq + ')');
640                 refine_cell.setAttribute('href', '#');
641                 refine_cell.setAttribute('term', term);
642                 refine_cell.setAttribute('facet', listname);
643                 refine_cell.setAttribute('target_id', id);
644                 refine_cell.onclick = function () {
645                     refine_query(this);
646                     return false;
647                 };
648                 body.appendChild(refine_cell);
649             }
650         }
651     }
652     if (clients > 0)
653         termtimer = setTimeout(check_termlist, 1000);
654 }
655
656 function check_termlist()
657 {
658     var facet_names = '';
659     var i;
660     for (i = 0; i < facet_list.length; i++)
661         if (facet_list[i][1].style.display != 'none')
662         {
663             if (facet_names)
664                 facet_names += ',';
665             facet_names += facet_list[i][0];
666         }
667     var url = "search.pz2?" +
668         "command=termlist" +
669         "&session=" + session +
670         "&name=" + facet_names +
671         "&num=12";
672     SendXmlHttpObject(xtermlist = GetXmlHttpObject(), url, show_termlists);
673 }
674
675 function show_stat()
676 {
677     if (xstat.readyState != 4)
678         return;
679     var i;
680     var xml = xstat.responseXML;
681     var body = document.getElementById("stat");
682     var nodes = xml.childNodes[0].childNodes;
683     var clients =
684         Number(xml.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue);
685     if (!nodes[0])
686     {
687         stattimer  = setTimeout(check_stat, 500);
688     }
689     else
690     {
691         assign_text(body, '(');
692         for (i = 0; i < nodes.length; i++)
693         {
694             if (nodes[i].nodeType != 1)
695                 continue;
696             var value = nodes[i].childNodes[0].nodeValue;
697             if (value == 0)
698                 continue;
699             var name = nodes[i].nodeName;
700             append_text(body, ' ' + name + '=' + value);
701         }
702
703         append_text(body, ')');
704         if (clients > 0)
705             stattimer = setTimeout(check_stat, 2000);
706     }
707 }
708
709 function check_stat()
710 {
711     var url = "search.pz2?" +
712         "command=stat" +
713         "&session=" + session;
714     xstat = GetXmlHttpObject();
715     xstat.onreadystatechange=show_stat;
716     xstat.open("GET", url);
717     xstat.send(null);
718 }
719
720 function search_started()
721 {
722     if (xsearch.readyState != 4)
723         return;
724     var xml = xsearch.responseXML;
725     var error = xml.getElementsByTagName("error");
726     if (error[0])
727     {
728         var msg = error[0].childNodes[0].nodeValue;
729         alert(msg);
730         return;
731     }
732     check_search();
733     stattimer = setTimeout(check_stat, 1000);
734 }
735
736 function clear_filter()
737 {
738     filter = '';
739 }
740
741 function start_search()
742 {
743     clearTimeout(termtimer);
744     termtimer = 0;
745     clearTimeout(searchtimer);
746     searchtimer = 0;
747     clearTimeout(stattimer);
748     stattimer = 0;
749     clearTimeout(showtimer);
750     showtimer = 0;
751     cur_id = -1;
752     clear_termlists();
753     var query = escape(document.getElementById('query').value);
754     var url = "search.pz2?" +
755         "command=search" +
756         "&session=" + session +
757         "&query=" + query +
758         "&filter=" + escape(filter);
759     xsearch = GetXmlHttpObject();
760     xsearch.onreadystatechange=search_started;
761     xsearch.open("GET", url);
762     xsearch.send(null);
763     clear_cell(document.getElementById("body"));
764     update_history();
765     shown = 0;
766     document.search.startrec.value = 0;
767 }
768
769 function session_encode ()
770 {
771     var i;
772     var session = '';
773
774     for (i = 0; i < session_cells.length; i++)
775     {
776         var name = session_cells[i];
777         var value = escape(document.getElementById(name).value);
778         session += '&' + name + '=' + value;
779     }
780
781     return session;
782 }
783
784
785 function session_restore (session)
786 {
787     var fields = session.split(/&/);
788     var i;
789
790     for (i = 1; i < fields.length; i++)
791     {
792         var pair = fields[i].split(/=/);
793         var key = pair.shift();
794         var value = pair.join('=');
795         var cell = document.getElementById(key);
796
797         cell.value = value;
798     }
799     
800 }
801
802
803 function session_read ()
804 {
805     var ses = window.location.hash.replace(/^#/, '');
806     return ses;
807 }
808
809
810 function session_store (new_value)
811 {
812     window.location.hash = '#' + new_value;
813 }
814
815
816 function update_history ()
817 {
818     var session = session_encode();
819     session_store(session);
820     old_session = session;
821 }
822
823
824 function session_check ()
825 {
826     var session = session_read();
827     var action = document.search.action_type.value;
828
829     clearInterval(url_surveillence);
830
831     if ( session != unescape(old_session) )
832     {
833         session_restore(session);
834
835         if (action == 'search') {
836             start_search();
837         } else if (action == 'page') {
838             check_search();
839         } else {
840             alert('Unregocnized action_type: ' + action);
841             return;
842         }
843     }
844     
845     url_surveillence = setInterval(session_check, 200);
846 }
847
848
849 function get_available_facets () {
850     var facet_container = document.getElementById('termlists');
851     var facet_cells = facet_container.childNodes;
852     var facets = Array();
853     var i;
854
855     for (i = 0; i < facet_cells.length; i++) {
856         var cell = facet_cells.item(i);
857
858         if (cell.className == 'facet') {
859             var facet_name = cell.id.replace(/^facet_([^_]+)_terms$/, "$1");
860             facets.push(Array(facet_name, cell));
861         }
862     }
863
864     return facets;
865 }
866
867
868 function get_facet_container (obj) {
869     return document.getElementById(obj.id + '_terms');
870 }
871
872
873 function toggle_facet (obj) {
874     var container = get_facet_container(obj);
875
876     if (obj.className == 'selected') {
877         obj.className = 'unselected';
878         container.style.display = 'inline';
879         check_termlist();
880     } else {
881         obj.className = 'selected';
882         container.style.display = 'none';
883     }
884 }