Internal query handling completely rewritten.
[pazpar2-moved-to-github.git] / www / masterkey / js / client.js
index f1822ad..6a8683d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-** $Id: client.js,v 1.5 2007-03-28 15:20:53 jakub Exp $
+** $Id: client.js,v 1.10 2007-04-02 15:50:27 jakub Exp $
 ** MasterKey - pazpar2's javascript client .
 */
 
@@ -8,15 +8,19 @@ var my_paz = new pz2( { "onshow": my_onshow,
                     //"showtime": 1000,
                     //"onstat": my_onstat,
                     "onterm": my_onterm,
-                    "termlist": "subject,author,xtargets,date",
+                    "termlist": "xtargets,subject,author,date",
                     //"onbytarget": my_onbytarget,
                     "onrecord": my_onrecord } );
 
 /* some state variable */
 var currentSort = 'relevance';
 var currentResultsPerPage = 20;
-var currentQuery = null;
+/*var currentQuery = null;
+var currentQueryArr = new Array();*/
 var currentPage = 0;
+var curQuery = new pzQuery();
+/*var currentFilter = undefined;*/
+/*var currentFilterName = null;*/
 
 var currentDetailedId = null;
 var currentDetailedData = null;
@@ -51,9 +55,10 @@ $(document).ready( function() {
 
 /* search button event handler */
 function onFormSubmitEventHandler() {
-    if(!loadQueryFromForm())
-        return false;
-    my_paz.search(currentQuery, currentResultsPerPage, currentSort);
+    loadQueryFromForm();
+    curQuery.clearFilter();
+    fireSearch();
+    drawBreadcrumb();
     $('div.content').show();
     $("div.leftbar").show();
     return false;
@@ -95,15 +100,21 @@ function my_onshow(data)
                         my_paz.record(currentDetailedId);
                         });
         
-        if( author )
+        if( author ) {
             recBody.append('<i> by </i>');
-            $('<a name="author" class="recAuthor">'+author+'</a>\n').click(function(){ refine(this.name, this.firstChild.nodeValue) }).appendTo(recBody);
+            $('<a name="author" class="recAuthor">'+author+'</a>\n').click(function(){ 
+                            refine(this.name, this.firstChild.nodeValue) }).appendTo(recBody);
+        }
 
-        if( currentDetailedId == id ){
+        if( currentDetailedId == id ) {
             var detailBox = $('<div class="detail"></div>').appendTo(recBody);
             drawDetailedRec(detailBox);
         }
 
+        if( count > 1 ) {
+            recBody.append('<span> ('+count+')</span>');
+        }
+
         recsBody.append('<div class="resultNum">'+(currentPage*currentResultsPerPage+i+1)+'.</a>');
         recsBody.append(recBody);
     }
@@ -128,11 +139,15 @@ function my_onterm(data)
             if (key == "activeclients")
                 continue;
             var listName = key;
-            if (key == "xtargets")
+            var listClass = "unselected";
+
+            if (key == "xtargets"){
                 listName = "resource";
+                listClass = "selected";
+            }
 
             var termList = $('<div class="termlist" id="term_'+key+'"/>').appendTo(termLists);
-            var termTitle = $('<div class="termTitle"><a class="unselected">'+listName+'</a></div>').appendTo(termList);
+            var termTitle = $('<div class="termTitle"><a class="'+listClass+'">'+listName+'</a></div>').appendTo(termList);
             termTitle.click(function(){
                                 if( this.firstChild.className == "selected" ){
                                     this.firstChild.className = "unselected";
@@ -144,20 +159,22 @@ function my_onterm(data)
                             });
 
             listEntries = $('<div class="termEntries"></div>');
-            listEntries.hide();
+            if (key != "xtargets") listEntries.hide();
             listEntries.appendTo(termList);
 
             for(var i = 0; i < data[key].length; i++)
             {
                 if (key == "xtargets"){
-                    var listItem = $('<a class="sub" name="xtarget" value="'+data[key][i].id+'">'+data[key][i].name+
-                                '<span> ('+data[key][i].freq+')</span></a>').appendTo(listEntries);
+                    var listItem = $('<a class="sub" name="xtarget" value="'+data[key][i].id+'">'+data[key][i].name
+                            /*+'<span> ('+data[key][i].freq+')</span>'*/+'</a>');
                     listItem.click(function(){ 
-                        refine(this.name, this.attributes[0].nodeValue) });
+                        refine(this.name, this.attributes[0].nodeValue, this.firstChild.nodeValue) });
+                    listItem.appendTo(listEntries);
                 } else {
-                    var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name+
-                                    '<span> ('+data[key][i].freq+')</span></a>').appendTo(listEntries);
+                    var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name
+                            /*+'<span> ('+data[key][i].freq+')</span>'*/+'</a>');
                     listItem.click(function(){ refine(this.name, this.firstChild.nodeValue) });
