]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/javascript/opac/MRResultPage.js
afbf3097a3783d6772b4ca07cb3dbd14e03d9ede
[Evergreen.git] / Open-ILS / src / javascript / opac / MRResultPage.js
1 var globalMRResultPage = null;                                  /* our global object */
2
3 MRResultPage.prototype                                  = new AbstractRecordResultPage();
4 MRResultPage.prototype.constructor      = MRResultPage;
5 MRResultPage.baseClass                                  = AbstractRecordResultPage.constructor;
6
7 /* constructor for our singleton object */
8 function MRResultPage() {
9         debug("MRResultPage()");
10         //this.searchBar = new SearchBarChunk();
11
12         if( globalMRResultPage != null ) {
13                 debug("MRResultPage() exists, returning");
14                 return globalMRResultPage;
15         }
16
17         //this.progressBar = new ProgressBar(getById('progress_bar'));
18         this.resetSearch();
19         globalMRResultPage = this;
20 }
21
22
23 /* returns the global instance. builds the instance if necessary.  All client
24  * code should use this method */
25 MRResultPage.instance = function() {
26         if( globalMRResultPage != null ) {
27                 return globalMRResultPage;
28         } 
29         return new MRResultPage();
30 }
31
32
33 MRResultPage.buildExtendedLinks = function(record, page_id) {
34         return null;
35 }
36
37
38 MRResultPage.prototype.setPageTrail = function() {
39
40         var box = getById("page_trail");
41         if(!box) return;
42
43         var d = this.buildTrailLink("start",true);
44         if(d) {
45                 box.appendChild(d);
46         } else {
47                 d = this.buildTrailLink("advanced_search", true);
48                 if(d)
49                         box.appendChild(d);
50         }
51
52         box.appendChild(this.buildDivider());
53         box.appendChild(
54                         this.buildTrailLink("mr_result", false));
55         
56 }
57
58
59 MRResultPage.prototype.next = function() {
60
61         var location = globalSelectedLocation;
62         if(location == null) 
63                 location = globalLocation.id();
64         else
65                 location = location.id();
66
67         /* if the user has changed the 'location' of the search, it will be
68                 reflected when the user hits the next button.  the search depth
69                 will not change, however, because that is a different search */
70         url_redirect( [ 
71                         "target",                                       "mr_result",
72                         "mr_search_type",                       this.stype,
73                         "mr_search_query",              this.string,
74                         "mr_search_location",   location,
75                         "mr_search_depth",              this.searchDepth,
76                         "format",                                       this.format, 
77                         "page",                                         this.page + 1   
78                         ] );
79 }
80
81
82 MRResultPage.prototype.prev = function() {
83         if(this.page == 0 ) return;
84
85
86         var depth = globalSearchDepth;
87         var location = globalSelectedLocation;
88         if(location == null) 
89                 location = globalLocation.id();
90         else
91                 location = location.id();
92
93         /* if the user has changed the 'location' of the search, it will be
94                 reflected when the user hits this  button.  the search depth
95                 will not change, however, because that is a different search */
96         url_redirect( [ 
97                         "target",                                       "mr_result",
98                         "mr_search_type",                       this.stype,
99                         "mr_search_query",              this.string,
100                         "mr_search_location",   location,
101                         "mr_search_depth",              this.searchDepth,
102                         "format",                                       this.format,
103                         "page",                                         this.page - 1   
104                         ] );
105 }
106
107
108 MRResultPage.prototype.addMenuItems = function(menu, record) {
109                 menu.addItem("View Metarecord Details", 
110                                                         function() { alert(record.doc_id()); });
111                 if(isXUL())
112                         xulEvtMRResultDisplayed( menu, record );
113 }
114
115 MRResultPage.prototype.URLRefresh = function() {
116
117         return [ 
118                                 "target",                                       "mr_result",
119                                 "mr_search_type",                       this.stype,
120                                 "mr_search_query",              this.string,
121                                 "mr_search_location",   this.searchLocation,
122                                 "mr_search_depth",              this.searchDepth,       
123                                 "format",                                       this.format,
124                                 "page",                                         0
125                                 ];
126 }
127
128 MRResultPage.prototype.mkLink = function(id, type, value, title) {
129
130         var href;
131
132         var t = title;
133         if(!t) t = value;
134
135         debug("Making link with title: " + t);
136
137         switch(type) {
138
139                 case "title":
140                         href = createAppElement("a");
141                         add_css_class(href,"record_result_title_link");
142                         href.setAttribute("href",
143                                 "?target=record_result&page=0&mrid=" + id + 
144                                 "&hits_per_page=" + this.hitsPerPage +
145                                 "&location=" + this.searchLocation +
146                                 "&format=" + this.format + 
147                                 "&depth=" + this.searchDepth );
148
149                         href.appendChild(createAppTextNode(value));
150                         href.title = "View titles for " + t + "";
151                         break;
152
153         case "img":
154                         href = createAppElement("a");
155                         add_css_class(href,"record_result_title_link");
156                         href.setAttribute("href",
157                                 "?target=record_result&page=0&mrid=" + id +
158                                 "&hits_per_page=" + this.hitsPerPage +
159                                 "&location=" + this.searchLocation +
160                                 "&format=" + this.format + 
161                                 "&depth=" + this.searchDepth );
162
163                         href.title = "View titles for " + t + "";
164                         break;
165
166
167                 case "author":
168                         href = createAppElement("a");
169                         add_css_class(href,"record_result_author_link");
170                         href.setAttribute("href",
171                                 "?target=mr_result&mr_search_type=author&page=0&mr_search_query=" +
172                              encodeURIComponent(value) + 
173                                         "&format=" + this.format );
174
175                         href.appendChild(createAppTextNode(value));
176                         href.title = "Author search for " + t + "";
177                         break;
178
179                 default:
180                         throw new EXArg("Unknown link type: " + type );
181         }
182
183         return href;
184 }
185
186
187
188 /* performs a new search */
189 MRResultPage.prototype.doSearch = function() {
190
191
192         debug("XUL IS " + isXUL() );
193
194         var string                      = paramObj.__mr_search_query;
195         var stype                       = paramObj.__mr_search_type;
196         var location            = paramObj.__mr_search_location;
197         var depth                       = paramObj.__mr_search_depth;
198         var hitsper                     = paramObj.__hits_per_page;
199         var format                      = paramObj.__format;
200
201         lastSearchString = string;
202         lastSearchType = stype;
203
204         if(hitsper)
205                 this.hitsPerPage = parseInt(hitsper);
206
207         debug("mr search params string " + string + " stype " + stype +
208                         " location " + location + " depth " + depth  + " format " + format);
209
210         if(depth == null || depth == "undefined")
211                 depth = globalSearchDepth;
212
213         if(depth == null)
214                 depth = findOrgDepth(globalLocation.ou_type());
215
216         if(location == null || location == "undefined") {
217                 if(globalSelectedLocation)
218                         location = globalSelectedLocation.id();
219                 else
220                         location = globalLocation.id();
221         }
222
223         if(!stype || !string) return;
224
225         if(this.searchDepth == null)
226                 this.searchDepth = globalSearchDepth;
227
228         /* see if this is a new search */
229         if(     isXUL()                                                                 || /* don't cache client searches */
230                         string != this.string                           || 
231                         stype != this.stype                                     ||
232                         this.searchLocation != location ||
233                         this.format != format                           || 
234                         this.searchDepth != depth ) {
235                 debug("Resetting MRSearch for search " + string);
236                 this.resetSearch();
237
238         } else {
239                 debug("Not Resetting MRSearch for search " + string);
240         }
241
242         this.searchDepth                = depth;
243         this.searchLocation     = location;
244         this.stype                              = stype;
245         this.string                             = string;
246         this.page                               = parseInt(paramObj.__page);
247         this.format                             = format;
248
249         if(this.page == null) this.page = 0;
250
251         this.searchOffset               = this.page * this.hitsPerPage;
252
253         this.resetPage();
254
255         var offset = parseInt(this.searchOffset);
256         var hitspp      = parseInt(this.hitsPerPage);
257
258         /* is this just a call to next/prev? */
259         if( this.recordIDs && this.recordIDs[offset] != null )  {
260                 debug("We have the first part of the ID's");
261                 if( this.recordIDs[offset + (hitspp -1 )] != null  ||
262                                 this.recordIDs[this.hitCount - 1] != null ) {
263                         /* we already have all of the IDS */
264                         debug("We alread have the required mr " + 
265                                         "ids for the search: [" + this.string + "]");
266                         this.collectRecords();
267                         return;
268                 }
269         }
270
271
272         debug("MRResultPage doSearch() with type: " 
273                         + this.stype + " and search [" + this.string + "]"
274                         + " and offset " + this.searchOffset  +
275                         " depth: " + depth + " location: " + location);
276
277         debug("gathering the search count\n");
278
279
280         if(this.searchOffset > 0 && this.hitCount > 0) {
281                 this.buildNextLinks();
282                 this.doMRSearch();
283
284         } else {
285
286                 var method = "open-ils.search.biblio.class.count";
287                 if(isXUL()) 
288                         method = method + ".staff";
289
290                 debug("Method: " + method);
291                 
292                 if(isNaN(this.searchDepth)) this.searchDepth = 0;
293                 if(isNaN(this.searchLocation)) this.searchLocation = 1;
294
295                 var form = this.format;
296                 if(this.format == "all") form = null;
297                 var creq = new RemoteRequest(
298                         "open-ils.search", method,
299                         this.stype, this.string, this.searchLocation, this.searchDepth, form );
300         
301                 /* this request grabs the search count.  When the counts come back
302                         the metarecord ids are collected */
303                 var obj = this;
304                 creq.setCompleteCallback(
305                         function(req) {
306
307                                 try {
308                                         obj.hitCount = req.getResultObject();   
309                                         debug("Received hit count of " + obj.hitCount );
310
311                                 } catch(E) {
312                                         if(instanceOf(E, ex)) {
313                                                 alert(E.err_msg());
314                                                 return;
315                                         }
316                                         else throw E;
317                                 }
318                                 
319                                 /*
320                                 var row = getById("hourglass_row");
321                                 if(row) row.parentNode.removeChild(row);
322                                 */
323
324                                 if(obj.hitCount > 0) obj.buildNextLinks();
325
326                                 /* do the spell check and make suggestion if possible */
327
328                                 else { 
329                                         var row = getById("hourglass_row");
330                                         if(row) row.parentNode.removeChild(row);
331                                         obj.noHits(); 
332                                         obj.checkSpelling();
333                                         return; 
334                                 }
335
336                                 obj.checkSpelling();
337
338         //                      obj.doMRSearch();       
339                         }
340                 );
341                 creq.send();
342
343                 this.doMRSearch();      
344         }
345 }
346
347
348 MRResultPage.prototype.checkSpelling = function() {
349         if(this.hitCount > 3) return;
350
351         debug("Checking spelling on " + this.string );
352
353         var request = new RemoteRequest(
354                 "open-ils.search",
355                 "open-ils.search.spell_check",
356                 this.string );
357         request.send(true);
358
359         var response = request.getResultObject();
360         if(response && response != "0") {
361
362                 debug("Received spell check response " + response );
363
364                 var dymb = getById("did_you_mean_box");
365                 dymb.appendChild(elem("br"));
366
367                 var ref = elem("a", 
368                         {
369                                 href: "?target=mr_result&mr_search_type=" + this.stype + 
370                                         "&page=0&mr_search_query=" + encodeURIComponent(response) +
371                                         "&format=" + this.format
372                         } 
373                 );
374
375                 add_css_class(ref,"record_result_author_link");
376                 ref.appendChild(createAppTextNode(response));
377                 ref.title = "Search for " + response + "";
378
379                 dymb.appendChild(createAppTextNode("Did you mean "));
380                 var ul = createAppElement("u");
381                 dymb.appendChild(ul);
382                 ul.appendChild(ref);
383                 dymb.appendChild(createAppTextNode("?"));
384         }
385 }
386
387 /* expand search if results are too low... */
388 MRResultPage.prototype.buildExpandSearchLinks = function() {
389
390         /*
391         var string                      = paramObj.__mr_search_query;
392         var stype                       = paramObj.__mr_search_type;
393         var location            = paramObj.__mr_search_location;
394         var depth                       = paramObj.__mr_search_depth;
395         */
396         
397         var div = elem("div");
398 }
399
400
401 MRResultPage.prototype.doMRSearch = function() {
402
403         var obj = this;
404         var method = "open-ils.search.biblio.class";
405
406         /* now the count and search are simultaneous 
407         if( this.hitCount > 5000 )
408                 method = method + ".unordered";
409                 */
410
411         if(isXUL())
412                 method = method + ".staff";
413
414         debug("Search method is " + method);
415
416         var form = this.format;
417         if(this.format == "all") form = null;
418
419         var request = new RemoteRequest( 
420                 "open-ils.search", method, obj.stype, obj.string, obj.searchLocation, 
421                 obj.searchDepth, "50", obj.searchOffset, form );
422         
423         request.setCompleteCallback(
424                 function(req) {
425
426                         var row = getById("hourglass_row");
427                         if(row)
428                                 row.parentNode.removeChild(row);
429
430                         var result = req.getResultObject();
431                         if(result == null) return;
432                         result.count = obj.hitCount;
433                         obj.gatherIDs(result) 
434                         obj.collectRecords();
435                         obj.requestBatch.remove(req);
436                 }
437         );
438         obj.requestBatch.add(request);
439         request.send();
440         debug("Sent mr id search");
441
442 }
443
444 MRResultPage.prototype.collectRecords = function() {
445
446         debug("Collecting records...");
447         var i = this.searchOffset;
448
449         var row = getById("hourglass_row");
450         if(row)
451                 row.parentNode.removeChild(row);
452
453         /* ------------------------------------------------- */
454
455         /*
456         var ids = new Array();
457         while( i < (this.searchOffset + this.hitsPerPage) ) 
458                 ids.push(this.recordIDs[i++]);
459
460         debug("Retrieving IDs " + ids);
461
462         var request = new RemoteRequest( "open-ils.search",
463                 "open-ils.search.biblio.metarecord.mods_slim.batch.retrieve", ids );
464         this.requestBatch.add(request);
465         var obj = this;
466
467
468         request.setCompleteCallback(
469                 function(req) {
470                         var records = req.getResultObject();
471                         //alert(records);
472
473                         for(var i = 0; i!= records.length; i++) {
474                                 var rec = records[i];
475                                 debug("Displaying recocord " + rec.doc_id());
476                                 obj.displayRecord( rec, obj.searchOffset, i );
477                                 obj.doCopyCount( rec, obj.searchOffset, i );
478                         }
479                         obj.requestBatch.remove(request);
480                 }
481         );              
482         request.send();
483         return;
484         */
485         /* ------------------------------------------------- */
486
487
488         while( i < (this.searchOffset + this.hitsPerPage) ) {
489                 var id = this.recordIDs[i];
490
491                 if(id==null){ i++;  continue; }
492
493                 var request = new RemoteRequest( "open-ils.search",
494                         "open-ils.search.biblio.metarecord.mods_slim.retrieve", id );
495                 this.requestBatch.add(request);
496                 debug( "Sending mods retrieval for metarecord " + id );
497
498                 request.name = "record_request_" + i;
499                 request.search_id = i;
500                 request.page_id = parseInt(i) - parseInt(this.searchOffset);
501
502                 /* define the callback for when we receive the record */
503                 var obj = this;
504                 request.setCompleteCallback(
505                         function(req) {
506                                 var record = req.getResultObject();
507                                 obj.displayRecord( record, req.search_id, req.page_id );
508                                 obj.doCopyCount( record, req.search_id, req.page_id );
509                                 obj.requestBatch.remove(req);
510                         }
511                 );
512
513                 debug("Sending mods retrieval request for " + id);
514                 request.send();
515                 i++;
516         }
517 }
518
519
520
521 MRResultPage.prototype.doCopyCount = function( record, search_id, page_id ) {
522
523         if(record==null || !record) return;
524
525         var copy_box    = getById("record_result_copy_count_box_" + page_id );
526
527         var orgunit = globalSelectedLocation;
528         if(!orgunit) orgunit = globalLocation;
529
530         var method = "open-ils.search.biblio.metarecord.copy_count";
531         if(isXUL())
532                 method = method + ".staff";
533
534         var copy_request = new RemoteRequest( 
535                 "open-ils.search", method,
536                 this.searchLocation, record.doc_id() );
537
538         copy_request.search_id = search_id;
539         copy_request.name = "copy_request_" + (search_id+this.searchOffset);
540
541         var obj = this;
542         copy_request.setCompleteCallback( 
543                 function(req) {
544                         try {   
545                                 obj.displayCopyCounts(req.getResultObject(), search_id, page_id );
546                         } catch(E) { 
547                                 debug("****** Copy Count Retrieval Error:\n" + E ); 
548                         }
549                 }
550         );
551
552         copy_request.send();
553 }
554
555