2 ** $Id: client.js,v 1.22 2007-04-30 14:28:09 quinn Exp $
3 ** MasterKey - pazpar2's javascript client .
6 /* start with creating pz2 object and passing it event handlers*/
10 //"onstat": my_onstat,
12 "termlist": "xtargets,subject,author,date",
13 //"onbytarget": my_onbytarget,
14 "onrecord": my_onrecord,
15 "errorhandler": my_errorhandler
18 /* some state variable */
19 var currentSort = 'relevance';
20 var currentResultsPerPage = 20;
22 var curQuery = new pzQuery();
24 var currentDetailedId = null;
25 var currentDetailedData = null;
27 var termStartup = true;
28 var advancedOn = false;
30 var showBriefLocations = false;
32 /* wait until the DOM is ready and register basic handlers */
33 $(document).ready( function() {
34 document.search.onsubmit = onFormSubmitEventHandler;
36 document.search.query.value = '';
37 document.search.title.value = '';
38 document.search.author.value = '';
39 document.search.subject.value = '';
40 document.search.date.value = '';
42 $('#advanced').click(toggleAdvanced);
44 $('#sort').change(function(){
45 currentSort = this.value;
47 my_paz.show(0, currentResultsPerPage, currentSort);
50 $('#perpage').change(function(){
51 currentResultsPerPage = this.value;
53 my_paz.show(0, currentResultsPerPage, currentSort);
57 /* search button event handler */
58 function onFormSubmitEventHandler() {
60 curQuery.clearFilter();
63 $('div.motd').empty();
64 $('div.content').show();
65 $("div.leftbar").show();
70 *********************************************************************************
71 ** pz2 Event Handlers ***********************************************************
72 *********************************************************************************
74 function my_errorhandler(err)
78 case 'QUERY': alert("Your query was not understood. Please rephrase."); break;
79 default: alert(err.message);
84 ** data.hits["md-title"], data.hits["md-author"], data.hits.recid, data.hits.count
85 ** data.activeclients, data.merged, data.total, data.start, data.num
87 function my_onshow(data)
89 var recsBody = $('div.records');
92 for (var i = 0; i < data.hits.length; i++) {
93 var title = data.hits[i]["md-title"] || 'N/A';
94 var author = data.hits[i]["md-author"] || '';
95 var id = data.hits[i].recid;
96 var count = data.hits[i].count || 1;
98 var recBody = $('<div class="record" id="rec_'+id+'"></div>');
99 var aTitle = $('<a class="recTitle">'+title+'</a>').appendTo(recBody);
100 aTitle.click(function(){
101 var clickedId = this.parentNode.id.split('_')[1];
102 if(currentDetailedId == clickedId){
103 $(this.parentNode.lastChild).remove();
104 currentDetailedId = null;
106 } else if (currentDetailedId != null) {
107 $('#rec_'+currentDetailedId).children('.detail').remove();
109 currentDetailedId = clickedId;
110 my_paz.record(currentDetailedId);
114 recBody.append('<i> by </i>');
115 $('<a name="author" class="recAuthor">'+author+'</a>\n').click(function(){
116 refine("authoronly", this.firstChild.nodeValue) }).appendTo(recBody);
119 if( currentDetailedId == id ) {
120 var detailBox = $('<div class="detail"></div>').appendTo(recBody);
121 drawDetailedRec(detailBox);
124 if (showBriefLocations) {
125 var location = data.hits[i]['location'];
128 for (l in location) {
131 list += location[l].name;
133 recBody.append('<span> ('+list+')</span>');
137 recBody.append('<span> ('+count+')</span>');
141 recsBody.append('<div class="resultNum">'+(currentPage*currentResultsPerPage+i+1)+'.</a>');
142 recsBody.append(recBody);
144 drawPager(data.merged, data.total);
148 ** data.activeclients, data.hits, data.records, data.clients, data.searching
150 function my_onstat(data){}
153 ** data[listname]: name, freq, [id]
155 function my_onterm(data)
159 var termLists = $("#termlists");
161 for(var key in data){
162 if (key == "activeclients")
165 var listClass = "unselected";
167 if (key == "xtargets"){
168 listName = "resource";
169 listClass = "selected";
172 var termList = $('<div class="termlist" id="term_'+key+'"/>').appendTo(termLists);
173 var termTitle = $('<div class="termTitle"><a class="'+listClass+'">'+listName+'</a></div>').appendTo(termList);
174 termTitle.click(function(){
175 if( this.firstChild.className == "selected" ){
176 this.firstChild.className = "unselected";
177 $(this.nextSibling).hide();
179 this.firstChild.className = "selected";
180 $(this.nextSibling).show();
184 listEntries = $('<div class="termEntries"></div>');
185 if (key != "xtargets") listEntries.hide();
186 listEntries.appendTo(termList);
188 for(var i = 0; i < data[key].length; i++)
190 if (key == "xtargets"){
191 var listItem = $('<a class="sub" name="xtarget" value="'+data[key][i].id+'">'+data[key][i].name +'<span> ('+data[key][i].freq+')</span>'+'</a>');
192 listItem.click(function(){
193 refine(this.name, this.attributes[0].nodeValue, this.firstChild.nodeValue) });
194 listItem.appendTo(listEntries);
196 var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name
197 +'<span> ('+data[key][i].freq+')</span>'+'</a>');
198 listItem.click(function(){ refine(this.name, this.firstChild.nodeValue) });
199 listItem.appendTo(listEntries);
202 $('<hr/>').appendTo(termLists);
208 for(var key in data){
209 if (key == "activeclients")
211 var listEntries = $('#term_'+key).children('.termEntries');
212 if( data[key].length ) listEntries.empty();
214 for(var i = 0; i < data[key].length; i++){
215 if (key == "xtargets"){
216 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(){
217 refine(this.name, this.attributes[0].nodeValue, this.firstChild.nodeValue) });
218 listItem.appendTo(listEntries);
220 var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name
221 +'<span> ('+data[key][i].freq+')</span>'+'</a>').click(function(){
222 refine(this.name, this.firstChild.nodeValue) });
223 listItem.appendTo(listEntries);
231 ** data["md-title"], data["md-date"], data["md-author"], data["md-subject"], data["location"][0].name
233 function my_onrecord(data)
235 currentDetailedData = data;
240 ** data[i].id, data[i].hits, data[i].diagnostic, data[i].records, data[i].state
242 function my_onbytarget(data){}
245 *********************************************************************************
246 ** HELPER FUNCTIONS *************************************************************
247 *********************************************************************************
249 function fireSearch()
251 $('div.showing').empty().text('No records to show.');
252 $('div.pages').empty().html(' ');
253 $('div.records').empty();
254 currentDetailedId = null;
255 if( !curQuery.totalLength() )
257 my_paz.search(curQuery.toCCL(), currentResultsPerPage, currentSort, curQuery.getFilterString() );
260 function toggleAdvanced()
263 $("div.advanced").hide();
264 $("div.search").height(73);
266 $("#advanced").text("Advanced search");
268 $("div.search").height(173);
269 $("div.advanced").show();
271 $("#advanced").text("Simple search");
272 loadFormFieldsFromQuery();
276 function drawDetailedRec(detailBox)
278 if( detailBox == undefined )
279 detailBox = $('<div class="detail"></div>').appendTo($('#rec_'+currentDetailedId));
281 var detailTable = $('<table></table>');
282 var recLocation = currentDetailedData["location"];
286 hdtarget = $('<tr><td class="item" align="right">Available at: </td></tr>');
287 detailTable.append(hdtarget);
289 for(var i=0; i < recLocation.length; i++)
292 hdtarget = $('<tr><td class="item"> </td></tr>').appendTo(detailTable);
293 var url = recLocation[i]["md-url"];
294 var description = recLocation[i]["md-description"];
295 var date = recLocation[i]["md-date"];
296 var citation = recLocation[i]["md-citation"];
297 hdtarget.append('<td><b>'+recLocation[i].name+'</b></td>');
299 detailTable.append($('<tr><td align="right">Date: </td><td>'+date+'</td></tr>'));
301 detailTable.append($('<tr><td align="right" valign="top">Citation: </td><td>'+citation+'</td></tr>'));
303 detailTable.append($('<tr><td> </td><td>'+description+'</td></tr>'));
305 var tline = $('<tr><td> </td></tr>');
306 var td = $('<td></td>').appendTo(tline);
307 var tlink = $('<a>Go to resource</a>');
308 tlink.attr('href', url);;
309 tlink.attr('target', '_blank');
311 detailTable.append(tline);
313 hdtarget = undefined;
317 detailTable.appendTo(detailBox);
320 function refine(field, value, opt)
323 case "authoronly": curQuery.reset(); curQuery.addTerm('au', value); break;
324 case "author": curQuery.addTerm('au', value); break;
325 case "title": curQuery.addTerm('ti', value); break;
326 case "date": curQuery.addTerm('date', value); break;
327 case "subject": curQuery.addTerm('su', value); break;
328 case "xtarget": curQuery.setFilter(opt, value); break;
332 loadFormFieldsFromQuery();
339 function loadQueryFromForm()
342 curQuery.simpleQuery = document.search.query.value;
346 curQuery.addTermsFromList(document.search.author.value, 'au');
347 curQuery.addTermsFromList(document.search.title.value, 'ti');
348 curQuery.addTermsFromList(document.search.date.value, 'date');
349 curQuery.addTermsFromList(document.search.subject.value, 'su');
353 function loadFormFieldsFromQuery()
355 document.search.author.value = '';
356 document.search.title.value = '';
357 document.search.date.value = '';
358 document.search.subject.value = '';
360 for(var i = 0; i < curQuery.numTerms; i++)
362 switch( curQuery.getTermFieldByIdx(i) )
364 case "au": document.search.author.value += curQuery.getTermValueByIdx(i) + '; '; break;
365 case "ti": document.search.title.value += curQuery.getTermValueByIdx(i) + '; '; break;
366 case "date": document.search.date.value += curQuery.getTermValueByIdx(i) + '; '; break;
367 case "su": document.search.subject.value += curQuery.getTermValueByIdx(i) + '; '; break;
372 function drawPager(max, hits)
374 var firstOnPage = currentPage * currentResultsPerPage + 1;
375 var lastOnPage = (firstOnPage + currentResultsPerPage - 1) < max ? (firstOnPage + currentResultsPerPage - 1) : max;
377 var results = $('div.showing');
379 results.append('Displaying: <b>'+firstOnPage+'</b> to <b>'+lastOnPage+
380 '</b> of <b>'+max+'</b> (total hits: '+hits+')');
381 var pager = $('div.pages');
384 if ( currentPage > 0 ){
385 $('<a class="previous_active">Previous</a>').click(function() { my_paz.showPrev(1); currentPage--; }).appendTo(pager.eq(0));
386 $('<a class="previous_active">Previous</a>').click(function() { my_paz.showPrev(1); currentPage--; }).appendTo(pager.eq(1));
389 pager.append('<a class="previous_inactive">Previous</a>');
391 var numPages = Math.ceil(max / currentResultsPerPage);
393 var start = ( currentPage - 5 > 0 ? currentPage - 5 : 1 );
394 var stop = ( start + 12 < numPages ? start + 12 : numPages );
396 if (start > 1) $('<span>... </span>').appendTo(pager);
398 for(var i = start; i <= stop; i++)
400 if( i == (currentPage + 1) ){
401 $('<a class="select">'+i+'</a>').appendTo(pager);
404 var pageLink = $('<a class="page">'+i+'</a>');
405 var plClone = pageLink.clone();
407 pageLink.click(function() {
408 my_paz.showPage(this.firstChild.nodeValue - 1);
409 currentPage = (this.firstChild.nodeValue - 1);
412 plClone.click(function() {
413 my_paz.showPage(this.firstChild.nodeValue - 1);
414 currentPage = (this.firstChild.nodeValue - 1);
418 pager.eq(0).append(pageLink);
419 pager.eq(1).append(plClone);
422 if (stop < numPages) $('<span> ...</span>').appendTo(pager);
424 if ( currentPage < (numPages-1) ){
425 $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(0));
426 $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(1));
429 pager.append('<a class="next_inactive">Next</a>');
432 function drawBreadcrumb()
434 var bc = $("#breadcrumb");
437 if(curQuery.filterNums) $('<strong id="filter"><a>'+curQuery.getFilterName(0)+'</a>: </strong>').click(function() {
438 curQuery.removeFilter(0);
442 bc.append('<span>'+curQuery.simpleQuery+'</span>');
444 for(var i = 0; i < curQuery.numTerms; i++){
445 bc.append('<strong> + </strong>');
446 var bcLink = $('<a id="pos_'+i+'">'+curQuery.getTermValueByIdx(i)+'</a>').click(function() {
447 curQuery.removeTermByIdx(this.id.split('_')[1]);