b4de590eec4361985502c1ab116dab791fa4d948
[pazpar2-moved-to-github.git] / js / pz2.js
1 /*
2 ** $Id: pz2.js,v 1.34 2007-06-13 16:07:43 jakub Exp $
3 ** pz2.js - pazpar2's javascript client library.
4 */
5
6 //since explorer is flawed
7 if (!window['Node']) {
8     window.Node = new Object();
9     Node.ELEMENT_NODE = 1;
10     Node.ATTRIBUTE_NODE = 2;
11     Node.TEXT_NODE = 3;
12     Node.CDATA_SECTION_NODE = 4;
13     Node.ENTITY_REFERENCE_NODE = 5;
14     Node.ENTITY_NODE = 6;
15     Node.PROCESSING_INSTRUCTION_NODE = 7;
16     Node.COMMENT_NODE = 8;
17     Node.DOCUMENT_NODE = 9;
18     Node.DOCUMENT_TYPE_NODE = 10;
19     Node.DOCUMENT_FRAGMENT_NODE = 11;
20     Node.NOTATION_NODE = 12;
21 }
22
23 // prevent execution of more than once
24 if(typeof window.pz2 == "undefined") {
25 window.undefined = window.undefined;
26
27 var pz2 = function(paramArray) {
28     //for convenience
29     __myself = this;
30
31     //supported pazpar2's protocol version
32     __myself.suppProtoVer = '1';
33     __myself.pz2String = "search.pz2";
34     __myself.stylesheet = paramArray.detailstylesheet || null;
35
36     //load stylesheet if required in async mode
37     if( __myself.stylesheet ) {
38         var request = new pzHttpRequest( __myself.stylesheet );
39         request.get(
40                 {},
41                 function ( doc ) {
42                     __myself.xslDoc = doc;
43                 }
44         );
45     }
46
47     // at least one callback required
48     if ( !paramArray )
49         throw new Error("An array with parameters has to be suplied when instantiating a class");
50     
51     __myself.errorHandler = paramArray.errorhandler || null;
52     
53     // function callbacks
54     __myself.statCallback = paramArray.onstat || null;
55     __myself.showCallback = paramArray.onshow || null;
56     __myself.termlistCallback = paramArray.onterm || null;
57     __myself.recordCallback = paramArray.onrecord || null;
58     __myself.bytargetCallback = paramArray.onbytarget || null;
59     __myself.resetCallback = paramArray.onreset || null;
60
61     // termlist keys
62     __myself.termKeys = paramArray.termlist || "subject";
63     
64     // some configurational stuff
65     __myself.keepAlive = 50000;
66
67     __myself.sessionID = null;
68     __myself.initStatusOK = false;
69     __myself.pingStatusOK = false;
70     __myself.searchStatusOK = false;
71
72     if ( paramArray.keepAlive < __myself.keepAlive )
73         __myself.keepAlive = paramArray.keepAlive;
74
75     // for sorting
76     __myself.currentSort = "relevance";
77     // where are we?
78     __myself.currentStart = 0;
79     __myself.currentNum = 20;
80
81     // last full record retrieved
82     __myself.currRecID = null;
83     // current query
84     __myself.currQuery = null;
85
86     //timers
87     __myself.statTime = paramArray.stattime || 1000;
88     __myself.statTimer = null;
89     __myself.termTime = paramArray.termtime || 1000;
90     __myself.termTimer = null;
91     __myself.showTime = paramArray.showtime || 1000;
92     __myself.showTimer = null;
93     __myself.showFastCount = 4;
94     __myself.bytargetTime = paramArray.bytargettime || 1000;
95     __myself.bytargetTimer = null;
96
97     // counters for each command and applied delay
98     __myself.dumpFactor = 500;
99     __myself.showCounter = 0;
100     __myself.termCounter = 0;
101     __myself.statCounter = 0;
102     __myself.bytargetCounter = 0;
103
104     // active clients, updated by stat and show
105     // might be an issue since bytarget will poll accordingly
106     __myself.activeClients = 1;
107     
108     // auto init session?
109     if (paramArray.autoInit !== false)
110         __myself.init();
111 };
112 pz2.prototype = {
113     reset: function ()
114     {
115         __myself.sessionID = null;
116         __myself.initStatusOK = false;
117         __myself.pingStatusOK = false;
118         __myself.searchStatusOK = false;
119
120         clearTimeout(__myself.statTimer);
121         clearTimeout(__myself.showTimer);
122         clearTimeout(__myself.termTimer);
123         clearTimeout(__myself.bytargetTimer);
124             
125         if ( __myself.resetCallback )
126                 __myself.resetCallback();
127     },
128     init: function ( sessionId ) 
129     {
130         __myself.reset();
131         if ( sessionId != undefined ) {
132             __myself.initStatusOK = true;
133             __myself.sessionID = sessionId;
134             __myself.ping();
135
136         } else {
137             var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
138             request.get(
139                 { "command": "init" },
140                 function(data) {
141                     if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
142                         if ( data.getElementsByTagName("protocol")[0].childNodes[0].nodeValue != __myself.suppProtoVer )
143                             throw new Error("Server's protocol not supported by the client");
144                         __myself.initStatusOK = true;
145                         __myself.sessionID = data.getElementsByTagName("session")[0].childNodes[0].nodeValue;
146                         setTimeout("__myself.ping()", __myself.keepAlive);
147                     }
148                     else
149                         // if it gets here the http return code was 200 (pz2 errors are 417)
150                         // but the response was invalid, it should never occur
151                         setTimeout("__myself.init()", 1000);
152                 }
153             );
154         }
155     },
156     // no need to ping explicitly
157     ping: function () 
158     {
159         if( !__myself.initStatusOK )
160             return;
161             // session is not initialized code here
162         var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
163         request.get(
164             { "command": "ping", "session": __myself.sessionID },
165             function(data) {
166                 if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
167                     __myself.pingStatusOK = true;
168                     setTimeout("__myself.ping()", __myself.keepAlive);
169                 }
170                 else
171                     // if it gets here the http return code was 200 (pz2 errors are 417)
172                     // but the response was invalid, it should never occur
173                     setTimeout("__myself.ping()", 1000);
174             }
175         );
176     },
177     search: function (query, num, sort, filter)
178     {
179         clearTimeout(__myself.statTimer);
180         clearTimeout(__myself.showTimer);
181         clearTimeout(__myself.termTimer);
182         clearTimeout(__myself.bytargetTimer);
183         
184         __myself.showCounter = 0;
185         __myself.termCounter = 0;
186         __myself.bytargetCounter = 0;
187         __myself.statCounter = 0;
188         
189         if( !__myself.initStatusOK )
190             return;
191         
192         if( query !== undefined )
193             __myself.currQuery = query;
194         else
195             throw new Error("You need to supply query to the search command");
196
197         if( filter !== undefined )
198             var searchParams = { "command": "search", "session": __myself.sessionID, "query": __myself.currQuery, "filter": filter };
199         else
200             var searchParams = { "command": "search", "session": __myself.sessionID, "query": __myself.currQuery };
201         var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
202         request.get(
203             searchParams,
204             function(data) {
205                 if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
206                     __myself.searchStatusOK = true;
207                     //piggyback search
208                     __myself.show(0, num, sort);
209                     if ( __myself.statCallback )
210                         __myself.stat();
211                         //__myself.statTimer = setTimeout("__myself.stat()", __myself.statTime / 4);
212                     if ( __myself.termlistCallback )
213                         __myself.termlist();
214                         //__myself.termTimer = setTimeout("__myself.termlist()", __myself.termTime / 4);
215                     if ( __myself.bytargetCallback )
216                         __myself.bytarget();
217                         //__myself.bytargetTimer = setTimeout("__myself.bytarget()", __myself.bytargetTime / 4);
218                 }
219                 else
220                     // if it gets here the http return code was 200 (pz2 errors are 417)
221                     // but the response was invalid, it should never occur
222                     setTimeout("__myself.search(__myself.currQuery)", 500);
223             }
224         );
225     },
226     stat: function()
227     {
228         if( !__myself.initStatusOK )
229             return;
230         // if called explicitly takes precedence
231         clearTimeout(__myself.statTimer);
232         var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
233         request.get(
234             { "command": "stat", "session": __myself.sessionID },
235             function(data) {
236                 if ( data.getElementsByTagName("stat") ) {
237                     var activeClients = Number( data.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue );
238                     __myself.activeClients = activeClients;
239                     var stat = {
240                     "activeclients": activeClients,
241                     "hits": Number( data.getElementsByTagName("hits")[0].childNodes[0].nodeValue ),
242                     "records": Number( data.getElementsByTagName("records")[0].childNodes[0].nodeValue ),
243                     "clients": Number( data.getElementsByTagName("clients")[0].childNodes[0].nodeValue ),
244                     "initializing": Number( data.getElementsByTagName("initializing")[0].childNodes[0].nodeValue ),
245                     "searching": Number( data.getElementsByTagName("searching")[0].childNodes[0].nodeValue ),
246                     "presenting": Number( data.getElementsByTagName("presenting")[0].childNodes[0].nodeValue ),
247                     "idle": Number( data.getElementsByTagName("idle")[0].childNodes[0].nodeValue ),
248                     "failed": Number( data.getElementsByTagName("failed")[0].childNodes[0].nodeValue ),
249                     "error": Number( data.getElementsByTagName("error")[0].childNodes[0].nodeValue )
250                     };
251                     
252                     __myself.statCounter++;
253                     var delay = __myself.statTime + __myself.statCounter * __myself.dumpFactor;
254                     if ( activeClients > 0 )
255                         __myself.statTimer = setTimeout("__myself.stat()", delay);
256                     
257                     __myself.statCallback(stat);
258                 }
259                 else
260                     // if it gets here the http return code was 200 (pz2 errors are 417)
261                     // but the response was invalid, it should never occur
262                     __myself.statTimer = setTimeout("__myself.stat()", __myself.statTime / 4);
263             }
264         );
265     },
266     show: function(start, num, sort)
267     {
268         if( !__myself.searchStatusOK )
269             return;
270         // if called explicitly takes precedence
271         clearTimeout(__myself.showTimer);
272         
273         if( sort !== undefined )
274             __myself.currentSort = sort;
275         if( start !== undefined )
276             __myself.currentStart = Number( start );
277         if( num !== undefined )
278             __myself.currentNum = Number( num );
279         var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
280         var context = this;
281         request.get(
282             { "command": "show", "session": __myself.sessionID, "start": __myself.currentStart,
283               "num": __myself.currentNum, "sort": __myself.currentSort, "block": 1 },
284             function(data) {
285                 if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
286                     // first parse the status data send along with records
287                     // this is strictly bound to the format
288                     var activeClients = Number( data.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue );
289                     __myself.activeClients = activeClients; 
290                     var show = {
291                     "activeclients": activeClients,
292                     "merged": Number( data.getElementsByTagName("merged")[0].childNodes[0].nodeValue ),
293                     "total": Number( data.getElementsByTagName("total")[0].childNodes[0].nodeValue ),
294                     "start": Number( data.getElementsByTagName("start")[0].childNodes[0].nodeValue ),
295                     "num": Number( data.getElementsByTagName("num")[0].childNodes[0].nodeValue ),
296                     "hits": []
297                     };
298                     // parse all the first-level nodes for all <hit> tags
299                     var hits = data.getElementsByTagName("hit");
300                     var hit = new Array();
301                     for (i = 0; i < hits.length; i++) {
302                         show.hits[i] = new Array();
303                         show.hits[i]['location'] = new Array();
304                         for ( j = 0; j < hits[i].childNodes.length; j++) {
305                             var locCount = 0;
306                             if ( hits[i].childNodes[j].nodeType == Node.ELEMENT_NODE ) {
307                                 if (hits[i].childNodes[j].nodeName == 'location') {
308                                     var locNode = hits[i].childNodes[j];
309                                     var id = locNode.getAttribute('id');
310                                     show.hits[i]['location'][id] = {
311                                         "id": locNode.getAttribute("id"),
312                                         "name": locNode.getAttribute("name")
313                                     };
314                                 }
315                                 else {
316                                     var nodeName = hits[i].childNodes[j].nodeName;
317                                     var nodeText = 'ERROR'
318                                     if ( hits[i].childNodes[j].firstChild )
319                                         nodeText = hits[i].childNodes[j].firstChild.nodeValue;
320                                     show.hits[i][nodeName] = nodeText;
321                                 }
322                             }
323                         }
324                     }
325                     __myself.showCounter++;
326                     var delay = __myself.showTime;
327                     if (__myself.showCounter > __myself.showFastCount)
328                             delay += __myself.showCounter * __myself.dumpFactor;
329                     if ( activeClients > 0 )
330                         __myself.showTimer = setTimeout("__myself.show()", delay);
331
332                     __myself.showCallback(show);
333                 }
334                 else
335                     // if it gets here the http return code was 200 (pz2 errors are 417)
336                     // but the response was invalid, it should never occur
337                     __myself.showTimer = setTimeout("__myself.show()", __myself.showTime / 4);
338             }
339         );
340     },
341     record: function(id)
342     {
343         if( !__myself.searchStatusOK )
344             return;
345
346         if( id !== undefined )
347             __myself.currRecID = id;
348         var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
349         request.get(
350             { "command": "record", "session": __myself.sessionID, "id": __myself.currRecID },
351             function(data) {
352                 var recordNode;
353                 var record = new Array();
354                 if ( recordNode = data.getElementsByTagName("record")[0] ) {
355                     // if stylesheet was fetched do not parse the response
356                     if ( __myself.xslDoc ) {
357                         record['recid'] = recordNode.getElementsByTagName("recid")[0].firstChild.nodeValue;
358                         record['xmlDoc'] = data;
359                         record['xslDoc'] = __myself.xslDoc;
360                     } else {
361                         for ( i = 0; i < recordNode.childNodes.length; i++) {
362                             if ( recordNode.childNodes[i].nodeType == Node.ELEMENT_NODE
363                                     && recordNode.childNodes[i].nodeName != 'location' ) {
364                                 var nodeName = recordNode.childNodes[i].nodeName;
365                                 var nodeText = recordNode.childNodes[i].firstChild.nodeValue;
366                                 record[nodeName] = nodeText;                            
367                             }
368                         }
369                         // the location might be empty!!
370                         var locationNodes = recordNode.getElementsByTagName("location");
371                         record["location"] = new Array();
372                         for ( i = 0; i < locationNodes.length; i++ ) {
373                             record["location"][i] = {
374                                 "id": locationNodes[i].getAttribute("id"),
375                                 "name": locationNodes[i].getAttribute("name")
376                             };
377                             
378                             for ( j = 0; j < locationNodes[i].childNodes.length; j++) {
379                                 if ( locationNodes[i].childNodes[j].nodeType == Node.ELEMENT_NODE ) {
380                                     var nodeName = locationNodes[i].childNodes[j].nodeName;
381                                     var nodeText = '';
382                                     if (locationNodes[i].childNodes[j].firstChild)
383                                             nodeText = locationNodes[i].childNodes[j].firstChild.nodeValue;
384                                     record["location"][i][nodeName] = nodeText;                            
385                                 }
386                             }
387                         }
388                     }
389                     
390                     __myself.recordCallback(record);
391                 }
392                 else
393                     // if it gets here the http return code was 200 (pz2 errors are 417)
394                     // but the response was invalid, it should never occur
395                     setTimeout("__myself.record(__myself.currRecID)", 500);
396             }
397         );
398     },
399     termlist: function()
400     {
401         if( !__myself.searchStatusOK )
402             return;
403         // if called explicitly takes precedence
404         clearTimeout(__myself.termTimer);
405         var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
406         request.get(
407             { "command": "termlist", "session": __myself.sessionID, "name": __myself.termKeys },
408             function(data) {
409                 if ( data.getElementsByTagName("termlist") ) {
410                     var activeClients = Number( data.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue );
411                     __myself.activeClients = activeClients;
412                     var termList = { "activeclients":  activeClients };
413                     var termLists = data.getElementsByTagName("list");
414                     //for each termlist
415                     for (i = 0; i < termLists.length; i++) {
416                         var listName = termLists[i].getAttribute('name');
417                         termList[listName] = new Array();
418                         var terms = termLists[i].getElementsByTagName('term');
419                         //for each term in the list
420                         for (j = 0; j < terms.length; j++) { 
421                             var term = {
422                                 "name": (terms[j].getElementsByTagName("name")[0].childNodes.length 
423                                                 ? terms[j].getElementsByTagName("name")[0].childNodes[0].nodeValue
424                                                 : 'ERROR'),
425                                 "freq": terms[j].getElementsByTagName("frequency")[0].childNodes[0].nodeValue || 'ERROR'
426                             };
427
428                             var termIdNode = terms[j].getElementsByTagName("id");
429                             if(terms[j].getElementsByTagName("id").length)
430                                 term["id"] = termIdNode[0].childNodes[0].nodeValue;
431
432                             termList[listName][j] = term;
433                         }
434                     }
435
436                     __myself.termCounter++;
437                     var delay = __myself.termTime + __myself.termCounter * __myself.dumpFactor;
438                     if ( activeClients > 0 )
439                         __myself.termTimer = setTimeout("__myself.termlist()", delay);
440                    
441                    __myself.termlistCallback(termList);
442                 }
443                 else
444                     // if it gets here the http return code was 200 (pz2 errors are 417)
445                     // but the response was invalid, it should never occur
446                     __myself.termTimer = setTimeout("__myself.termlist()", __myself.termTime / 4); 
447             }
448         );
449
450     },
451     bytarget: function()
452     {
453         if( !__myself.searchStatusOK )
454             return;
455         // if called explicitly takes precedence
456         clearTimeout(__myself.bytargetTimer);
457         var request = new pzHttpRequest(__myself.pz2String, __myself.errorHandler);
458         request.get(
459             { "command": "bytarget", "session": __myself.sessionID },
460             function(data) {
461                 if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
462                     var targetNodes = data.getElementsByTagName("target");
463                     var bytarget = new Array();
464                     for ( i = 0; i < targetNodes.length; i++) {
465                         bytarget[i] = new Array();
466                         for( j = 0; j < targetNodes[i].childNodes.length; j++ ) {
467                             if ( targetNodes[i].childNodes[j].nodeType == Node.ELEMENT_NODE ) {
468                                 var nodeName = targetNodes[i].childNodes[j].nodeName;
469                                 var nodeText = targetNodes[i].childNodes[j].firstChild.nodeValue;
470                                 bytarget[i][nodeName] = nodeText;
471                             }
472                         }
473                     }
474                     
475                     __myself.bytargetCounter++;
476                     var delay = __myself.bytargetTime + __myself.bytargetCounter * __myself.dumpFactor;
477                     if ( __myself.activeClients > 0 )
478                         __myself.bytargetTimer = setTimeout("__myself.bytarget()", delay);
479
480                     __myself.bytargetCallback(bytarget);
481                 }
482                 else
483                     // if it gets here the http return code was 200 (pz2 errors are 417)
484                     // but the response was invalid, it should never occur
485                     __myself.bytargetTimer = setTimeout("__myself.bytarget()", __myself.bytargetTime / 4);
486             }
487         );
488     },
489     // just for testing, probably shouldn't be here
490     showNext: function(page)
491     {
492         var step = page || 1;
493         __myself.show( ( step * __myself.currentNum ) + __myself.currentStart );     
494     },
495     showPrev: function(page)
496     {
497         if (__myself.currentStart == 0 )
498             return false;
499         var step = page || 1;
500         var newStart = __myself.currentStart - (step * __myself.currentNum );
501         __myself.show( newStart > 0 ? newStart : 0 );
502     },
503     showPage: function(pageNum)
504     {
505         //var page = pageNum || 1;
506         __myself.show(pageNum * __myself.currentNum);
507     }
508 };
509
510 /*
511 *********************************************************************************
512 ** AJAX HELPER CLASS ************************************************************
513 *********************************************************************************
514 */
515 var pzHttpRequest = function ( url, errorHandler ) {
516         this.request = null;
517         this.url = url;
518         this.errorHandler = errorHandler || null;
519         this.async = true;
520         
521         if ( window.XMLHttpRequest ) {
522             this.request = new XMLHttpRequest();
523         } else if ( window.ActiveXObject ) {
524             try {
525                 this.request = new ActiveXObject( 'Msxml2.XMLHTTP' );
526             } catch (err) {
527                 this.request = new ActiveXObject( 'Microsoft.XMLHTTP' );
528             }
529         }
530 };
531
532 pzHttpRequest.prototype = 
533 {
534     get: function ( params, callback ) 
535     {
536         this._send( 'GET', params, null, callback );
537     },
538
539     post: function ( params, data, callback )
540     {
541         this._send( 'POST', params, data, callback );
542     },
543
544     _send: function ( type, params, data, callback )
545     {
546         this.callback = callback;
547         var context = this;
548         this.request.open( type, this._urlAppendParams(params), this.async );
549         //this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
550         this.request.onreadystatechange = function () {
551             context._handleResponse();
552         }
553         this.request.send(data);
554     },
555
556     _urlAppendParams: function (params)
557     {
558         var getUrl = this.url;
559         var paramArr = new Array();
560
561         for ( var key in params ) {
562             paramArr.push(key + '=' + encodeURI(params[key]) );
563         }
564
565         if ( paramArr.length )
566             getUrl += '?' + paramArr.join('&');
567
568         return getUrl;
569     },
570
571     _handleResponse: function ()
572     {
573         if ( this.request.readyState == 4 ) {
574             if ( this.request.status == 200 ) {
575                 this.callback( this.request.responseXML );
576             }
577             // pz errors
578             else if ( this.request.status == 417 ) {
579                 var errMsg = this.request.responseXML.getElementsByTagName("error")[0].childNodes[0].nodeValue;
580                 var errCode = this.request.responseXML.getElementsByTagName("error")[0].getAttribute("code");
581             
582                 var err = new Error(errMsg);
583                 err.code = errCode;
584             
585                 if (this.errorHandler) {
586                     this.errorHandler(err);
587                 }
588                 else {
589                     throw err;
590                 }
591             }
592             else {
593                 var err = new Error("XMLHttpRequest error. STATUS: " 
594                             + this.request.status + " STATUS TEXT: " 
595                             + this.request.statusText );
596                 err.code = 'HTTP';
597                 
598                 if (this.errorHandler) {
599                     this.errorHandler(err);
600                 }
601                 else {
602                     throw err;
603                 }
604             }
605         }
606     }
607 };
608
609 /*
610 *********************************************************************************
611 ** QUERY CLASS ******************************************************************
612 *********************************************************************************
613 */
614 var pzQuery = function()
615 {
616     this.simpleQuery = '';
617     this.singleFilter = null;
618     this.advTerms = new Array();
619     this.filterHash = new Array();
620     this.numTerms = 0;
621     this.filterNums = 0;
622 };
623 pzQuery.prototype = {
624     reset: function()
625     {
626         this.simpleQuery = '';
627         this.advTerms = new Array();
628         this.simpleFilter = null;
629         this.numTerms = 0;
630     },
631     addTerm: function(field, value)
632     {
633         var term = {"field": field, "value": value};
634         this.advTerms[this.numTerms] = term;
635         this.numTerms++;
636     },
637     getTermValueByIdx: function(index)
638     {
639         return this.advTerms[index].value;
640     },
641     getTermFieldByIdx: function(index)
642     {
643         return this.advTerms[index].field;
644     },
645     /* semicolon separated list of terms for given field*/
646     getTermsByField: function(field)
647     {
648         var terms = '';
649         for(var i = 0; i < this.advTerms.length; i++)
650         {
651             if( this.advTerms[i].field == field )
652                 terms = terms + this.queryHas[i].value + ';';
653         }
654         return terms;
655     },
656     addTermsFromList: function(inputString, field)
657     {
658         var inputArr = inputString.split(';');
659         for(var i=0; i < inputArr.length; i++)
660         {
661             if(inputArr[i].length < 3) continue;
662             this.advTerms[this.numTerms] = {"field": field, "value": inputArr[i] };
663             this.numTerms++;
664         }
665     },
666     removeTermByIdx: function(index)
667     {
668         this.advTerms.splice(index, 1);
669         this.numTerms--;
670     },
671     toCCL: function()
672     {   
673         var ccl = '';
674         if( this.simpleQuery != '')
675             ccl = this.simpleQuery;
676         for(var i = 0; i < this.advTerms.length; i++)
677         {
678             if (ccl != '') ccl = ccl + ' and ';
679             ccl = ccl + this.advTerms[i].field+'="'+this.advTerms[i].value+'"';
680         }
681         return ccl;
682     },
683     addFilter: function(name, value)
684     {
685         var filter = {"name": name, "id": value };
686         this.filterHash[this.filterHash.length] = filter;
687         this.filterNums++
688         return  this.filterHash.length - 1;
689     },
690     setFilter: function(name, value)
691     {
692         this.filterHash = new Array();
693         this.filterNums = 0;
694         this.addFilter(name, value);
695     },
696     getFilter: function(index)
697     {
698         return this.filterHash[index].id;
699     },
700     getFilterName: function(index)
701     {
702         return this.filterHash[index].name;
703     },
704     removeFilter: function(index)
705     {
706         delete this.filterHash[index];
707         this.filterNums--;
708     },
709     clearFilter: function()
710     {
711         this.filterHash = new Array();
712         this.filterNums = 0;
713     },
714     getFilterString: function()
715     {
716         //temporary
717         if( this.singleFilter != null ) {
718             return 'pz:id='+this.singleFilter.id;
719         } 
720         else if( this.filterNums <= 0 ) {
721             return undefined;
722         }
723
724         var filter = 'pz:id=';
725         for(var i = 0; i < this.filterHash.length; i++)
726         {
727             if (this.filterHash[i] == undefined) continue;
728             if (filter > 'pz:id=') filter = filter + '|';            
729             filter += this.filterHash[i].id; 
730         }
731         return filter;
732     },
733     totalLength: function()
734     {
735         var simpleLength = this.simpleQuery != '' ? 1 : 0;
736         return this.advTerms.length + simpleLength;
737     },
738     clearSingleFilter: function()
739     {
740         this.singleFilter = null;
741     },
742     setSingleFilter: function(name, value)
743     {
744         this.singleFilter = {"name": name, "id": value };
745     },
746     getSingleFilterName: function()
747     {
748         return this.singleFilter.name;
749     }
750 }
751
752 }