1 /* A very simple client that shows a basic usage of the pz2.js
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 = {};
15 // Fail to get JSON working stabil.
16 var showResponseType = 'xml';
18 var imageHelper = new ImageHelper();
20 if (document.location.hash == '#pazpar2' || document.location.search.match("useproxy=false")) {
22 pazpar2path = '/pazpar2/search.pz2';
23 showResponseType = 'xml';
26 my_paz = new pz2( { "onshow": my_onshow,
27 // "showtime": 2000, //each timer (show, stat, term, bytarget) can be specified this way
28 "pazpar2path": pazpar2path,
31 "onterm": my_onterm_iphone,
32 "termlist": "xtargets,subject,author",
34 "usesessions" : usesessions,
35 "showResponseType": showResponseType,
36 "onrecord": my_onrecord } );
40 var recToShowPageSize = 20;
41 var recToShow = recToShowPageSize;
45 var curDetRecData = null;
46 var curSort = 'relevance';
47 var curFilter = 'ALL';
48 var submitted = false;
52 var tab = "recordview";
57 function loginFormSubmit() {
58 triedUser = document.loginForm.username.value;
59 triedPass = document.loginForm.password.value;
60 auth.login( {"username": triedUser,
61 "password": triedPass},
65 function handleKeyPress(e)
69 key = window.event.keyCode;
73 if(key == 13 || key == 10)
75 button = document.getElementById('button');
85 function authCb(authData) {
86 if (!authData.loginFailed) {
91 if (authData.loggedIn == true) {
92 showhide("recordview");
96 function logOutClick() {
97 auth.logOut(authCb, authCb);
100 function loggedOut() {
101 var login = document.getElementById("login");
102 login.innerHTML = 'Login';
105 function loggingOutFailed() {
106 alert("Logging out failed");
114 auth.logOut(loggedOut, loggingOutFailed, true);
117 function logInOrOut() {
118 var loginElement = document.getElementById("login");
119 if (loginElement.innerHTML == 'Login')
124 function loggedIn() {
125 var login = document.getElementById("login");
126 login.innerHTML = 'Logout(' + auth.displayName + ')';
127 document.getElementById("log").innerHTML = login.innerHTML;
130 function auth_check() {
131 auth.check(loggedIn, login);
136 // Pz2.js event handlers:
138 function my_oninit() {
143 function showMoreRecords() {
145 recToShow += recToShowPageSize;
146 for ( ; i < recToShow && i < recPerPage; i++) {
147 var element = document.getElementById(recIDs[i]);
149 element.style.display = '';
151 if (i == recPerPage) {
152 var element = document.getElementById('recdiv_END');
154 element.style.display = 'none';
158 function hideRecords() {
159 for ( var i = 0; i < recToShow; i++) {
160 var element = document.getElementById(recIDs[i]);
161 if (element && recIDs != curDetRecId)
162 element.style.display = 'none';
164 var element = document.getElementById('recdiv_END');
166 element.style.display = 'none';
169 function showRecords() {
170 for (var i = 0 ; i < recToShow && i < recPerPage; i++) {
171 var element = document.getElementById(recIDs[i]);
173 element.style.display = '';
175 var element = document.getElementById('recdiv_END');
178 element.style.display = 'none';
180 element.style.display = '';
187 function my_onshow(data) {
188 totalRec = data.merged;
190 var pager = document.getElementById("pager");
191 pager.innerHTML = "";
192 pager.innerHTML +='<hr/><div style="float: right">Displaying: '
193 + (data.start + 1) + ' to ' + (data.start + data.num) +
194 ' of ' + data.merged + ' (found: '
195 + data.total + ')</div>';
198 var results = document.getElementById("results");
201 if (data.hits == undefined)
204 for (var i = 0; i < data.hits.length; i++) {
205 var hit = data.hits[i];
206 var recDivID = "recdiv_" + hit.recid;
207 recIDs[i] = recDivID;
210 style = ' style="display:none" ';
211 html.push('<li class="img arrow" id="' + recDivID + '" ' + style + '>' );
212 html.push('<a class="img" href="#' + i + '" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;" >');
214 var useThumbnails = hit["md-use_thumbnails"];
215 var thumburls = hit["md-thumburl"];
216 if (thumburls && (useThumbnails == undefined || useThumbnails == "1")) {
217 var thumbnailtag = imageHelper.getImageTagByRecId(hit.recid,"md-thumburl", 60, "S");
218 html.push(thumbnailtag);
220 if (hit["md-isbn"] != undefined) {
221 var coverimagetag = imageHelper.getImageTagByRecId(hit.recid, "md-isbn", 60, "S");
222 if (coverimagetag.length>0) {
223 html.push(coverimagetag);
231 html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
232 html.push(hit["md-title"]);
235 if (hit["md-title-remainder"] != undefined) {
236 html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
237 html.push(hit["md-title-remainder"]);
241 if (hit["md-author"] != undefined) {
242 html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
243 html.push(hit["md-author"]);
247 else if (hit["md-title-responsibility"] != undefined) {
248 html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
249 html.push(hit["md-title-responsibility"]);
253 for (var idx = lines ; idx < 2 ; idx++) {
254 html.push('<a href="#" id="rec_'+hit.recid + '" onclick="showDetails(this.id);return false;">');
259 if (hit.recid == curDetRecId) {
260 html.push(renderDetails_iphone(curDetRecData));
265 document.getElementById("loading").style.display = 'none';
266 // set up "More..." if needed.
267 style = 'display:none';
268 if (recToShow < recPerPage) {
269 style = 'display:block';
271 html.push('<li class="img" id="recdiv_END" style="' + style + '"><a onclick="showMoreRecords()">More...</a></li>');
273 replaceHtml(results, html.join(''));
276 function my_onstat(data) {
277 var stat = document.getElementById("stat");
281 stat.innerHTML = '<b> .:STATUS INFO</b> -- Active clients: '
283 + '/' + data.clients + ' -- </span>'
284 + '<span>Retrieved records: ' + data.records
285 + '/' + data.hits + ' :.</span>';
288 function showhide(newtab, hash) {
289 var showtermlist = false;
293 if (tab == "recordview") {
294 document.getElementById("recordview").style.display = '';
295 if (hash != undefined)
296 document.location.hash = hash;
299 document.getElementById("recordview").style.display = 'none';
301 if (tab == "xtargets") {
302 document.getElementById("term_xtargets").style.display = '';
306 document.getElementById("term_xtargets").style.display = 'none';
308 if (tab == "subjects") {
309 document.getElementById("term_subjects").style.display = '';
313 document.getElementById("term_subjects").style.display = 'none';
315 if (tab == "authors") {
316 document.getElementById("term_authors").style.display = '';
320 document.getElementById("term_authors").style.display = 'none';
322 if (tab == "detailview") {
323 document.getElementById("detailview").style.display = '';
326 document.getElementById("detailview").style.display = 'none';
327 var element = document.getElementById("rec_" + curDetRecId);
328 if (element != undefined)
329 element.scrollIntoView();
332 if (showtermlist == false)
333 document.getElementById("termlist").style.display = 'none';
335 document.getElementById("termlist").style.display = '';
337 var tabDiv = document.getElementById("loginDiv");
338 if (tab == "login") {
339 tabDiv.style.display = '';
342 tabDiv.style.display = 'none';
346 function my_onterm(data) {
349 termlists.push('<div id="term_xtargets" >');
350 termlists.push('<h4 class="termtitle">Sources</h4>');
351 termlists.push('<ul class="termlist">');
352 termlists.push('<li> <a href="#" target_id="reset_xt" onclick="limitOrResetTarget(\'reset_xt\',\'All\');return false;">All</a></li>');
353 for (var i = 0; i < data.xtargets.length && i < SourceMax; i++ ) {
354 termlists.push('<li class="termlist"><a href="#" target_id='+data.xtargets[i].id
355 + ' onclick="limitOrResetTarget(this.getAttribute(\'target_id\'), \'' + data.xtargets[i].name + '\');return false;">'
356 + data.xtargets[i].name + ' (' + data.xtargets[i].freq + ')</a></li>');
358 termlists.push('</ul>');
359 termlists.push('</div>');
361 termlists.push('<div id="term_subjects" >');
362 termlists.push('<h4>Subjects</h4>');
363 termlists.push('<ul class="termlist">');
364 termlists.push('<li><a href="#" target_id="reset_su" onclick="limitOrResetQuery(\'reset_su\',\'All\');return false;">All</a></li>');
365 for (var i = 0; i < data.subject.length && i < SubjectMax; i++ ) {
366 termlists.push('<li><a href="#" onclick="limitOrResetQuery(\'su\', \'' + data.subject[i].name + '\');return false;">'
367 + data.subject[i].name + ' (' + data.subject[i].freq + ')</a></li>');
369 termlists.push('</ul>');
370 termlists.push('</div>');
372 termlists.push('<div id="term_authors" >');
373 termlists.push('<h4 class="termtitle">Authors</h4>');
374 termlists.push('<ul class="termlist">');
375 termlists.push('<li><a href="#" onclick="limitOrResetQuery(\'reset_au\',\'All\');return false;">All<a></li>');
376 for (var i = 0; i < data.author.length && i < AuthorMax; i++ ) {
377 termlists.push('<li><a href="#" onclick="limitOrResetQuery(\'au\', \'' + data.author[i].name +'\');return false;">'
378 + data.author[i].name
380 + data.author[i].freq
383 termlists.push('</ul>');
384 termlists.push('</div>');
385 var termlist = document.getElementById("termlist");
386 replaceHtml(termlist, termlists.join(''));
391 function my_onterm_iphone(data) {
393 var targets = "reset_xt|All\n";
395 for (var i = 0; i < data.xtargets.length; i++ ) {
397 targets = targets + data.xtargets[i].id + "|" + data.xtargets[i].name + "|" + data.xtargets[i].freq + "\n";
399 termlist["xtargets"] = targets;
400 var subjects = "reset_su|All\n";
401 for (var i = 0; i < data.subject.length; i++ ) {
402 subjects = subjects + "su" + "|" + data.subject[i].name + "|" + data.subject[i].freq + "\n";
404 termlist["subjects"] = subjects;
405 var authors = "reset_au|All\n";
406 for (var i = 0; i < data.author.length; i++ ) {
407 authors = authors + "au" + "|" + data.author[i].name + "|" + data.author[i].freq + "\n";
409 termlist["authors"] = authors;
410 callback.send("termlist", "refresh");
413 function getTargets() {
414 return termlist['xtargets'];
417 function getSubjects() {
418 return termlist['subjects'];
421 function getAuthors() {
422 return termlist['authors'];
425 function my_onrecord(data) {
427 // FIXME: record is async!!
428 clearTimeout(my_paz.recordTimer);
429 // in case on_show was faster to redraw element
430 var detailRecordDiv = document.getElementById('detailrecord');
431 if (!detailRecordDiv)
433 curDetRecData = data;
434 var html = renderDetails_iphone(curDetRecData);
435 detailRecordDiv.innerHTML = html;
436 document.getElementById("loading").style.diplay = 'none';
437 showhide('detailview');
440 function my_onrecord_iphone(data) {
442 callback.send("record", data.recid, data, data.xtargets[i].freq);
446 function my_onbytarget(data) {
447 var targetDiv = document.getElementById("bytarget");
448 var table ='<table><thead><tr><td>Target ID</td><td>Hits</td><td>Diags</td>'
449 +'<td>Records</td><td>State</td></tr></thead><tbody>';
451 for (var i = 0; i < data.length; i++ ) {
452 table += "<tr><td>" + data[i].id +
453 "</td><td>" + data[i].hits +
454 "</td><td>" + data[i].diagnostic +
455 "</td><td>" + data[i].records +
456 "</td><td>" + data[i].state + "</td></tr>";
459 table += '</tbody></table>';
460 targetDiv.innerHTML = table;
463 ////////////////////////////////////////////////////////////////////////////////
464 ////////////////////////////////////////////////////////////////////////////////
466 // wait until the DOM is ready
469 document.search.onsubmit = onFormSubmitEventHandler;
470 document.search.query.value = '';
471 document.select.sort.onchange = onSelectDdChange;
472 document.select.perpage.onchange = onSelectDdChange;
473 if (document.location.search.match("inApp=true"))
474 applicationMode(true);
476 applicationMode(false);
478 var params = parseQueryString(window.location.search);
480 document.search.query.value = params.query;
481 onFormSubmitEventHandler();
485 function applicationMode(newmode)
487 var searchdiv = document.getElementById("searchForm");
491 document.getElementById("heading").style.display="none";
492 searchdiv.style.display = 'none';
496 document.getElementById("nav").style.display="";
497 document.getElementById("normal").style.display="inline";
498 document.getElementById("normal").style.visibility="";
499 searchdiv.style.display = '';
500 document.search.onsubmit = onFormSubmit;
504 // when search button pressed
505 function onFormSubmitEventHandler()
508 document.getElementById("logo").style.display = 'none';
515 function onSelectDdChange()
517 if (!submitted) return false;
520 my_paz.show(0, recPerPage, curSort);
530 function getFacets() {
532 for (var key in querys_server) {
533 if (result.length > 0)
535 result += querys_server[key];
540 function triggerSearch ()
542 // Restore to initial page size
543 recToShow = recToShowPageSize;
544 my_paz.search(document.search.query.value, recPerPage, curSort, curFilter, undefined,
546 "limit" : getFacets()
549 document.getElementById("loading").style.diplay = 'block';
552 function loadSelect ()
554 curSort = document.select.sort.value;
555 recPerPage = document.select.perpage.value;
558 // limit the query after clicking the facet
559 function limitQuery(field, value)
561 var newQuery = ' and ' + field + '="' + value + '"';
562 querys[field] += newQuery;
563 document.search.query.value += newQuery;
564 onFormSubmitEventHandler();
565 showhide("recordview");
568 // limit the query after clicking the facet
569 function limitQueryServer(field, value)
571 // Check for client field usage
572 var fieldname = query_client_server[field];
576 var newQuery = fieldname + '=' + value.replace(",", "\\,").replace("|", "\\,");
577 // Does it already exists?
578 if (querys_server[fieldname])
579 querys_server[fieldname] += "," + newQuery;
581 querys_server[fieldname] = newQuery;
582 // document.search.query.value += newQuery;
583 onFormSubmitEventHandler();
584 showhide("recordview");
589 // limit the query after clicking the facet
590 function removeQuery (field, value) {
591 document.search.query.value.replace(' and ' + field + '="' + value + '"', '');
592 onFormSubmitEventHandler();
593 showhide("recordview");
596 // limit the query after clicking the facet
597 function limitOrResetQuery (field, value, selected) {
599 limitOrResetQueryServer(field,value, selected);
602 if (field == 'reset_su' || field == 'reset_au') {
603 var reset_field = field.substring(6);
604 document.search.query.value = document.search.query.value.replace(querys[reset_field], '');
605 querys[reset_field] = '';
606 onFormSubmitEventHandler();
607 showhide("recordview");
610 limitQuery(field, value);
611 //alert("limitOrResetQuerry: query after: " + document.search.query.value);
614 // limit the query after clicking the facet
615 function limitOrResetQueryServer (field, value, selected) {
616 if (field.substring(0,6) == 'reset_') {
617 var clientname = field.substring(6);
618 var fieldname = query_client_server[clientname];
620 fieldname = clientname;
621 delete querys_server[fieldname];
622 onFormSubmitEventHandler();
623 showhide("recordview");
626 limitQueryServer(field, value);
627 //alert("limitOrResetQuerry: query after: " + document.search.query.value);
633 // limit by target functions
634 function limitTarget (id, name)
636 curFilter = 'pz:id=' + id;
640 showhide("recordview");
644 function delimitTarget ()
653 function limitOrResetTarget(id, name) {
654 if (id == 'reset_xt') {
658 limitTarget(id,name);
662 function drawPager (pagerDiv)
664 //client indexes pages from 1 but pz2 from 0
666 var pages = Math.ceil(totalRec / recPerPage);
668 var firstClkbl = ( curPage - onsides > 0 )
672 var lastClkbl = firstClkbl + 2*onsides < pages
673 ? firstClkbl + 2*onsides
676 var prev = '<span id="prev"><< Prev</span><b> | </b>';
678 var prev = '<a href="#" id="prev" onclick="pagerPrev();">'
679 +'<< Prev</a><b> | </b>';
682 for(var i = firstClkbl; i <= lastClkbl; i++) {
685 numLabel = '<b>' + i + '</b>';
687 middle += '<a href="#" onclick="showPage(' + i + ')"> '
688 + numLabel + ' </a>';
691 var next = '<b> | </b><span id="next">Next >></span>';
692 if (pages - curPage > 0)
693 var next = '<b> | </b><a href="#" id="next" onclick="pagerNext()">'
694 +'Next >></a>';
701 if (lastClkbl < pages)
704 pagerDiv.innerHTML += '<div style="float: none">'
705 + prev + predots + middle + postdots + next + '</div><hr/>';
708 function showPage (pageNum)
711 my_paz.showPage( curPage - 1 );
714 // simple paging functions
716 function pagerNext() {
717 if ( totalRec - recPerPage*curPage > 0) {
723 function pagerPrev() {
724 if ( my_paz.showPrev() != false )
728 // swithing view between targets and records
730 function switchView(view) {
732 var targets = document.getElementById('targetview');
733 var records = document.getElementById('recordview');
737 targets.style.display = "block";
738 records.style.display = "none";
741 targets.style.display = "none";
742 records.style.display = "block";
745 alert('Unknown view.');
749 // detailed record drawing
750 function showDetails (prefixRecId) {
751 var recId = prefixRecId.replace('rec_', '');
752 var oldRecId = curDetRecId;
755 // if the same clicked, just show it again
756 if (recId == oldRecId) {
757 showhide('detailview');
760 // request the record
761 my_paz.record(recId);
762 document.getElementById("loading").style.diplay = 'block';
765 function replaceHtml(el, html) {
766 var oldEl = typeof el === "string" ? document.getElementById(el) : el;
767 /*@cc_on // Pure innerHTML is slightly faster in IE
768 oldEl.innerHTML = html;
771 var newEl = oldEl.cloneNode(false);
772 newEl.innerHTML = html;
773 oldEl.parentNode.replaceChild(newEl, oldEl);
774 /* Since we just removed the old element from the DOM, return a reference
775 to the new element, which can be used to restore variable references. */
779 function renderDetails(data, marker)
781 var details = '<div class="details" id="det_'+data.recid+'"><table>';
782 if (marker) details += '<tr><td>'+ marker + '</td></tr>';
783 if (data["md-title"] != undefined) {
784 details += '<tr><td><b>Title</b></td><td><b>:</b> '+data["md-title"];
785 if (data["md-title-remainder"] != undefined) {
786 details += ' : <span>' + data["md-title-remainder"] + ' </span>';
788 if (data["md-author"] != undefined) {
789 details += ' <span><i>'+ data["md-auhtor"] +'</i></span>';
791 details += '</td></tr>';
793 if (data["md-date"] != undefined)
794 details += '<tr><td><b>Date</b></td><td><b>:</b> ' + data["md-date"] + '</td></tr>';
795 if (data["md-author"] != undefined)
796 details += '<tr><td><b>Author</b></td><td><b>:</b> ' + data["md-author"] + '</td></tr>';
797 if (data["md-electronic-url"] != undefined)
798 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>';
799 if (data["location"][0]["md-subject"] != undefined)
800 details += '<tr><td><b>Subject</b></td><td><b>:</b> ' + data["location"][0]["md-subject"] + '</td></tr>';
801 if (data["location"][0]["@name"] != undefined)
802 details += '<tr><td><b>Location</b></td><td><b>:</b> ' + data["location"][0]["@name"] + " (" +data["location"][0]["@id"] + ")" + '</td></tr>';
803 details += '</table></div>';
807 function renderLine(title, value) {
808 if (value != undefined)
809 return '<li><h3>' + title + '</h3> <big>' + value + '<br></big></li>';
813 function renderLines(title, values, name) {
815 result = '<li><h3>' + title + '</h3><big>';
816 if (values != undefined && values.length)
817 for (var idx = 0 ; idx < values.length ; idx++)
818 result += values[idx][name] + '<br>';
823 function renderLinesURL(title, values, name, url) {
825 result = '<li><h3>' + title + '</h3><big>';
826 if (values != undefined && values.length) {
827 for (var idx = 0 ; idx < values.length ; idx++) {
828 if (values[idx][url] != undefined)
829 result += '<a href="' + values[idx][url] + '">' + values[idx][name] + '</a><br>';
831 result += values[idx][name] + '<br>';
838 function renderLineURL(title, URL, display) {
839 if (URL != undefined)
840 return '<li><h3>' + title + '</h3> <a href="' + URL + '" target="_blank">' + display + '</a></li>';
844 function renderLineEmail(dtitle, email, display) {
845 if (email != undefined)
846 return '<li><h3>' + title + '</h3> <a href="mailto:' + email + '" target="_blank">' + display + '</a></li>';
850 function renderDetails_iphone(data, marker)
852 //return renderDetails(data,marker);
856 var details = '<div class="details" id="det_'+data.recid+'" >'
858 details = '<div id="header" id="det_'+data.recid+'">'
859 + '<h1>Detailed Info</h1>'
860 + '<a id="backbutton" href="hidedetail(\'det_' + data.recid + '\')">Back</a>'
864 details += '<h4>'+ marker + '</h4>';
865 details += '<ul class="field" >';
866 if (data["md-title"] != undefined) {
867 details += '<li><h3>Title</h3><big> ' + data["md-title"];
868 if (data["md-title-remainder"] != undefined) {
869 details += ' - ' + data["md-title-remainder"] + ' ';
872 if (data["md-author"] != undefined) {
873 details += '<i>'+ data["md-author"] +'</i>';
874 } else if (data["md-title-responsibility"] != undefined) {
875 details += '<i>'+ data["md-title-responsibility"] +'</i>';
882 +=renderLine('Date', data["md-date"])
883 + renderLine('Author', data["md-author"])
884 // + renderLineURL('URL', data["md-electronic-url"], data["md-electronic-url"])
885 + renderLine('Description', data["md-description"]);
886 + renderLines('Subjects', data["location"], "md-subject");
888 details += renderLinesURL('Location', data["location"], "@name", "md-url_recipe");
889 details += '</ul></div>';