Advnced search view added.
[pazpar2-moved-to-github.git] / www / masterkey / js / client.js
1 /*
2 ** $Id: client.js,v 1.5 2007-03-28 15:20:53 jakub Exp $
3 ** MasterKey - pazpar2's javascript client .
4 */
5
6 /* start with creating pz2 object and passing it event handlers*/
7 var my_paz = new pz2( { "onshow": my_onshow,
8                     //"showtime": 1000,
9                     //"onstat": my_onstat,
10                     "onterm": my_onterm,
11                     "termlist": "subject,author,xtargets,date",
12                     //"onbytarget": my_onbytarget,
13                     "onrecord": my_onrecord } );
14
15 /* some state variable */
16 var currentSort = 'relevance';
17 var currentResultsPerPage = 20;
18 var currentQuery = null;
19 var currentPage = 0;
20
21 var currentDetailedId = null;
22 var currentDetailedData = null;
23
24 var termStartup = true;
25 var advancedOn = false;
26
27 /* wait until the DOM is ready and register basic handlers */
28 $(document).ready( function() { 
29                     document.search.onsubmit = onFormSubmitEventHandler;
30
31                     document.search.query.value = '';
32                     document.search.title.value = '';
33                     document.search.author.value = '';
34                     document.search.subject.value = '';
35                     document.search.date.value = '';
36                     
37                     $('#advanced').click(toggleAdvanced);
38
39                     $('#sort').change(function(){ 
40                         currentSort = this.value;
41                         currentPage = 0;
42                         my_paz.show(0, currentResultsPerPage, currentSort);
43                     });
44                     
45                     $('#perpage').change(function(){ 
46                         currentResultsPerPage = this.value;
47                         currentPage = 0;
48                         my_paz.show(0, currentResultsPerPage, currentSort);
49                     });
50 } );
51
52 /* search button event handler */
53 function onFormSubmitEventHandler() {
54     if(!loadQueryFromForm())
55         return false;
56     my_paz.search(currentQuery, currentResultsPerPage, currentSort);
57     $('div.content').show();
58     $("div.leftbar").show();
59     return false;
60 }
61
62 /*
63 *********************************************************************************
64 ** pz2 Event Handlers ***********************************************************
65 *********************************************************************************
66 */
67
68 /*
69 ** data.hits["md-title"], data.hits["md-author"], data.hits.recid, data.hits.count
70 ** data.activeclients, data.merged, data.total, data.start, data.num 
71 */
72 function my_onshow(data)
73 {
74     var recsBody = $('div.records');
75     recsBody.empty();
76     
77     for (var i = 0; i < data.hits.length; i++) {
78         var title = data.hits[i]["md-title"] || 'N/A';
79         var author = data.hits[i]["md-author"] || '';
80         var id = data.hits[i].recid;
81         var count = data.hits[i].count || 1;
82         
83         var recBody = $('<div class="record" id="rec_'+id+'"></div>');
84         var aTitle = $('<a class="recTitle">'+title+'</a>').appendTo(recBody);
85         aTitle.click(function(){
86                         var clickedId = this.parentNode.id.split('_')[1];
87                         if(currentDetailedId == clickedId){
88                             $(this.parentNode.lastChild).remove();
89                             currentDetailedId = null;
90                             return;
91                         } else if (currentDetailedId != null) {
92                             $('#rec_'+currentDetailedId).children('.detail').remove();
93                         }
94                         currentDetailedId = clickedId;
95                         my_paz.record(currentDetailedId);
96                         });
97         
98         if( author )
99             recBody.append('<i> by </i>');
100             $('<a name="author" class="recAuthor">'+author+'</a>\n').click(function(){ refine(this.name, this.firstChild.nodeValue) }).appendTo(recBody);
101
102         if( currentDetailedId == id ){
103             var detailBox = $('<div class="detail"></div>').appendTo(recBody);
104             drawDetailedRec(detailBox);
105         }
106
107         recsBody.append('<div class="resultNum">'+(currentPage*currentResultsPerPage+i+1)+'.</a>');
108         recsBody.append(recBody);
109     }
110     drawPager(data.merged, data.total);    
111 }
112
113 /*
114 ** data.activeclients, data.hits, data.records, data.clients, data.searching
115 */
116 function my_onstat(data){}
117
118 /*
119 ** data[listname]: name, freq, [id]
120 */
121 function my_onterm(data)
122 {
123     var termLists = $("#termlists");
124
125     if(termStartup)
126     {
127         for(var key in data){
128             if (key == "activeclients")
129                 continue;
130             var listName = key;
131             if (key == "xtargets")
132                 listName = "resource";
133
134             var termList = $('<div class="termlist" id="term_'+key+'"/>').appendTo(termLists);
135             var termTitle = $('<div class="termTitle"><a class="unselected">'+listName+'</a></div>').appendTo(termList);
136             termTitle.click(function(){
137                                 if( this.firstChild.className == "selected" ){
138                                     this.firstChild.className = "unselected";
139                                     $(this.nextSibling).hide();
140                                 } else {
141                                     this.firstChild.className = "selected";
142                                     $(this.nextSibling).show();
143                                 }
144                             });
145
146             listEntries = $('<div class="termEntries"></div>');
147             listEntries.hide();
148             listEntries.appendTo(termList);
149
150             for(var i = 0; i < data[key].length; i++)
151             {
152                 if (key == "xtargets"){
153                     var listItem = $('<a class="sub" name="xtarget" value="'+data[key][i].id+'">'+data[key][i].name+
154                                 '<span> ('+data[key][i].freq+')</span></a>').appendTo(listEntries);
155                     listItem.click(function(){ 
156                         refine(this.name, this.attributes[0].nodeValue) });
157                 } else {
158                     var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name+
159                                     '<span> ('+data[key][i].freq+')</span></a>').appendTo(listEntries);
160                     listItem.click(function(){ refine(this.name, this.firstChild.nodeValue) });
161                 }
162             }        
163             $('<hr/>').appendTo(termLists);
164         }
165         termStartup = false;
166     } 
167     else 
168     {
169         for(var key in data){
170             if (key == "activeclients")
171                 continue;
172             var listEntries = $('#term_'+key).children('.termEntries');
173             listEntries.empty()
174
175             for(var i = 0; i < data[key].length; i++){
176                 if (key == "xtargets"){
177                     var listItem = $('<a class="sub" name="xtarget" value="'+data[key][i].id+'">'+data[key][i].name+
178                                 '<span> ('+data[key][i].freq+')</span></a>').click(function(){ 
179                                                                         refine(this.name, this.attributes[0].nodeValue) });
180                     listItem.appendTo(listEntries);
181                 } else {
182                     var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name+
183                                     '<span> ('+data[key][i].freq+')</span></a>').click(function(){ 
184                                                                         refine(this.name, this.firstChild.nodeValue) });
185                     listItem.appendTo(listEntries);
186                 }
187             }         
188         }
189     }
190 }
191
192 /*
193 ** data["md-title"], data["md-date"], data["md-author"], data["md-subject"], data["location"][0].name
194 */
195 function my_onrecord(data)
196 {
197     currentDetailedData = data;
198     drawDetailedRec();
199 }
200
201 /*
202 ** data[i].id, data[i].hits, data[i].diagnostic, data[i].records, data[i].state
203 */
204 function my_onbytarget(data){}
205
206 /*
207 *********************************************************************************
208 ** HELPER FUNCTIONS *************************************************************
209 *********************************************************************************
210 */
211 function toggleAdvanced()
212 {
213     if(advancedOn){
214         $("div.advanced").hide();
215         $("div.search").height(73);
216         advancedOn = false;
217         $("#advanced").text("Advanced search");
218     } else {
219         $("div.search").height(173);
220         $("div.advanced").show();
221         advancedOn = true;
222         $("#advanced").text("Simple search");
223     }
224 }
225
226 function drawDetailedRec(detailBox)
227 {
228     if( detailBox == undefined )
229         detailBox = $('<div class="detail"></div>').appendTo($('#rec_'+currentDetailedId));
230     
231     detailBox.append('Details:<hr/>');
232     var detailTable = $('<table></table>');
233     var recDate = currentDetailedData["md-date"];
234     var recSubject = currentDetailedData["md-subject"];
235     var recLocation = currentDetailedData["location"];
236
237     if( recDate )
238         detailTable.append('<tr><td class="item">Published:</td><td>'+recDate+'</td></tr>');
239     if( recSubject )
240         detailTable.append('<tr><td class="item">Subject:</td><td>'+recSubject+'</td></tr>');
241     if( recLocation )
242         detailTable.append('<tr><td class="item">Available at:</td><td>&nbsp;</td></tr>');
243
244     for(var i=0; i < recLocation.length; i++)
245     {
246         detailTable.append('<tr><td class="item">&nbsp;</td><td>'+recLocation[i].name+'</td></tr>');
247     }
248
249     detailTable.appendTo(detailBox);
250 }
251
252 function refine(field, value)
253 {
254     // for the time being
255     if(!advancedOn)
256         toggleAdvanced();
257
258     var query = '';
259     var filter = undefined;
260     
261     switch(field) {
262         case "author":  query = ' and au="'+value+'"';
263                         if(document.search.author.value != '') document.search.author.value+='; ';
264                         document.search.author.value += value; break;
265
266         case "title":   query = ' and ti="'+value+'"';
267                         //if(document.search.tile.value != '') document.search.title.value+='; ';
268                         //document.search.title.value += value; break;
269         
270         case "date":    query = ' and date="'+value+'"';
271                         if(document.search.date.value != '') document.search.date.value+='; ';
272                         document.search.date.value += value; break;
273         
274         case "subject": query = ' and su="'+value+'"';
275                         if(document.search.subject.value != '') document.search.subject.value+='; ';
276                         document.search.subject.value += value; break;
277         
278         case "xtarget": filter = 'id='+value; break;
279     }
280
281     currentPage = 0;
282     currentQuery = currentQuery + query;
283     my_paz.search(currentQuery, currentResultsPerPage, currentSort, filter);    
284 }
285
286 function loadQueryFromForm()
287 {
288     var query = new Array();
289
290     if( document.search.query.value !== '' ) query.push(document.search.query.value);    
291     if( document.search.author.value !== '' ) query.push(parseField(document.search.author.value, 'au'));
292     //if( document.search.title.value !== '' ) query.push(parseField(document.search.title.value, 'ti'));
293     if( document.search.date.value !== '' ) query.push(parseField(document.search.date.value, 'date'));
294     if( document.search.subject.value !== '' ) query.push(parseField(document.search.subject.value, 'su'));
295
296     if( query.length ) {
297         currentQuery = query.join(" and ");
298         return true;
299     } else {
300         return false;
301     }
302 }
303
304 function parseField(inputString, field)
305 {
306     var inputArr = inputString.split(';');
307     var outputArr = new Array();
308     for(var i=0; i < inputArr.length; i++){
309         if(inputArr[i].length < 3){
310             continue;
311         }
312         outputArr.push(field+'="'+inputArr[i]+'"');
313     }
314     return outputArr.join(" and ");
315 }
316
317 function drawPager(max, hits)
318 {
319     var firstOnPage = currentPage * currentResultsPerPage + 1;
320     var lastOnPage = (firstOnPage + currentResultsPerPage - 1) < max ? (firstOnPage + currentResultsPerPage - 1) : max;
321
322     var results = $('div.showing');
323     results.empty();
324     results.append('Displaying: <b>'+firstOnPage+'</b> to <b>'+lastOnPage+
325                             '</b> of <b>'+max+'</b>'); //(total hits: '+hits+')');
326     var pager = $('div.pages');
327     pager.empty();
328     
329     if ( currentPage > 0 ){
330         $('<a class="previous_active">Previous</a>').click(function() { my_paz.showPrev(1); currentPage--; }).appendTo(pager.eq(0));
331         $('<a class="previous_active">Previous</a>').click(function() { my_paz.showPrev(1); currentPage--; }).appendTo(pager.eq(1));
332     }
333     else
334         pager.append('<a class="previous_inactive">Previous</a>');
335
336     var numPages = Math.ceil(max / currentResultsPerPage);
337     
338     for(var i = 1; i <= numPages; i++)
339     {
340         if( i == (currentPage + 1) ){
341            $('<a class="select">'+i+'</a>').appendTo(pager);
342            continue;
343         }
344         var pageLink = $('<a class="page">'+i+'</a>');
345         var plClone = pageLink.clone();
346
347         pageLink.click(function() { 
348             my_paz.showPage(this.firstChild.nodeValue - 1);
349             currentPage = (this.firstChild.nodeValue - 1);
350             });
351
352         plClone.click(function() { 
353             my_paz.showPage(this.firstChild.nodeValue - 1);
354             currentPage = (this.firstChild.nodeValue - 1);
355             });
356
357         //nasty hack
358         pager.eq(0).append(pageLink);
359         pager.eq(1).append(plClone);
360     }
361
362     if ( currentPage < (numPages-1) ){
363         $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(0));
364         $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(1));
365     }
366     else
367         pager.append('<a class="next_inactive">Next</a>');
368 }