+                    listItem.appendTo(listEntries);
                 }
             }        
             $('<hr/>').appendTo(termLists);
@@ -174,13 +191,13 @@ function my_onterm(data)
 
             for(var i = 0; i < data[key].length; i++){
                 if (key == "xtargets"){
-                    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(){ 
-                                                                        refine(this.name, this.attributes[0].nodeValue) });
+                    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(){ 
+                                    refine(this.name, this.attributes[0].nodeValue, this.firstChild.nodeValue) });
                     listItem.appendTo(listEntries);
                 } else {
-                    var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name+
-                                    '<span> ('+data[key][i].freq+')</span></a>').click(function(){ 
+                    var listItem = $('<a class="sub" name="'+key+'">'+data[key][i].name
+                                /*+'<span> ('+data[key][i].freq+')</span>'*/+'</a>').click(function(){ 
                                                                         refine(this.name, this.firstChild.nodeValue) });
                     listItem.appendTo(listEntries);
                 }
@@ -208,6 +225,16 @@ function my_onbytarget(data){}
 ** HELPER FUNCTIONS *************************************************************
 *********************************************************************************
 */
+function fireSearch()
+{
+    $('div.showing').empty().text('No records to show.');
+    $('div.pages').empty().html('&nbsp;');
+    $('div.records').empty();
+    if( !curQuery.totalLength() )
+        return false;
+    my_paz.search(curQuery.toCCL(), currentResultsPerPage, currentSort, curQuery.getFilterString() );
+}
+
 function toggleAdvanced()
 {
     if(advancedOn){
@@ -220,6 +247,7 @@ function toggleAdvanced()
         $("div.advanced").show();
         advancedOn = true;
         $("#advanced").text("Simple search");
+        loadFormFieldsFromQuery();
     }
 }
 
@@ -249,69 +277,55 @@ function drawDetailedRec(detailBox)
     detailTable.appendTo(detailBox);
 }
 
