pz2.js:
authorJakub Skoczen <jakub@indexdata.dk>
Wed, 16 May 2007 07:53:31 +0000 (07:53 +0000)
committerJakub Skoczen <jakub@indexdata.dk>
Wed, 16 May 2007 07:53:31 +0000 (07:53 +0000)
        removed jquery dependency
        added xsl stylesheet support for detailed record view
        merged with pzQuery.js
        added pzHttpRequest class

client.js:
        updated to use the new library

js/pz2.js
www/masterkey/index.html
www/masterkey/js/client.js
www/masterkey/js/pzQuery.js [deleted file]

index 8d1e944..062e124 100644 (file)
--- a/js/pz2.js
+++ b/js/pz2.js
@@ -1,5 +1,5 @@
 /*
-** $Id: pz2.js,v 1.13 2007-05-14 12:57:43 jakub Exp $
+** $Id: pz2.js,v 1.14 2007-05-16 07:53:32 jakub Exp $
 ** pz2.js - pazpar2's javascript client library.
 */
 
@@ -19,10 +19,7 @@ if (!window['Node']) {
     Node.DOCUMENT_FRAGMENT_NODE = 11;
     Node.NOTATION_NODE = 12;
 }
-// check for jQuery
-if(typeof window.jQuery == "undefined"){
-    throw new Error("pz2.js requires jQuery library");
-}
+
 // prevent execution of more than once
 if(typeof window.pz2 == "undefined") {
 window.undefined = window.undefined;
@@ -31,12 +28,26 @@ var pz2 = function(paramArray) {
     //for convenience
     __myself = this;
 
+    //supported pazpar2's protocol version
+    __myself.suppProtoVer = '1';
+    __myself.pz2String = "search.pz2";
+    __myself.stylesheet = paramArray.detailstylesheet || null;
+
+    //load stylesheet if required in async mode
+    if( __myself.stylesheet ) {
+        var request = new pzHttpRequest( __myself.stylesheet );
+        request.get(
+                {},
+                function ( doc ) {
+                    __myself.xslDoc = doc;
+                }
+        );
+    }
+
     // at least one callback required
     if ( !paramArray )
         throw new Error("An array with parameters has to be suplied when instantiating a class");
-
-    //supported pazpar2's protocol version
-    __myself.suppProtoVer = '1';
+    
     __myself.errorHandler = paramArray.errorhandler || null;
     
     // function callbacks
@@ -51,7 +62,6 @@ var pz2 = function(paramArray) {
     __myself.termKeys = paramArray.termlist || "subject";
     
     // some configurational stuff
-    __myself.pz2String = "search.pz2";
     __myself.keepAlive = 50000;
 
     __myself.sessionID = null;
@@ -92,34 +102,6 @@ var pz2 = function(paramArray) {
     // active clients, updated by stat and show
     // might be an issue since bytarget will poll accordingly
     __myself.activeClients = 1;
-
-    // error handling
-    $(document).ajaxError( 
-    function (ajaxError, xhr, reqSettings, prevException)
-    {
-        if ( xhr.responseXML && xhr.responseXML.getElementsByTagName("error").length )
-       {
-           var errMsg = xhr.responseXML.getElementsByTagName("error")[0].childNodes[0].nodeValue;
-            var errCode = xhr.responseXML.getElementsByTagName("error")[0].getAttribute("code");
-            
-            var err = new Error(errMsg);
-            err.code = errCode;
-           
-            if (__myself.errorHandler) {
-                __myself.errorHandler(err);
-            }
-            else {
-                throw err;
-            }
-       }
-        // ensure the errors are propagated
-       else if (prevException != undefined ) {
-           throw prevException;
-        }
-        else {
-                throw new Error("XMLHttpRequest error. STATUS: " + xhr.status + " STATUS TEXT: " + xhr.statusText);
-        }
-    });
     
     // auto init session?
     if (paramArray.autoInit !== false)
@@ -137,8 +119,9 @@ pz2.prototype = {
         clearTimeout(__myself.showTimer);
         clearTimeout(__myself.termTimer);
         clearTimeout(__myself.bytargetTimer);
-
-        __myself.resetCallback();
+            
+        if ( __myself.resetCallback )
+                __myself.resetCallback();
     },
     init: function ( sessionId ) 
     {
@@ -149,7 +132,8 @@ pz2.prototype = {
             __myself.ping();
 
         } else {
-            $.get( __myself.pz2String,
+            var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+            request.get(
                 { "command": "init" },
                 function(data) {
                     if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
@@ -173,8 +157,8 @@ pz2.prototype = {
         if( !__myself.initStatusOK )
             return;
             // session is not initialized code here
-
-        $.get( __myself.pz2String,
+        var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+        request.get(
             { "command": "ping", "session": __myself.sessionID },
             function(data) {
                 if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
@@ -210,8 +194,8 @@ pz2.prototype = {
             var searchParams = { "command": "search", "session": __myself.sessionID, "query": __myself.currQuery, "filter": filter };
         else
             var searchParams = { "command": "search", "session": __myself.sessionID, "query": __myself.currQuery };
-
-        $.get( __myself.pz2String,
+        var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+        request.get(
             searchParams,
             function(data) {
                 if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
@@ -239,8 +223,8 @@ pz2.prototype = {
             return;
         // if called explicitly takes precedence
         clearTimeout(__myself.statTimer);
-
-        $.get( __myself.pz2String,
+        var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+        request.get(
             { "command": "stat", "session": __myself.sessionID },
             function(data) {
                 if ( data.getElementsByTagName("stat") ) {
@@ -282,8 +266,9 @@ pz2.prototype = {
             __myself.currentStart = Number( start );
         if( num !== undefined )
             __myself.currentNum = Number( num );
-        
-        $.get( __myself.pz2String,
+        var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+        var context = this;
+        request.get(
             { "command": "show", "session": __myself.sessionID, "start": __myself.currentStart,
               "num": __myself.currentNum, "sort": __myself.currentSort, "block": 1 },
             function(data) {
@@ -346,37 +331,43 @@ pz2.prototype = {
 
         if( id !== undefined )
             __myself.currRecID = id;
-
-        $.get( __myself.pz2String,
+        var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+        request.get(
             { "command": "record", "session": __myself.sessionID, "id": __myself.currRecID },
             function(data) {
                 var recordNode;
                 var record = new Array();
                 if ( recordNode = data.getElementsByTagName("record")[0] ) {
-                    for ( i = 0; i < recordNode.childNodes.length; i++) {
-                        if ( recordNode.childNodes[i].nodeType == Node.ELEMENT_NODE ) {
-                            var nodeName = recordNode.childNodes[i].nodeName;
-                            var nodeText = recordNode.childNodes[i].firstChild.nodeValue;
-                            record[nodeName] = nodeText;                            
+                    // if stylesheet was fetched do not parse the response
+                    if ( __myself.xslDoc ) {
+                        record['xmlDoc'] = data;
+                        record['xslDoc'] = __myself.xslDoc;
+                    } else {
+                        for ( i = 0; i < recordNode.childNodes.length; i++) {
+                            if ( recordNode.childNodes[i].nodeType == Node.ELEMENT_NODE ) {
+                                var nodeName = recordNode.childNodes[i].nodeName;
+                                var nodeText = recordNode.childNodes[i].firstChild.nodeValue;
+                                record[nodeName] = nodeText;                            
+                            }
                         }
-                    }
-                    // the location is hard coded
-                    var locationNodes = recordNode.getElementsByTagName("location");
-                    record["location"] = new Array();
-                    for ( i = 0; i < locationNodes.length; i++ ) {
-                        record["location"][i] = {
-                            "id": locationNodes[i].getAttribute("id"),
-                            "name": locationNodes[i].getAttribute("name")
-                        };
-                        for ( j = 0; j < locationNodes[i].childNodes.length; j++) {
-                            if ( locationNodes[i].childNodes[j].nodeType == Node.ELEMENT_NODE ) {
-                                var nodeName = locationNodes[i].childNodes[j].nodeName;
-                                var nodeText;
-                               if (locationNodes[i].childNodes[j].firstChild)
-                                       nodeText = locationNodes[i].childNodes[j].firstChild.nodeValue;
-                               else
-                                       nodeText = '';
-                                record["location"][i][nodeName] = nodeText;                            
+                        // the location is hard coded
+                        var locationNodes = recordNode.getElementsByTagName("location");
+                        record["location"] = new Array();
+                        for ( i = 0; i < locationNodes.length; i++ ) {
+                            record["location"][i] = {
+                                "id": locationNodes[i].getAttribute("id"),
+                                "name": locationNodes[i].getAttribute("name")
+                            };
+                            for ( j = 0; j < locationNodes[i].childNodes.length; j++) {
+                                if ( locationNodes[i].childNodes[j].nodeType == Node.ELEMENT_NODE ) {
+                                    var nodeName = locationNodes[i].childNodes[j].nodeName;
+                                    var nodeText;
+                                    if (locationNodes[i].childNodes[j].firstChild)
+                                            nodeText = locationNodes[i].childNodes[j].firstChild.nodeValue;
+                                    else
+                                            nodeText = '';
+                                    record["location"][i][nodeName] = nodeText;                            
+                                }
                             }
                         }
                     }
@@ -395,8 +386,8 @@ pz2.prototype = {
             return;
         // if called explicitly takes precedence
         clearTimeout(__myself.termTimer);
-
-        $.get( __myself.pz2String,
+        var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+        request.get(
             { "command": "termlist", "session": __myself.sessionID, "name": __myself.termKeys },
             function(data) {
                 if ( data.getElementsByTagName("termlist") ) {
@@ -441,8 +432,8 @@ pz2.prototype = {
             return;
         // if called explicitly takes precedence
         clearTimeout(__myself.bytargetTimer);
-
-        $.get( __myself.pz2String,
+        var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
+        request.get(
             { "command": "bytarget", "session": __myself.sessionID },
             function(data) {
                 if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
@@ -489,4 +480,226 @@ pz2.prototype = {
         __myself.show(pageNum * __myself.currentNum);
     }
 };
+
+/*
+*********************************************************************************
+** AJAX HELPER CLASS ************************************************************
+*********************************************************************************
+*/
+var pzHttpRequest = function ( url, errorHandler ) {
+        this.request = null;
+        this.url = url;
+        this.errorHandler = errorHandler || null;
+        
+        if ( window.XMLHttpRequest ) {
+            this.request = new XMLHttpRequest();
+        } else if ( window.ActiveXObject ) {
+            try {
+                this.request = new ActiveXObject( 'Msxml2.XMLHTTP' );
+            } catch (err) {
+                this.request = new ActiveXObject( 'Microsoft.XMLHTTP' );
+            }
+        }
+};
+
+pzHttpRequest.prototype = 
+{
+    get: function ( params, callback ) 
+    {
+        this.callback = callback;
+        
+        var paramArr = new Array();
+        for ( var key in params ) {
+            paramArr.push(key + '=' + escape(params[key]));
+        }
+
+        var context = this;
+        this.request.open( 'GET', this.url+'?'+paramArr.join('&'), true );
+        this.request.onreadystatechange = function () {
+            context._handleResponse();
+        }
+        this.request.send();
+    },
+
+    _handleResponse: function ()
+    {
+        if ( this.request.readyState == 4 ) {
+            if ( this.request.status == 200 ) {
+                this.callback( this.request.responseXML );
+            }
+            // pz errors
+            else if ( this.request.status == 417 ) {
+                var errMsg = this.request.responseXML.getElementsByTagName("error")[0].childNodes[0].nodeValue;
+                var errCode = this.request.responseXML.getElementsByTagName("error")[0].getAttribute("code");
+            
+                var err = new Error(errMsg);
+                err.code = errCode;
+           
+                if (this.errorHandler) {
+                    this.errorHandler(err);
+                }
+                else {
+                    throw err;
+                }
+            }
+            else {
+                var err = new Error("XMLHttpRequest error. STATUS: " 
+                            + this.request.status + " STATUS TEXT: " 
+                            + this.request.statusText );
+                err.code = 'HTTP';
+                
+                if (this.errorHandler) {
+                    this.errorHandler(err);
+                }
+                else {
+                    throw err;
+                }
+            }
+        }
+    }
+};
+
+/*
+*********************************************************************************
+** QUERY CLASS ******************************************************************
+*********************************************************************************
+*/
+var pzQuery = function()
+{
+    this.simpleQuery = '';
+    this.singleFilter = null;
+    this.advTerms = new Array();
+    this.filterHash = new Array();
+    this.numTerms = 0;
+    this.filterNums = 0;
+};
+pzQuery.prototype = {
+    reset: function()
+    {
+        this.simpleQuery = '';
+        this.advTerms = new Array();
+        this.simpleFilter = null;
+        this.numTerms = 0;
+    },
+    addTerm: function(field, value)
+    {
+        var term = {"field": field, "value": value};
+        this.advTerms[this.numTerms] = term;
+        this.numTerms++;
+    },
+    getTermValueByIdx: function(index)
+    {
+        return this.advTerms[index].value;
+    },
+    getTermFieldByIdx: function(index)
+    {
+        return this.advTerms[index].field;
+    },
+    /* semicolon separated list of terms for given field*/
+    getTermsByField: function(field)
+    {
+        var terms = '';
+        for(var i = 0; i < this.advTerms.length; i++)
+        {
+            if( this.advTerms[i].field == field )
+                terms = terms + this.queryHas[i].value + ';';
+        }
+        return terms;
+    },
+    addTermsFromList: function(inputString, field)
+    {
+        var inputArr = inputString.split(';');
+        for(var i=0; i < inputArr.length; i++)
+        {
+            if(inputArr[i].length < 3) continue;
+            this.advTerms[this.numTerms] = {"field": field, "value": inputArr[i] };
+            this.numTerms++;
+        }
+    },
+    removeTermByIdx: function(index)
+    {
+        this.advTerms.splice(index, 1);
+        this.numTerms--;
+    },
+    toCCL: function()
+    {   
+        var ccl = '';
+        if( this.simpleQuery != '')
+            ccl = '"'+this.simpleQuery+'"';
+        for(var i = 0; i < this.advTerms.length; i++)
+        {
+            if (ccl != '') ccl = ccl + ' and ';
+            ccl = ccl + this.advTerms[i].field+'="'+this.advTerms[i].value+'"';
+        }
+        return ccl;
+    },
+    addFilter: function(name, value)
+    {
+        var filter = {"name": name, "id": value };
+        this.filterHash[this.filterHash.length] = filter;
+        this.filterNums++
+        return  this.filterHash.length - 1;
+    },
+    setFilter: function(name, value)
+    {
+        this.filterHash = new Array();
+        this.filterNums = 0;
+        this.addFilter(name, value);
+    },
+    getFilter: function(index)
+    {
+        return this.filterHash[index].id;
+    },
+    getFilterName: function(index)
+    {
+        return this.filterHash[index].name;
+    },
+    removeFilter: function(index)
+    {
+        delete this.filterHash[index];
+        this.filterNums--;
+    },
+    clearFilter: function()
+    {
+        this.filterHash = new Array();
+        this.filterNums = 0;
+    },
+    getFilterString: function()
+    {
+        //temporary
+        if( this.singleFilter != null ) {
+            return 'pz:id='+this.singleFilter.id;
+        } 
+        else if( this.filterNums <= 0 ) {
+            return undefined;
+        }
+
+        var filter = 'pz:id=';
+        for(var i = 0; i < this.filterHash.length; i++)
+        {
+            if (this.filterHash[i] == undefined) continue;
+            if (filter > 'pz:id=') filter = filter + '|';            
+            filter += this.filterHash[i].id; 
+        }
+        return filter;
+    },
+    totalLength: function()
+    {
+        var simpleLength = this.simpleQuery != '' ? 1 : 0;
+        return this.advTerms.length + simpleLength;
+    },
+    clearSingleFilter: function()
+    {
+        this.singleFilter = null;
+    },
+    setSingleFilter: function(name, value)
+    {
+        this.singleFilter = {"name": name, "id": value };
+    },
+    getSingleFilterName: function()
+    {
+        return this.singleFilter.name;
+    }
+}
+
 }
index 98c56fa..faf4390 100755 (executable)
@@ -4,9 +4,8 @@
     <title>MasterKey Power Search</title>
     <link rel="author" href="http://www.indexdata.dk" />
     <link href="css/styles.css" rel="stylesheet" type="text/css" media="screen, all" />
-    <script type="text/javascript" src="js/jquery.pack.js"></script>
     <script type="text/javascript" src="js/pz2.js"></script>
-    <script type="text/javascript" src="js/pzQuery.js"></script>
+    <script type="text/javascript" src="js/jquery.pack.js"></script>
     <script type="text/javascript" src="js/client.js"></script>
   </head>
   <body>
index 9fb9412..d2e3985 100644 (file)
@@ -1,8 +1,18 @@
 /*
-** $Id: client.js,v 1.22 2007-04-30 14:28:09 quinn Exp $
+** $Id: client.js,v 1.23 2007-05-16 07:53:32 jakub Exp $
 ** MasterKey - pazpar2's javascript client .
 */
 
+// check for pz2.js
+if(typeof window.pz2 == "undefined"){
+    throw new Error("Client requires pz2.js library.");
+}
+
+// check for jQuery
+if(typeof window.jQuery == "undefined"){
+    throw new Error("Client requires requires jQuery library");
+}
+
 /* start with creating pz2 object and passing it event handlers*/
 var my_paz = new pz2({ 
                     "onshow": my_onshow,
@@ -61,8 +71,6 @@ function onFormSubmitEventHandler() {
     fireSearch();
     drawBreadcrumb();
     $('div.motd').empty();
-    $('div.content').show();
-    $("div.leftbar").show();
     return false;
 }
 
@@ -76,6 +84,8 @@ function my_errorhandler(err)
     switch (err.message) 
     {
         case 'QUERY': alert("Your query was not understood. Please rephrase."); break;
+        case 'NOTARGETS': alert("You are not allowed to search any targets."); break;
+        case 'HTTP': alert("There were problems with the connection."); break;
         default: alert(err.message);
     }
 }
@@ -86,6 +96,9 @@ function my_errorhandler(err)
 */
 function my_onshow(data)
 {
+    $('div.content').show();
+    $("div.leftbar").show();
+    
     var recsBody = $('div.records');
     recsBody.empty();
     
diff --git a/www/masterkey/js/pzQuery.js b/www/masterkey/js/pzQuery.js
deleted file mode 100644 (file)
index 62865ef..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-*********************************************************************************
-** QUERY CLASS ******************************************************************
-*********************************************************************************
-*/
-var pzQuery = function()
-{
-    this.simpleQuery = '';
-    this.singleFilter = null;
-    this.advTerms = new Array();
-    this.filterHash = new Array();
-    this.numTerms = 0;
-    this.filterNums = 0;
-};
-pzQuery.prototype = {
-    reset: function()
-    {
-        this.simpleQuery = '';
-        this.advTerms = new Array();
-        this.simpleFilter = null;
-        this.numTerms = 0;
-    },
-    addTerm: function(field, value)
-    {
-        var term = {"field": field, "value": value};
-        this.advTerms[this.numTerms] = term;
-        this.numTerms++;
-    },
-    getTermValueByIdx: function(index)
-    {
-        return this.advTerms[index].value;
-    },
-    getTermFieldByIdx: function(index)
-    {
-        return this.advTerms[index].field;
-    },
-    /* semicolon separated list of terms for given field*/
-    getTermsByField: function(field)
-    {
-        var terms = '';
-        for(var i = 0; i < this.advTerms.length; i++)
-        {
-            if( this.advTerms[i].field == field )
-                terms = terms + this.queryHas[i].value + ';';
-        }
-        return terms;
-    },
-    addTermsFromList: function(inputString, field)
-    {
-        var inputArr = inputString.split(';');
-        for(var i=0; i < inputArr.length; i++)
-        {
-            if(inputArr[i].length < 3) continue;
-            this.advTerms[this.numTerms] = {"field": field, "value": inputArr[i] };
-            this.numTerms++;
-        }
-    },
-    removeTermByIdx: function(index)
-    {
-        this.advTerms.splice(index, 1);
-        this.numTerms--;
-    },
-    toCCL: function()
-    {   
-        // TODO escape the characters
-        var ccl = '';
-        if( this.simpleQuery != '')
-            ccl = '"'+this.simpleQuery+'"';
-        for(var i = 0; i < this.advTerms.length; i++)
-        {
-            if (ccl != '') ccl = ccl + ' and ';
-            ccl = ccl + this.advTerms[i].field+'="'+this.advTerms[i].value+'"';
-        }
-        return ccl;
-    },
-    addFilter: function(name, value)
-    {
-        var filter = {"name": name, "id": value };
-        this.filterHash[this.filterHash.length] = filter;
-        this.filterNums++
-        return  this.filterHash.length - 1;
-    },
-    setFilter: function(name, value)
-    {
-        this.filterHash = new Array();
-        this.filterNums = 0;
-        this.addFilter(name, value);
-    },
-    getFilter: function(index)
-    {
-        return this.filterHash[index].id;
-    },
-    getFilterName: function(index)
-    {
-        return this.filterHash[index].name;
-    },
-    removeFilter: function(index)
-    {
-        delete this.filterHash[index];
-        this.filterNums--;
-    },
-    clearFilter: function()
-    {
-        this.filterHash = new Array();
-        this.filterNums = 0;
-    },
-    getFilterString: function()
-    {
-        //temporary
-        if( this.singleFilter != null ) {
-            return 'pz:id='+this.singleFilter.id;
-        } 
-        else if( this.filterNums <= 0 ) {
-            return undefined;
-        }
-
-        var filter = 'pz:id=';
-        for(var i = 0; i < this.filterHash.length; i++)
-        {
-            if (this.filterHash[i] == undefined) continue;
-            if (filter > 'pz:id=') filter = filter + '|';            
-            filter += this.filterHash[i].id; 
-        }
-        return filter;
-    },
-    totalLength: function()
-    {
-        var simpleLength = this.simpleQuery != '' ? 1 : 0;
-        return this.advTerms.length + simpleLength;
-    },
-    clearSingleFilter: function()
-    {
-        this.singleFilter = null;
-    },
-    setSingleFilter: function(name, value)
-    {
-        this.singleFilter = {"name": name, "id": value };
-    },
-    getSingleFilterName: function()
-    {
-        return this.singleFilter.name;
-    }
-}