Fix pazpar2 man page referral to pazpar2_play
[pazpar2-moved-to-github.git] / www / mobile / mobile_client.js
1 /* A very simple client that shows a basic usage of the pz2.js
2 */
3
4 // create a parameters array and pass it to the pz2's constructor
5 // then register the form submit event with the pz2.search function
6 // autoInit is set to true on default
7 var usesessions = false;
8 var pazpar2path = '/service-proxy/';
9 var showResponseType = '';
10 // Facet configuration
11 var querys = {'su': '', 'au': '', 'xt': ''};
12 var query_client_server = {'su': 'subject', 'au': 'author', 'xt': 'xtargets'};
13 var querys_server = {};
14 var useLimit = 1;
15 var state = new State();
16 // Fail to get JSON working stabil.
17 var showResponseType = 'xml';
18 //some state vars
19 state.curPage = 1;
20 state.recPerPage = 5;
21 var recToShowPageSize = 20;
22 var recToShow = recToShowPageSize;
23 var recIDs = {};
24 var totalRec = 0;
25 var curDetRecId = '';
26 var curDetRecData = null;
27 var curSort = 'relevance';
28 var curFilter = 'ALL';
29 var submitted = false;
30 var SourceMax = 16;
31 var SubjectMax = 10;
32 var AuthorMax = 10;
33 var tab = "recordview"; 
34
35 var triedPass = "";
36 var triedUser = "";
37
38 var previousOrientation = window.orientation || 0;
39
40
41 window.addEventListener("load",function() {
42   // Set a timeout...
43   setTimeout(function(){
44     // Hide the address bar!
45     window.scrollTo(0, 1);
46   }, 0);
47 });
48
49 function calcRecPerPage() {
50   state.width = window.innerWidth;
51   state.height = window.innerHeight;
52   return Math.max(Math.round((state.height - 88 - 40) / 60), 5) ; 
53 }
54
55 function checkOrientation() {
56     if(state.height != window.innerHeight){
57         var newPageSize = calcRecPerPage();
58         //alert("orient change: Dimension " + state.width + " " + state.height + " Old Rec/page " + state.recPerPage + " New: " + newPageSize);  
59         state.setRecPerPage(newPageSize);
60         my_paz.show(state.getStartWith(), state.getRecPerPage(), curSort);
61     }
62 };
63
64 function setQS (encodedParams) {
65   if ("onhashchange" in window) {
66     window.location.hash = '#' + encodedParams;
67   } else {
68     var  url = document.location.href;
69     var i = url.indexOf("?");
70     if (i > -1) url = url.substr(0, i);
71     document.location.href = url + "?" + encodedParams;
72   }
73 }
74
75 state.setRecPerPage(calcRecPerPage());
76
77 window.addEventListener("resize", checkOrientation, false);
78 window.addEventListener("orientationchange", checkOrientation, false);
79
80 // (optional) Android doesn't always fire orientationChange on 180 degree turns
81 //setInterval(checkOrientation, 2000);
82
83 var imageHelper = new ImageHelper();
84
85 if (document.location.hash == '#pazpar2' || document.location.search.match("useproxy=false")) {
86     usesessions = true;
87     pazpar2path = '/pazpar2/search.pz2';
88     showResponseType = 'xml';
89 }
90
91 my_paz = new pz2( { "onshow": my_onshow,
92 //                    "showtime": 2000,            //each timer (show, stat, term, bytarget) can be specified this way
93                     "pazpar2path": pazpar2path,
94                     "oninit": my_oninit,
95                     "onstat": null,
96                     "onterm": my_onterm_iphone,
97                     "termlist": "xtargets,subject,author",
98                     "onbytarget": null,
99                     "usesessions" : usesessions,
100                     "showResponseType": showResponseType,
101                     "onrecord": my_onrecord,
102                     "errorhandler" : my_onerror} 
103 );
104
105 //
106 // pz2.js event handlers:
107 //
108 function my_onerror(error) {
109     switch(error.code) {
110         // No targets!
111     case "8": alert("No resources were selected for the search"); break;
112         // target not configured, this is a pazpar2 bug
113         // but for now simply research
114     case "9": 
115         triggerSearch(); 
116         break;
117         
118         // Already blocked 
119     case "13": 
120         // ignore
121         break
122         // authentication
123     case "100" : 
124         auth.check(loggedIn, login);
125         break;
126     default: 
127       alert("Unhandled error: " + error.code);
128       throw error; // display error in JavaScript console
129     }
130 }
131
132 //FF has a bug and un-escaped location.hash, don't use it
133 function getRealHash() {
134   var i = window.location.href.indexOf('#');
135   return i > -1 ? window.location.href.substr(i) : "";
136 }
137
138 function loginFormSubmit() {
139     triedUser = document.loginForm.username.value;
140     triedPass = document.loginForm.password.value;
141     auth.login( {"username": triedUser,
142                 "password": triedPass},
143         authCb, authCb);
144 }
145
146 function handleKeyPress(e)  
147 {  
148   var key;  
149   if(window.event)  
150     key = window.event.keyCode;  
151   else  
152     key = e.which;  
153
154   if(key == 13 || key == 10)  
155   {  
156       button = document.getElementById('button');
157       button.focus();
158       button.click();
159
160       return false;  
161   }  
162   else  
163     return true;  
164 }  
165
166 function authCb(authData) {
167     if (!authData.loginFailed) {
168         triedUser = "";
169         triedPass = "";
170     }
171
172     if (authData.loggedIn == true) {        
173         showhide("recordview");
174     }
175 }
176
177 function logOutClick() {
178     auth.logOut(authCb, authCb);
179 }
180
181 function loggedOut() {
182     var login = document.getElementById("login");
183     login.innerHTML = 'Login';
184 }
185
186 function loggingOutFailed() {
187     alert("Logging out failed");
188 }
189
190 function login() {
191     showhide("login");
192 }
193
194 function logout() {
195     auth.logOut(loggedOut, loggingOutFailed, true);
196 }
197
198 function logInOrOut() {
199     var loginElement = document.getElementById("login");
200     if (loginElement.innerHTML == 'Login')
201         login();
202     else
203         logout();
204 }
205 function loggedIn(context) {
206
207   if (context.ipAuth != true) {
208     var login = document.getElementById("login");
209     login.innerHTML = 'Logout';
210     document.getElementById("log").innerHTML = login.innerHTML;
211   }
212   domReady();
213 }
214
215 function auth_check() {
216     auth.check(loggedIn, login);
217     //domReady();
218 }
219
220 //
221 // Pz2.js event handlers:
222 //
223 function my_oninit() {
224     my_paz.stat();
225     my_paz.bytarget();
226 }
227
228 function showMoreRecords() {
229     var i = recToShow;
230     recToShow += recToShowPageSize;
231     for ( ; i < recToShow && i < state.recPerPage; i++) {
232         var element = document.getElementById(recIDs[i]);
233         if (element)
234             element.style.display = '';
235     }
236     if (i == state.recPerPage) {
237         var element = document.getElementById('recdiv_END');
238         if (element)
239             element.style.display = 'none';
240     }
241 }
242
243 function hideRecords() {
244     for ( var i = 0; i < recToShow; i++) {
245         var element = document.getElementById(recIDs[i]);
246         if (element && recIDs != curDetRecId)
247             element.style.display = 'none';
248     }
249     var element = document.getElementById('recdiv_END');
250     if (element)
251         element.style.display = 'none';
252 }
253
254 function showRecords() {
255     for (var i = 0 ; i < recToShow && i < state.recPerPage; i++) {
256         var element = document.getElementById(recIDs[i]);
257         if (element)
258             element.style.display = '';
259     }
260     var element = document.getElementById('recdiv_END');
261     if (element) {
262         if (i == state.recPerPage)
263             element.style.display = 'none';
264         else
265             element.style.display = '';
266     }
267 }
268
269 function my_onshow(data) {
270   hideLogo();
271   totalRec = data.merged;
272     // move it out
273     var pager = document.getElementById("pager");
274     pager.innerHTML = "";
275     drawPager(pager);
276     pager.innerHTML +='<div class="status">Displaying: ' 
277                     + (data.start + 1) + ' to ' + (data.start + data.num) +
278                      ' of ' + data.merged + ' (found: ' 
279                      + data.total + ')</div>';
280
281     var results = document.getElementById("results");
282     
283     var html = [];
284     if (data.hits == undefined) 
285         return ;
286     var style = '';
287     for (var i = 0; i < data.hits.length; i++) {
288         var hit = data.hits[i];
289         var recDivID = "recdiv_" + hit.recid; 
290         recIDs[i] = recDivID;
291         var lines = 0;
292         if (i == recToShow)
293             style = ' style="display:none" ';
294         html.push('<li class="img" id="' + recDivID + '" ' + style +  '>' );
295         html.push('<a class="img" href="#' + i + '" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;" >');
296         if (1) {
297             var useThumbnails = hit["md-use_thumbnails"];
298             var thumburls = hit["md-thumburl"];
299             if (thumburls && (useThumbnails == undefined || useThumbnails == "1")) {
300                 var thumbnailtag = imageHelper.getImageTagByRecId(hit.recid,"md-thumburl", 60, "S"); 
301                 html.push(thumbnailtag);
302             } else { 
303                 if (hit["md-isbn"] != undefined) { 
304                     var coverimagetag = imageHelper.getImageTagByRecId(hit.recid, "md-isbn", 60, "S"); 
305                     if (coverimagetag.length>0) { 
306                         html.push(coverimagetag);
307                     } else { 
308                         html.push("&nbsp;");
309                     }
310                 }
311             }
312         } 
313         html.push("</a>");
314         html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
315         html.push(hit["md-title"]); 
316         html.push("</a>");
317
318         if (hit["md-title-remainder"] != undefined) {
319             html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
320             html.push(hit["md-title-remainder"]);
321             html.push("</a>");
322             lines++;
323         }
324         if (hit["md-author"] != undefined) {
325             html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
326             html.push(hit["md-author"]);
327             html.push("</a>");
328             lines++;
329         }
330         else if (hit["md-title-responsibility"] != undefined) {
331             html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
332             html.push(hit["md-title-responsibility"]);
333             html.push("</a>");
334             lines++;
335         }
336         for (var idx = lines ; idx < 2 ; idx++) {
337             html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
338             html.push("&nbsp;");            
339             html.push("</a>");
340         }
341 /*      
342         html.push('<a href="go.html" id="rec_'+ hit.recid + '" >');
343         html.push("item page;");            
344         html.push("</a>");
345 */
346 /*
347         if (hit.recid == curDetRecId) {
348             html.push(renderDetails_iphone(curDetRecData));
349         }
350 */
351         html.push('</li>');
352     }
353     if (data.activeclients == 0)
354       finishLoading();
355 /*
356     // set up "More..." if needed. 
357     style = 'display:none';
358     if (recToShow < recPerPage) {
359         style = 'display:block';
360     }
361     html.push('<li class="img" id="recdiv_END" style="' + style + '"><a onclick="showMoreRecords()">More...</a></li>');     
362 */
363     replaceHtml(results, html.join(''));
364 }
365
366 function my_onstat(data) {
367     var stat = document.getElementById("stat");
368     if (stat == null)
369         return;
370     
371     stat.innerHTML = '<b> .:STATUS INFO</b> -- Active clients: '
372                         + data.activeclients
373                         + '/' + data.clients + ' -- </span>'
374                         + '<span>Retrieved records: ' + data.records
375                         + '/' + data.hits + ' :.</span>';
376 }
377
378 function showhide(newtab, hash) {
379     var showtermlist = false;
380     if (newtab != null)
381         tab = newtab;
382     
383     if (tab == "recordview") {
384         document.getElementById("recordview").style.display = '';
385         if (hash != undefined)
386             document.location.hash = hash;
387     }
388     else 
389         document.getElementById("recordview").style.display = 'none';
390
391     if (tab == "xtargets") {
392         document.getElementById("term_xtargets").style.display = '';
393         showtermlist = true;
394     }
395     else
396         document.getElementById("term_xtargets").style.display = 'none';
397
398     if (tab == "subjects") {
399         document.getElementById("term_subjects").style.display = '';
400         showtermlist = true;
401     }
402     else
403         document.getElementById("term_subjects").style.display = 'none';
404
405     if (tab == "authors") {
406         document.getElementById("term_authors").style.display = '';
407         showtermlist = true;
408     }
409     else
410         document.getElementById("term_authors").style.display = 'none';
411
412     if (tab == "detailview") {
413         document.getElementById("detailview").style.display = '';
414     }
415     else {
416         document.getElementById("detailview").style.display = 'none';
417         var element = document.getElementById("rec_" + curDetRecId);
418         if (element != undefined)
419             element.scrollIntoView();
420
421     }
422     if (showtermlist == false) 
423         document.getElementById("termlist").style.display = 'none';
424     else 
425         document.getElementById("termlist").style.display = '';
426
427     var tabDiv = document.getElementById("loginDiv");
428     if (tab == "login") {
429         tabDiv.style.display = '';
430     }
431     else {
432         tabDiv.style.display = 'none';
433     }
434 }
435
436 function my_onterm(data) {
437     var termlists = [];
438     
439     termlists.push('<div id="term_xtargets" >');
440     termlists.push('<h4 class="termtitle">Sources</h4>');
441     termlists.push('<ul class="termlist">');
442     termlists.push('<li> <a href="#" target_id="reset_xt" onclick="limitOrResetTarget(\'reset_xt\',\'All\');return false;">All</a></li>');
443     for (var i = 0; i < data.xtargets.length && i < SourceMax; i++ ) {
444         termlists.push('<li class="termlist"><a href="#" target_id='+data.xtargets[i].id
445             + ' onclick="limitOrResetTarget(this.getAttribute(\'target_id\'), \'' + data.xtargets[i].name + '\');return false;">' 
446             + data.xtargets[i].name + ' (' + data.xtargets[i].freq + ')</a></li>');
447     }
448     termlists.push('</ul>');
449     termlists.push('</div>');
450      
451     termlists.push('<div id="term_subjects" >');
452     termlists.push('<h4>Subjects</h4>');
453     termlists.push('<ul class="termlist">');
454     termlists.push('<li><a href="#" target_id="reset_su" onclick="limitOrResetQuery(\'reset_su\',\'All\');return false;">All</a></li>');
455     if (data.subject) {
456       for (var i = 0; i < data.subject.length && i < SubjectMax; i++ ) {
457           termlists.push('<li><a href="#" onclick="limitOrResetQuery(\'su\', \'' + data.subject[i].name + '\');return false;">' 
458                        + data.subject[i].name + ' (' + data.subject[i].freq + ')</a></li>');
459       }
460     }
461     else {
462       throw "Missing subject termlist: " + data;
463       return;
464     } 
465       
466     termlists.push('</ul>');
467     termlists.push('</div>');
468             
469     termlists.push('<div id="term_authors" >');
470     termlists.push('<h4 class="termtitle">Authors</h4>');
471     termlists.push('<ul class="termlist">');
472     termlists.push('<li><a href="#" onclick="limitOrResetQuery(\'reset_au\',\'All\');return false;">All</a></li>');
473     if (data.author) {
474       for (var i = 0; i < data.author.length && i < AuthorMax; i++ ) {
475         termlists.push('<li><a href="#" onclick="limitOrResetQuery(\'au\', \'' + data.author[i].name +'\');return false;">' 
476                             + data.author[i].name 
477                             + '  (' 
478                             + data.author[i].freq 
479                             + ')</a></li>');
480       }
481     }
482     else {
483       throw "Missing author termlist: " + data;
484       return; 
485     } 
486       
487     termlists.push('</ul>');
488     termlists.push('</div>');
489     var termlist = document.getElementById("termlist");
490     replaceHtml(termlist, termlists.join(''));
491     showhide();
492 }
493
494 var termlist = {};
495 function my_onterm_iphone(data) {
496     my_onterm(data);
497     var targets = "reset_xt|All\n";
498     
499     for (var i = 0; i < data.xtargets.length; i++ ) {
500         
501         targets = targets + data.xtargets[i].id + "|" + data.xtargets[i].name + "|" + data.xtargets[i].freq + "\n";
502     }
503     termlist["xtargets"] = targets;
504     var subjects = "reset_su|All\n";
505     for (var i = 0; i < data.subject.length; i++ ) {
506         subjects = subjects + "su" + "|" + data.subject[i].name + "|" + data.subject[i].freq + "\n";
507     }
508     termlist["subjects"] = subjects;
509     var authors = "reset_au|All\n";
510     for (var i = 0; i < data.author.length; i++ ) {
511         authors = authors + "au" + "|" + data.author[i].name + "|" + data.author[i].freq + "\n";
512     }
513     termlist["authors"] = authors;
514     callback.send("termlist", "refresh");
515 }
516
517 function getTargets() {
518         return termlist['xtargets'];
519 }
520
521 function getSubjects() {
522         return termlist['subjects'];
523 }
524
525 function getAuthors() {
526         return termlist['authors'];
527 }
528
529 function my_onrecord(data) {
530
531     // FIXME: record is async!!
532     clearTimeout(my_paz.recordTimer);
533     // in case on_show was faster to redraw element
534     var detailRecordDiv = document.getElementById('detailrecord');
535     if (!detailRecordDiv) 
536         return;
537     curDetRecData = data;
538     var html = renderDetails_iphone(curDetRecData);
539     detailRecordDiv.innerHTML = html;
540     showhide('detailview');
541     finishLoading();
542 }
543
544 function my_onrecord_iphone(data) {
545     my_onrecord(data);
546     callback.send("record", data.recid, data, data.xtargets[i].freq);
547 }
548
549
550 function my_onbytarget(data) {
551     var targetDiv = document.getElementById("bytarget");
552     var table ='<table><thead><tr><td>Target ID</td><td>Hits</td><td>Diags</td>'
553         +'<td>Records</td><td>State</td></tr></thead><tbody>';
554     
555     for (var i = 0; i < data.length; i++ ) {
556         table += "<tr><td>" + data[i].id +
557             "</td><td>" + data[i].hits +
558             "</td><td>" + data[i].diagnostic +
559             "</td><td>" + data[i].records +
560             "</td><td>" + data[i].state + "</td></tr>";
561     }
562
563     table += '</tbody></table>';
564     targetDiv.innerHTML = table;
565 }
566
567 ////////////////////////////////////////////////////////////////////////////////
568 ////////////////////////////////////////////////////////////////////////////////
569
570 // wait until the DOM is ready
571 function domReady () 
572
573     // document.search.onsubmit = onFormSubmitEventHandler;
574     document.search.query.value = '';
575     document.select.sort.onchange = onSelectDdChange;
576     document.select.perpage.onchange = onSelectDdChange;
577     if (document.location.search.match("inApp=true")) 
578         applicationMode(true);
579     else
580         applicationMode(false);
581
582     window.location.parameters = parseQueryString(window.location.search);
583     window.location.parametersMulti = parseQueryStringMulti(window.location.search);
584
585     // hash params have highest priority, than query params
586     var params = (window.location.hash && window.location.hash.length > 1)
587       ? parseQueryString(getRealHash())
588       : window.location.parameters;
589     var paramsMulti = window.location.parametersMulti;
590 /*
591     var params = parseQueryString(window.location.search);
592     if (params.query) {
593         document.search.query.value = params.query;
594         onFormSubmitEventHandler();
595     }
596     
597 */
598     controlRegister.loadControls();
599
600     //append settings to the 'state'
601     loadSettings(function (setts) {
602         state.setFallbackSettings(setts);
603         controlRegister.populateControls(setts);  // set controls from cookies
604         controlRegister.populateControls(params); // override from query string
605         stateChanged(params);        
606     });
607     
608 }
609  
610 function applicationMode(newmode) 
611 {
612     var searchdiv = document.getElementById("searchForm");
613     if (newmode)
614         inApp = newmode;
615     if (inApp) {
616         document.getElementById("heading").style.display="none";
617         searchdiv.style.display = 'none';
618     }
619     else { 
620         
621         document.getElementById("nav").style.display="";
622         document.getElementById("normal").style.display="inline";
623         document.getElementById("normal").style.visibility="";
624         searchdiv.style.display = '';
625         //document.search.onsubmit = onFormSubmit;
626     }
627     callback.init();
628 }
629 // when search button pressed
630 function onFormSubmitEventHandler() 
631 {
632     resetPage();
633     document.location.hash = "query=" + document.search.query.value;
634     //window.location.search = "query=" + document.search.query.value;
635     loadSelect();
636     triggerSearch();
637     submitted = true;
638     return true;
639 }
640
641 function onSelectDdChange()
642 {
643     if (!submitted) return false;
644     resetPage();
645     loadSelect();
646     my_paz.show(0, state.recPerPage, curSort);
647     return false;
648 }
649
650
651 function stateChanged(params) {
652   if (params == undefined) 
653         return;
654   if (params["query"]) {
655     // If this page was accessed with a query param, usually means
656     // new page refresh, but not always!
657     state.reset(); // to ensure it's clean and fallbacks are loaded
658     calcRecPerPage();
659     state.loadParams(params);
660   } else if (params["query_state"]) {
661           // If this page was accessed with a serialized State object
662     state.reset(); // to ensure it's clean and fallbacks are loaded
663     state.deserialize(String(params["query_state"]));
664   }
665   document.search.query.value = state.simpleQuery;        
666   document.select.sort.value = state.curSort;        
667   //document.select.perpage.value = state.recPerPage;
668   if (document.category && document.category.category_filter) {
669         document.category.category_filter.value = state.categoryFilter;
670   }
671   if (document.search.query.value != "")
672     triggerSearch();
673 }
674
675 function resetPage()
676 {
677   state.curPage = 1;    
678   totalRec = 0;     
679 }
680
681 function getFacets() {
682     var result = "";
683     for (var key in querys_server) {
684         if (result.length > 0)
685             result += ","
686         result += querys_server[key];
687     }
688     return result;
689 }
690
691 function triggerSearch ()
692 {
693     // Restore to initial page size. Old stuff
694     recToShow = recToShowPageSize;
695     
696     displayLoading();
697     my_paz.search(document.search.query.value, state.recPerPage, curSort, curFilter, undefined,
698         {
699            "limit" : getFacets() 
700         }
701         );
702     showhide("recordview");
703 }
704
705 function loadSelect ()
706 {
707     curSort = document.select.sort.value;
708     //state.recPerPage = document.select.perpage.value;
709 }
710
711 // limit the query after clicking the facet
712 function limitQuery(field, value)
713 {
714   var newQuery = ' and ' + field + '="' + value + '"';
715   querys[field] += newQuery;
716   document.search.query.value += newQuery;
717   onFormSubmitEventHandler();
718   showhide("recordview");
719 }
720
721 // limit the query after clicking the facet
722 function limitQueryServer(field, value)
723 {
724     // Check for client field usage
725     var fieldname = query_client_server[field];
726     if (!fieldname) 
727         fieldname = field;      
728     
729     var newQuery = fieldname + '=' + value.replace(",", "\\,").replace("|", "\\,");
730     // Does it already exists?
731     if (querys_server[fieldname]) 
732         querys_server[fieldname] += "," + newQuery;
733     else
734         querys_server[fieldname] = newQuery;
735 //  document.search.query.value += newQuery;
736   onFormSubmitEventHandler();
737   showhide("recordview");
738 }
739
740
741
742 // limit the query after clicking the facet
743 function removeQuery (field, value) {
744         document.search.query.value.replace(' and ' + field + '="' + value + '"', '');
745     onFormSubmitEventHandler();
746     showhide("recordview");
747 }
748
749 // limit the query after clicking the facet
750 function limitOrResetQuery (field, value, selected) {
751     if (useLimit) {
752         limitOrResetQueryServer(field,value, selected);
753         return ;
754     }
755     if (field == 'reset_su' || field == 'reset_au') {
756         var reset_field = field.substring(6);
757         document.search.query.value = document.search.query.value.replace(querys[reset_field], '');
758         querys[reset_field] = '';
759         onFormSubmitEventHandler();
760         showhide("recordview");
761     }
762     else 
763         limitQuery(field, value);
764         //alert("limitOrResetQuerry: query after: " + document.search.query.value);
765 }
766
767 // limit the query after clicking the facet
768 function limitOrResetQueryServer (field, value, selected) {
769     if (field.substring(0,6) == 'reset_') {
770         var clientname = field.substring(6);
771         var fieldname = query_client_server[clientname];
772         if (!fieldname) 
773             fieldname = clientname;     
774         delete querys_server[fieldname];
775         onFormSubmitEventHandler();
776         showhide("recordview");
777     }
778     else 
779         limitQueryServer(field, value);
780         //alert("limitOrResetQuerry: query after: " + document.search.query.value);
781 }
782
783
784
785
786 // limit by target functions
787 function limitTarget (id, name)
788 {
789     curFilter = 'pz:id=' + id;
790     resetPage();
791     loadSelect();
792     triggerSearch();
793     return false;
794 }
795
796 function delimitTarget ()
797 {
798     curFilter = 'ALL'; 
799     resetPage();
800     loadSelect();
801     triggerSearch();
802     return false;
803 }
804
805 function limitOrResetTarget(id, name) {
806         if (id == 'reset_xt') {
807                 delimitTarget();
808         }
809         else {
810                 limitTarget(id,name);
811         }
812 }
813
814 function drawPager (pagerDiv)
815 {
816     //client indexes pages from 1 but pz2 from 0
817     var onsides = 2;
818     var pages = Math.ceil(totalRec / state.recPerPage);
819     
820     var firstClkbl = ( state.curPage - onsides > 0 ) 
821         ? state.curPage - onsides
822         : 1;
823
824     var lastClkbl = firstClkbl + 2*onsides < pages
825         ? firstClkbl + 2*onsides
826         : pages;
827
828     var prev = '<span id="prev">Prev</span><b> | </b>';
829     if (state.curPage > 1)
830         var prev = '<a href="#" id="prev" onclick="pagerPrev();">'
831         +'Prev</a><b> | </b>';
832
833     var middle = '';
834     for(var i = firstClkbl; i <= lastClkbl; i++) {
835         var numLabel = i;
836         if(i == state.curPage)
837             numLabel = '<b>' + i + '</b>';
838
839         middle += '<a href="#" onclick="showPage(' + i + ')"> '
840             + numLabel + ' </a>';
841     }
842     
843     var next = '<b> | </b><span id="next">Next</span>';
844     if (pages - state.curPage > 0)
845     var next = '<b> | </b><a href="#" id="next" onclick="pagerNext()">'
846         +'Next</a>';
847
848     predots = '';
849     if (firstClkbl > 1)
850         predots = '...';
851
852     postdots = '';
853     if (lastClkbl < pages)
854         postdots = '...';
855
856     pagerDiv.innerHTML += '<div class="pager">' 
857         + prev + predots + middle + postdots + next + '</div>';
858 }
859
860 function showPage(pageNum)
861 {
862     //state.curPage = pageNum;
863     state.curPage = pageNum;
864     displayLoading();
865     my_paz.showPage( state.curPage - 1 );
866 }
867
868 // simple paging functions
869
870 function pagerNext() {
871     if ( totalRec - state.recPerPage*state.curPage > 0) {
872         displayLoading();
873         my_paz.showNext();
874         //curPage++;
875         state.curPage++;
876     }
877 }
878
879 function pagerPrev() {
880   if ( my_paz.showPrev() != false ) {
881     displayLoading();    
882     state.curPage--;
883     if (state.curPage <= 0)
884       throw "Zero or negative current page"; 
885   }
886
887 }
888
889 // swithing view between targets and records
890
891 function switchView(view) {
892     
893     var targets = document.getElementById('targetview');
894     var records = document.getElementById('recordview');
895     
896     switch(view) {
897         case 'targetview':
898             targets.style.display = "block";            
899             records.style.display = "none";
900             break;
901         case 'recordview':
902             targets.style.display = "none";            
903             records.style.display = "block";
904             break;
905         default:
906             alert('Unknown view.');
907     }
908 }
909
910 function hideLogo() {
911   document.getElementById("logo").style.display = 'none';
912 }
913
914 function displayLoading() {
915   document.getElementById("loading").style.display = 'inline';
916 }
917
918 function finishLoading() {
919   document.getElementById("loading").style.display = 'none';
920 }
921
922
923 // detailed record drawing
924 function showDetails (prefixRecId) {
925     var recId = prefixRecId.replace('rec_', '');
926     var oldRecId = curDetRecId;
927     curDetRecId = recId;
928     
929     // if the same clicked, just show it again
930     if (recId == oldRecId) {
931         showhide('detailview');
932         return;
933     }
934     // request the record
935     displayLoading()
936     my_paz.record_with_query(recId, state.simpleQuery);
937 }
938
939 function replaceHtml(el, html) {
940   var oldEl = typeof el === "string" ? document.getElementById(el) : el;
941   /*@cc_on // Pure innerHTML is slightly faster in IE
942     oldEl.innerHTML = html;
943     return oldEl;
944     @*/
945   var newEl = oldEl.cloneNode(false);
946   newEl.innerHTML = html;
947   oldEl.parentNode.replaceChild(newEl, oldEl);
948   /* Since we just removed the old element from the DOM, return a reference
949      to the new element, which can be used to restore variable references. */
950   return newEl;
951 };
952
953 function renderDetails(data, marker)
954 {
955     var details = '<div class="details" id="det_'+data.recid+'"><table>';
956     if (marker) details += '<tr><td>'+ marker + '</td></tr>';
957     if (data["md-title"] != undefined) {
958         details += '<tr><td><b>Title</b></td><td><b>:</b> '+data["md-title"];
959         if (data["md-title-remainder"] != undefined) {
960               details += ' : <span>' + data["md-title-remainder"] + ' </span>';
961         }
962         if (data["md-author"] != undefined) {
963               details += ' <span><i>'+ data["md-auhtor"] +'</i></span>';
964         }
965         details += '</td></tr>';
966     }
967     if (data["md-date"] != undefined)
968         details += '<tr><td><b>Date</b></td><td><b>:</b> ' + data["md-date"] + '</td></tr>';
969     if (data["md-author"] != undefined)
970         details += '<tr><td><b>Author</b></td><td><b>:</b> ' + data["md-author"] + '</td></tr>';
971     if (data["md-electronic-url"] != undefined)
972         details += '<tr><td><b>URL</b></td><td><b>:</b> <a href="' + data["md-electronic-url"] + '" target="_blank">' + data["md-electronic-url"] + '</a>' + '</td></tr>';
973     if (data["location"][0]["md-subject"] != undefined)
974         details += '<tr><td><b>Subject</b></td><td><b>:</b> ' + data["location"][0]["md-subject"] + '</td></tr>';
975     if (data["location"][0]["@name"] != undefined)
976         details += '<tr><td><b>Location</b></td><td><b>:</b> ' + data["location"][0]["@name"] + " (" +data["location"][0]["@id"] + ")" + '</td></tr>';
977     details += '</table></div>';
978     return details;
979 }
980
981 var default_tag = 'big';
982 function renderLine(title, value, tag) {
983     if (tag == undefined)
984         tag = default_tag;
985     if (value != undefined)
986         return '<li><h3>' + title + '</h3><' + tag + '>' + value + '</' + tag + '></li>';
987     return '';
988 }
989
990 function renderLines(title, values, name, tag) {
991     if (tag == undefined)
992         tag = default_tag;
993     var result = "";
994     if (values != undefined && values.length)
995         for (var idx = 0 ; idx < values.length ; idx++)
996             if (values[idx][name] != undefined )
997                 result += values[idx][name] + ' ';
998     if (result != "") 
999         result = '<li><h3>' + title + '</h3><' + tag + '>' + result + '</' + tag + '></li>';
1000     return result;
1001 }
1002
1003 // Values is a array of locations. 
1004
1005 function renderLinesURL(title, values, name, url, tag) {
1006     if (tag == undefined)
1007         tag = default_tag;
1008     var result = "";
1009     result = '<li><h3>' + title + '</h3><' + tag + ' style="display: inline-block;">';
1010     if (values != undefined && values.length) {
1011         for (var idx = 0 ; idx < values.length ; idx++) {
1012             var url = choose_url(values[idx], auth.proxyUrl);
1013             if (url != null)
1014                 result += '<a target="_blank" href="' + url + '">' + values[idx][name] + '</a><br>';
1015             else
1016                 result += values[idx][name] + '<br>';
1017         }
1018     }
1019     result += '</' + tag + '></li>';
1020     return result;
1021 }
1022
1023 function renderLineURL(title, URL, display) {
1024     if (URL != undefined)
1025         return '<li><h3>' + title + '</h3><a href="' + URL + '" target="_blank">' + display + '</a></li>';
1026     return '';
1027 }
1028
1029 function renderLineEmail(dtitle, email, display) {
1030     if (email != undefined)
1031         return '<li><h3>' + title + '</h3> <a href="mailto:' + email + '" target="_blank">' + display + '</a></li>';
1032     return '';
1033 }
1034
1035
1036 function find_prioritized(values) {
1037     for (var index = 0; index < values.length; index++) {
1038         if (values[index] != undefined)
1039             return values[index];
1040     }
1041     return undefined;
1042 }
1043
1044 function renderDetails_iphone(data, marker)
1045 {
1046         //return renderDetails(data,marker);
1047
1048     if (!data) 
1049         return ""; 
1050     var details = '<div class="details" id="det_'+data.recid+'" >'
1051     if (marker) 
1052         details += '<h4>'+ marker + '</h4>'; 
1053     details += '<ul class="field" >';
1054
1055     var title  = '';
1056     if (data["md-title"] != undefined) {
1057         title +=  data["md-title"];
1058         if (data["md-title-remainder"] != undefined) {
1059             title += '<br><i>' + data["md-title-remainder"] + '</i>';
1060         }
1061     }
1062     details += renderLine('Title', title);
1063
1064     var author = find_prioritized(
1065         [
1066             data["md-author"],
1067             data["md-title-responsibility"]
1068         ]
1069     );
1070
1071     var coverimagetag = imageHelper.getImageTagByRecId(data.recid, "md-isbn", undefined, "M");
1072     details 
1073         +=renderLine('Date',    data["md-date"])
1074         + renderLine('Author',  data["md-author"])
1075 //      + renderLineURL('URL',  data["md-electronic-url"], data["md-electronic-url"])
1076         + renderLine('Description',     data["md-description"])
1077 //      + renderLines('Subjects', data["location"], "md-subject")
1078     ;
1079
1080     details += renderLinesURL('Location', data["location"], "@name", "md-url_recipe");
1081     details += '<li><a href="#" onclick="showhide(\'recordview\')" style="font-size: 18px;margin-left: 10px;">Back</a></li>';
1082     if (coverimagetag.length>0) {
1083         details += renderLine('&nbsp;', coverimagetag);
1084     }
1085
1086     details += '</ul></div>';
1087     return details;
1088 }
1089
1090 //EOF