2 ** $Id: client.js,v 1.23 2007-05-16 07:53:32 jakub Exp $
3 ** MasterKey - pazpar2's javascript client .
7 if(typeof window.pz2 == "undefined"){
8 throw new Error("Client requires pz2.js library.");
12 if(typeof window.jQuery == "undefined"){
13 throw new Error("Client requires requires jQuery library");
16 /* start with creating pz2 object and passing it event handlers*/
17 var my_paz = new pz2({
20 //"onstat": my_onstat,
22 "termlist": "xtargets,subject,author,date",
23 //"onbytarget": my_onbytarget,
24 "onrecord": my_onrecord,
25 "errorhandler": my_errorhandler
28 /* some state variable */
29 var currentSort = 'relevance';
30 var currentResultsPerPage = 20;
32 var curQuery = new pzQuery();
34 var currentDetailedId = null;
35 var currentDetailedData = null;
37 var termStartup = true;
38 var advancedOn = false;
40 var showBriefLocations = false;
42 /* wait until the DOM is ready and register basic handlers */
43 $(document).ready( function() {
44 document.search.onsubmit = onFormSubmitEventHandler;
46 document.search.query.value = '';
47 document.search.title.value = '';
48 document.search.author.value = '';
49 document.search.subject.value = '';
50 document.search.date.value = '';
52 $('#advanced').click(toggleAdvanced);
54 $('#sort').change(function(){
55 currentSort = this.value;
57 my_paz.show(0, currentResultsPerPage, currentSort);
60 $('#perpage').change(function(){
61 currentResultsPerPage = this.value;
63 my_paz.show(0, currentResultsPerPage, currentSort);
67 /* search button event handler */
68 function onFormSubmitEventHandler() {
70 curQuery.clearFilter();
73 $('div.motd').empty();
78 *********************************************************************************
79 ** pz2 Event Handlers ***********************************************************
80 *********************************************************************************
82 function my_errorhandler(err)
86 case 'QUERY': alert("Your query was not understood. Please rephrase."); break;
87 case 'NOTARGETS': alert("You are not allowed to search any targets."); break;
88 case 'HTTP': alert("There were problems with the connection."); break;
89 default: alert(err.message);
94 ** data.hits["md-title"], data.hits["md-author"], data.hits.recid, data.hits.count
95 ** data.activeclients, data.merged, data.total, data.start, data.num
97 function my_onshow(data)
99 $('div.content').show();
100 $("div.leftbar").show();
102 var recsBody = $('div.records');
105 for (var i = 0; i < data.hits.length; i++) {
106 var title = data.hits[i]["md-title"] || 'N/A';
107 var author = data.hits[i]["md-author"] || '';
108 var id = data.hits[i].recid;
109 var count = data.hits[i].count || 1;
111 var recBody = $('<div class="record" id="rec_'+id+'"></div>');
112 var aTitle = $('<a class="recTitle">'+title+'</a>').appendTo(recBody);
113 aTitle.click(function(){
114 var clickedId = this.parentNode.id.split('_')[1];
115 if(currentDetailedId == clickedId){
116 $(this.parentNode.lastChild).remove();
117 currentDetailedId = null;
119 } else if (currentDetailedId != null) {
120 $('#rec_'+currentDetailedId).children('.detail').remove();
122 currentDetailedId = clickedId;
123 my_paz.record(currentDetailedId);
127 recBody.append('<i> by </i>');
128 $('<a name="author" class="recAuthor">'+author+'</a>\n').click(function(){
129 refine("authoronly", this.firstChild.nodeValue) }).appendTo(recBody);
132 if( currentDetailedId == id ) {
133 var detailBox = $('<div class="detail"></div>').appendTo(recBody);
134 drawDetailedRec(detailBox);
137 if (showBriefLocations) {
138 var location = data.hits[i]['location'];
141 for (l in location) {
144 list += location[l].name;
146 recBody.append('<span> ('+list+')</span>');
150 recBody.append('<span> ('+count+')</span>');
154 recsBody.append('<div class="resultNum">'+(currentPage*currentResultsPerPage+i+1)+'.</a>');
155 recsBody.append(recBody);
157 drawPager(data.merged, data.total);
161 ** data.activeclients, data.hits, data.records, data.clients, data.searching
163 function my_onstat(data){}
166 ** data[listname]: name, freq, [id]
168 function my_onterm(data)
172 var termLists = $("#termlists");
174 for(var key in data){
175 if (key == "activeclients")
178 var listClass = "unselected";
180 if (key == "xtargets"){
181 listName = "resource";
182 listClass = "selected";
185 var termList = $('<div class="termlist" id="term_'+key+'"/>').appendTo(termLists);
186 var termTitle = $('<div class="termTitle"><a class="'+listClass+'">'+listName+'</a></div>').appendTo(termList);
187 termTitle.click(function(){
188 if( this.firstChild.className == "selected" ){
189 this.firstChild.className = "unselected";
190 $(this.nextSibling).hide();
192 this.firstChild.className = "selected";
193 $(this.nextSibling).show();
197 listEntries = $('<div class="termEntries"></div>');
198 if (key != "xtargets") listEntries.hide();
199 listEntries.appendTo(termList);
201 for(var i = 0; i < data[key].length; i++)
203 if (key == "xtargets"){
204 var listItem = $('<a class="sub" name="xtarget" value="'+data[key][i].id+'">'+data[key][i].name +'<span> ('+data[key][i].freq+')</span>'+'</a>');
205 listItem.click(function(){
206 refine(this.name, this.attributes[0].nodeValue, this.firstChild.nodeValue) });
207 listItem.appendTo(listEntries);
209 var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name
210 +'<span> ('+data[key][i].freq+')</span>'+'</a>');
211 listItem.click(function(){ refine(this.name, this.firstChild.nodeValue) });
212 listItem.appendTo(listEntries);
215 $('<hr/>').appendTo(termLists);
221 for(var key in data){
222 if (key == "activeclients")
224 var listEntries = $('#term_'+key).children('.termEntries');
225 if( data[key].length ) listEntries.empty();
227 for(var i = 0; i < data[key].length; i++){
228 if (key == "xtargets"){
229 var listItem = $('<a class="sub" name="xtarget" value="'+data[key][i].id+'">'+data[key][i].name+'<span> ('+data[key][i].freq+')</span>'+'</a>').click(function(){
230 refine(this.name, this.attributes[0].nodeValue, this.firstChild.nodeValue) });
231 listItem.appendTo(listEntries);
233 var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name
234 +'<span> ('+data[key][i].freq+')</span>'+'</a>').click(function(){
235 refine(this.name, this.firstChild.nodeValue) });
236 listItem.appendTo(listEntries);
244 ** data["md-title"], data["md-date"], data["md-author"], data["md-subject"], data["location"][0].name
246 function my_onrecord(data)
248 currentDetailedData = data;
253 ** data[i].id, data[i].hits, data[i].diagnostic, data[i].records, data[i].state
255 function my_onbytarget(data){}
258 *********************************************************************************
259 ** HELPER FUNCTIONS *************************************************************
260 *********************************************************************************
262 function fireSearch()
264 $('div.showing').empty().text('No records to show.');
265 $('div.pages').empty().html(' ');
266 $('div.records').empty();
267 currentDetailedId = null;
268 if( !curQuery.totalLength() )
270 my_paz.search(curQuery.toCCL(), currentResultsPerPage, currentSort, curQuery.getFilterString() );
273 function toggleAdvanced()
276 $("div.advanced").hide();
277 $("div.search").height(73);
279 $("#advanced").text("Advanced search");
281 $("div.search").height(173);
282 $("div.advanced").show();
284 $("#advanced").text("Simple search");
285 loadFormFieldsFromQuery();
289 function drawDetailedRec(detailBox)
291 if( detailBox == undefined )
292 detailBox = $('<div class="detail"></div>').appendTo($('#rec_'+currentDetailedId));
294 var detailTable = $('<table></table>');
295 var recLocation = currentDetailedData["location"];
299 hdtarget = $('<tr><td class="item" align="right">Available at: </td></tr>');
300 detailTable.append(hdtarget);
302 for(var i=0; i < recLocation.length; i++)
305 hdtarget = $('<tr><td class="item"> </td></tr>').appendTo(detailTable);
306 var url = recLocation[i]["md-url"];
307 var description = recLocation[i]["md-description"];
308 var date = recLocation[i]["md-date"];
309 var citation = recLocation[i]["md-citation"];
310 hdtarget.append('<td><b>'+recLocation[i].name+'</b></td>');
312 detailTable.append($('<tr><td align="right">Date: </td><td>'+date+'</td></tr>'));
314 detailTable.append($('<tr><td align="right" valign="top">Citation: </td><td>'+citation+'</td></tr>'));
316 detailTable.append($('<tr><td> </td><td>'+description+'</td></tr>'));
318 var tline = $('<tr><td> </td></tr>');
319 var td = $('<td></td>').appendTo(tline);
320 var tlink = $('<a>Go to resource</a>');
321 tlink.attr('href', url);;
322 tlink.attr('target', '_blank');
324 detailTable.append(tline);
326 hdtarget = undefined;
330 detailTable.appendTo(detailBox);
333 function refine(field, value, opt)
336 case "authoronly": curQuery.reset(); curQuery.addTerm('au', value); break;
337 case "author": curQuery.addTerm('au', value); break;
338 case "title": curQuery.addTerm('ti', value); break;
339 case "date": curQuery.addTerm('date', value); break;
340 case "subject": curQuery.addTerm('su', value); break;
341 case "xtarget": curQuery.setFilter(opt, value); break;
345 loadFormFieldsFromQuery();
352 function loadQueryFromForm()
355 curQuery.simpleQuery = document.search.query.value;
359 curQuery.addTermsFromList(document.search.author.value, 'au');
360 curQuery.addTermsFromList(document.search.title.value, 'ti');
361 curQuery.addTermsFromList(document.search.date.value, 'date');
362 curQuery.addTermsFromList(document.search.subject.value, 'su');
366 function loadFormFieldsFromQuery()
368 document.search.author.value = '';
369 document.search.title.value = '';
370 document.search.date.value = '';
371 document.search.subject.value = '';
373 for(var i = 0; i < curQuery.numTerms; i++)
375 switch( curQuery.getTermFieldByIdx(i) )
377 case "au": document.search.author.value += curQuery.getTermValueByIdx(i) + '; '; break;
378 case "ti": document.search.title.value += curQuery.getTermValueByIdx(i) + '; '; break;
379 case "date": document.search.date.value += curQuery.getTermValueByIdx(i) + '; '; break;
380 case "su": document.search.subject.value += curQuery.getTermValueByIdx(i) + '; '; break;
385 function drawPager(max, hits)
387 var firstOnPage = currentPage * currentResultsPerPage + 1;
388 var lastOnPage = (firstOnPage + currentResultsPerPage - 1) < max ? (firstOnPage + currentResultsPerPage - 1) : max;
390 var results = $('div.showing');
392 results.append('Displaying: <b>'+firstOnPage+'</b> to <b>'+lastOnPage+
393 '</b> of <b>'+max+'</b> (total hits: '+hits+')');
394 var pager = $('div.pages');
397 if ( currentPage > 0 ){
398 $('<a class="previous_active">Previous</a>').click(function() { my_paz.showPrev(1); currentPage--; }).appendTo(pager.eq(0));
399 $('<a class="previous_active">Previous</a>').click(function() { my_paz.showPrev(1); currentPage--; }).appendTo(pager.eq(1));
402 pager.append('<a class="previous_inactive">Previous</a>');
404 var numPages = Math.ceil(max / currentResultsPerPage);
406 var start = ( currentPage - 5 > 0 ? currentPage - 5 : 1 );
407 var stop = ( start + 12 < numPages ? start + 12 : numPages );
409 if (start > 1) $('<span>... </span>').appendTo(pager);
411 for(var i = start; i <= stop; i++)
413 if( i == (currentPage + 1) ){
414 $('<a class="select">'+i+'</a>').appendTo(pager);
417 var pageLink = $('<a class="page">'+i+'</a>');
418 var plClone = pageLink.clone();
420 pageLink.click(function() {
421 my_paz.showPage(this.firstChild.nodeValue - 1);
422 currentPage = (this.firstChild.nodeValue - 1);
425 plClone.click(function() {
426 my_paz.showPage(this.firstChild.nodeValue - 1);
427 currentPage = (this.firstChild.nodeValue - 1);
431 pager.eq(0).append(pageLink);
432 pager.eq(1).append(plClone);
435 if (stop < numPages) $('<span> ...</span>').appendTo(pager);
437 if ( currentPage < (numPages-1) ){
438 $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(0));
439 $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(1));
442 pager.append('<a class="next_inactive">Next</a>');
445 function drawBreadcrumb()
447 var bc = $("#breadcrumb");
450 if(curQuery.filterNums) $('<strong id="filter"><a>'+curQuery.getFilterName(0)+'</a>: </strong>').click(function() {
451 curQuery.removeFilter(0);
455 bc.append('<span>'+curQuery.simpleQuery+'</span>');
457 for(var i = 0; i < curQuery.numTerms; i++){
458 bc.append('<strong> + </strong>');
459 var bcLink = $('<a id="pos_'+i+'">'+curQuery.getTermValueByIdx(i)+'</a>').click(function() {
460 curQuery.removeTermByIdx(this.id.split('_')[1]);