-function refine(field, value)
+function refine(field, value, opt)
 {
-    // for the time being
-    if(!advancedOn)
-        toggleAdvanced();
-
-    var query = '';
-    var filter = undefined;
-    
     switch(field) {
-        case "author":  query = ' and au="'+value+'"';
-                        if(document.search.author.value != '') document.search.author.value+='; ';
-                        document.search.author.value += value; break;
-
-        case "title":   query = ' and ti="'+value+'"';
-                        //if(document.search.tile.value != '') document.search.title.value+='; ';
-                        //document.search.title.value += value; break;
-        
-        case "date":    query = ' and date="'+value+'"';
-                        if(document.search.date.value != '') document.search.date.value+='; ';
-                        document.search.date.value += value; break;
-        
-        case "subject": query = ' and su="'+value+'"';
-                        if(document.search.subject.value != '') document.search.subject.value+='; ';
-                        document.search.subject.value += value; break;
-        
-        case "xtarget": filter = 'id='+value; break;
+        case "author":  curQuery.addTerm('au', value); break;
+        case "title":   curQuery.addTerm('ti', value); break;
+        case "date":    curQuery.addTerm('date', value); break;
+        case "subject": curQuery.addTerm('su', value); break;
+        case "xtarget": curQuery.setFilter(opt, value); break;
     }
 
+    if(advancedOn)
+        loadFormFieldsFromQuery();
+
     currentPage = 0;
-    currentQuery = currentQuery + query;
-    my_paz.search(currentQuery, currentResultsPerPage, currentSort, filter);    
+    drawBreadcrumb();
+    fireSearch();
 }
 
 function loadQueryFromForm()
 {
-    var query = new Array();
+    curQuery.reset();
+    curQuery.simpleQuery = document.search.query.value;
 
-    if( document.search.query.value !== '' ) query.push(document.search.query.value);    
-    if( document.search.author.value !== '' ) query.push(parseField(document.search.author.value, 'au'));
-    //if( document.search.title.value !== '' ) query.push(parseField(document.search.title.value, 'ti'));
-    if( document.search.date.value !== '' ) query.push(parseField(document.search.date.value, 'date'));
-    if( document.search.subject.value !== '' ) query.push(parseField(document.search.subject.value, 'su'));
-
-    if( query.length ) {
-        currentQuery = query.join(" and ");
-        return true;
-    } else {
-        return false;
+    if( advancedOn )
+    {
+        curQuery.addTermsFromList(document.search.author.value, 'au');
+        curQuery.addTermsFromList(document.search.title.value, 'ti');
+        curQuery.addTermsFromList(document.search.date.value, 'date');
+        curQuery.addTermsFromList(document.search.subject.value, 'su');
     }
 }
 
-function parseField(inputString, field)
+function loadFormFieldsFromQuery()
 {
-    var inputArr = inputString.split(';');
-    var outputArr = new Array();
-    for(var i=0; i < inputArr.length; i++){
-        if(inputArr[i].length < 3){
-            continue;
+    document.search.author.value = '';
+    document.search.title.value = '';
+    document.search.date.value = '';
+    document.search.subject.value = '';
+
+    for(var i = 0; i < curQuery.numTerms; i++)
+    {
+        switch( curQuery.getTermFieldByIdx(i) )
+        {
+            case "au": document.search.author.value += curQuery.getTermValueByIdx(i) + ';'; break;
+            case "ti": document.search.title.value += curQuery.getTermValueByIdx(i) + ';'; break;
+            case "date": document.search.date.value += curQuery.getTermValueByIdx(i) + ';'; break;
+            case "su": document.search.subject.value += curQuery.getTermValueByIdx(i) + ';'; break;
         }
-        outputArr.push(field+'="'+inputArr[i]+'"');
     }
-    return outputArr.join(" and ");
 }
 
 function drawPager(max, hits)
@@ -322,7 +336,7 @@ function drawPager(max, hits)
     var results = $('div.showing');
     results.empty();
     results.append('Displaying: <b>'+firstOnPage+'</b> to <b>'+lastOnPage+
-                            '</b> of <b>'+max+'</b>'); //(total hits: '+hits+')');
+                            '</b> of <b>'+max+'</b> (total hits: '+hits+')');
     var pager = $('div.pages');
     pager.empty();
     
@@ -334,8 +348,13 @@ function drawPager(max, hits)
         pager.append('<a class="previous_inactive">Previous</a>');
 
     var numPages = Math.ceil(max / currentResultsPerPage);
+
+    var start = ( currentPage - 5 > 0 ? currentPage - 5 : 1 );
+    var stop =  ( start + 12 < numPages ? start + 12 : numPages );
+
+    if (start > 1) $('<span>... </span>').appendTo(pager);
     
-    for(var i = 1; i <= numPages; i++)
+    for(var i = start; i <= stop; i++)
     {
         if( i == (currentPage + 1) ){
            $('<a class="select">'+i+'</a>').appendTo(pager);
@@ -359,6 +378,8 @@ function drawPager(max, hits)
         pager.eq(1).append(plClone);
     }
 
+    if (stop < numPages) $('<span> ...</span>').appendTo(pager);
+
     if ( currentPage < (numPages-1) ){
         $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(0));
         $('<a class="next_active">Next</a>').click(function() { my_paz.showNext(1); currentPage++; }).appendTo(pager.eq(1));
@@ -366,3 +387,25 @@ function drawPager(max, hits)
     else
         pager.append('<a class="next_inactive">Next</a>');
 }
+
+function drawBreadcrumb()
+{
+    var bc = $("#breadcrumb");
+    bc.empty();
+    
+    if(curQuery.filterNums) $('<strong id="filter"><a>'+curQuery.getFilterName(0)+'</a>: </strong>').click(function() {
+                                curQuery.removeFilter(0);
+                                refine();
+                                }).appendTo(bc);
+
+    bc.append('<span>'+curQuery.simpleQuery+'</span>');
+
+    for(var i = 0; i < curQuery.numTerms; i++){
+        bc.append('<strong> + </strong>');
+        var bcLink = $('<a id="pos_'+i+'">'+curQuery.getTermValueByIdx(i)+'</a>').click(function() { 
+                                            curQuery.removeTermByIdx(this.id.split('_')[1]);
+                                            refine(); 
+                                            });
+        bc.append(bcLink);
+    }
+}