]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/javascript/opac/MRResultPage.js
e6260af95b09fce029aa1510200d452c7c0ada0a
[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                                 "&depth=" + this.searchDepth );
147
148                         href.appendChild(createAppTextNode(value));
149                         href.title = "View titles for " + t + "";
150                         break;
151
152         case "img":
153                         href = createAppElement("a");
154                         add_css_class(href,"record_result_title_link");
155                         href.setAttribute("href",
156                                 "?target=record_result&page=0&mrid=" + id +
157                                 "&hits_per_page=" + this.hitsPerPage +
158                                 "&location=" + this.searchLocation +
159                                 "&depth=" + this.searchDepth );
160
161                         href.title = "View titles for " + t + "";
162                         break;
163
164
165                 case "author":
166                         href = createAppElement("a");
167                         add_css_class(href,"record_result_author_link");
168                         href.setAttribute("href",
169                                 "?target=mr_result&mr_search_type=author&page=0&mr_search_query=" +
170                              encodeURIComponent(value));
171                         href.appendChild(createAppTextNode(value));
172                         href.title = "Author search for " + t + "";
173                         break;
174
175                 default:
176                         throw new EXArg("Unknown link type: " + type );
177         }
178
179         return href;
180 }
181
182
183
184 /* performs a new search */
185 MRResultPage.prototype.doSearch = function() {
186
187
188         debug("XUL IS " + isXUL() );
189
190         var string                      = paramObj.__mr_search_query;
191         var stype                       = paramObj.__mr_search_type;
192         var location            = paramObj.__mr_search_location;
193         var depth                       = paramObj.__mr_search_depth;
194         var hitsper                     = paramObj.__hits_per_page;
195         var format                      = paramObj.__format;
196
197         lastSearchString = string;
198         lastSearchType = stype;
199
200         if(hitsper)
201                 this.hitsPerPage = parseInt(hitsper);
202
203         debug("mr search params string " + string + " stype " + stype +
204                         " location " + location + " depth " + depth  + " format " + format);
205
206         if(depth == null || depth == "undefined")
207                 depth = globalSearchDepth;
208
209         if(depth == null)
210                 depth = findOrgDepth(globalLocation.ou_type());
211
212         if(location == null || location == "undefined") {
213                 if(globalSelectedLocation)
214                         location = globalSelectedLocation.id();
215                 else
216                         location = globalLocation.id();
217         }
218
219         if(!stype || !string) return;
220
221         if(this.searchDepth == null)
222                 this.searchDepth = globalSearchDepth;
223
224         /* see if this is a new search */
225         if(     isXUL()                                                                 || /* don't cache client searches */
226                         string != this.string                           || 
227                         stype != this.stype                                     ||
228                         this.searchLocation != location ||
229                         this.format != format                           || 
230                         this.searchDepth != depth ) {
231                 debug("Resetting MRSearch for search " + string);
232                 this.resetSearch();
233
234         } else {
235                 debug("Not Resetting MRSearch for search " + string);
236         }
237
238         this.searchDepth                = depth;
239         this.searchLocation     = location;
240         this.stype                              = stype;
241         this.string                             = string;
242         this.page                               = parseInt(paramObj.__page);
243         this.format                             = format;
244
245         if(this.page == null) this.page = 0;
246
247         this.searchOffset               = this.page * this.hitsPerPage;
248
249         this.resetPage();
250
251         var offset = parseInt(this.searchOffset);
252         var hitspp      = parseInt(this.hitsPerPage);
253
254         /* is this just a call to next/prev? */
255         if( this.recordIDs && this.recordIDs[offset] != null )  {
256                 debug("We have the first part of the ID's");
257                 if( this.recordIDs[offset + (hitspp -1 )] != null  ||
258                                 this.recordIDs[this.hitCount - 1] != null ) {
259                         /* we already have all of the IDS */
260                         debug("We alread have the required mr " + 
261                                         "ids for the search: [" + this.string + "]");
262                         this.collectRecords();
263                         return;
264                 }
265         }
266
267
268         debug("MRResultPage doSearch() with type: " 
269                         + this.stype + " and search [" + this.string + "]"
270                         + " and offset " + this.searchOffset  +
271                         " depth: " + depth + " location: " + location);
272
273         debug("gathering the search count\n");
274
275
276         if(this.searchOffset > 0 && this.hitCount > 0) {
277                 this.buildNextLinks();
278                 this.doMRSearch();
279
280         } else {
281
282                 var method = "open-ils.search.biblio.class.count";
283                 if(isXUL()) 
284                         method = method + ".staff";
285
286                 debug("Method: " + method);
287                 
288                 if(isNaN(this.searchDepth)) this.searchDepth = 0;
289                 if(isNaN(this.searchLocation)) this.searchLocation = 1;
290
291                 var form = this.format;
292                 if(this.format == "all") form = null;
293                 var creq = new RemoteRequest(
294                         "open-ils.search", method,
295                         this.stype, this.string, this.searchLocation, this.searchDepth, form );
296         
297                 /* this request grabs the search count.  When the counts come back
298                         the metarecord ids are collected */
299                 var obj = this;
300                 creq.setCompleteCallback(
301                         function(req) {
302
303                                 try {
304                                         obj.hitCount = req.getResultObject();   
305                                         debug("Received hit count of " + obj.hitCount );
306
307                                 } catch(E) {
308                                         if(instanceOf(E, ex)) {
309                                                 alert(E.err_msg());
310                                                 return;
311                                         }
312                                         else throw E;
313                                 }
314                                 
315                                 /*
316                                 var row = getById("hourglass_row");
317                                 if(row) row.parentNode.removeChild(row);
318                                 */
319
320                                 if(obj.hitCount > 0) obj.buildNextLinks();
321
322                                 /* do the spell check and make suggestion if possible */
323
324                                 else { 
325                                         var row = getById("hourglass_row");
326                                         if(row) row.parentNode.removeChild(row);
327                                         obj.noHits(); 
328                                         obj.checkSpelling();
329                                         return; 
330                                 }
331
332                                 obj.checkSpelling();
333
334         //                      obj.doMRSearch();       
335                         }
336                 );
337                 creq.send();
338
339                 this.doMRSearch();      
340         }
341 }
342
343
344 MRResultPage.prototype.checkSpelling = function() {
345         if(this.hitCount > 3) return;
346
347         debug("Checking spelling on " + this.string );
348
349         var request = new RemoteRequest(
350                 "open-ils.search",
351                 "open-ils.search.spell_check",
352                 this.string );
353         request.send(true);
354
355         var response = request.getResultObject();
356         if(response && response != "0") {
357
358                 debug("Received spell check response " + response );
359
360                 var dymb = getById("did_you_mean_box");
361                 dymb.appendChild(elem("br"));
362
363                 var ref = elem("a", 
364                         {
365                                 href: "?target=mr_result&mr_search_type=" + 
366                                         this.stype + "&page=0&mr_search_query=" +
367                                         encodeURIComponent(response)
368                         } 
369                 );
370
371                 add_css_class(ref,"record_result_author_link");
372                 ref.appendChild(createAppTextNode(response));
373                 ref.title = "Search for " + response + "";
374
375                 dymb.appendChild(createAppTextNode("Did you mean "));
376                 var ul = createAppElement("u");
377                 dymb.appendChild(ul);
378                 ul.appendChild(ref);
379                 dymb.appendChild(createAppTextNode("?"));
380         }
381 }
382
383 /* expand search if results are too low... */
384 MRResultPage.prototype.buildExpandSearchLinks = function() {
385
386         /*
387         var string                      = paramObj.__mr_search_query;
388         var stype                       = paramObj.__mr_search_type;
389         var location            = paramObj.__mr_search_location;
390         var depth                       = paramObj.__mr_search_depth;
391         */
392         
393         var div = elem("div");
394 }
395
396
397 MRResultPage.prototype.doMRSearch = function() {
398
399         var obj = this;
400         var method = "open-ils.search.biblio.class";
401
402         /* now the count and search are simultaneous 
403         if( this.hitCount > 5000 )
404                 method = method + ".unordered";
405                 */
406
407         if(isXUL())
408                 method = method + ".staff";
409
410         debug("Search method is " + method);
411
412         var form = this.format;
413         if(this.format == "all") form = null;
414
415         var request = new RemoteRequest( 
416                 "open-ils.search", method, obj.stype, obj.string, obj.searchLocation, 
417                 obj.searchDepth, "50", obj.searchOffset, form );
418         
419         request.setCompleteCallback(
420                 function(req) {
421
422                         var row = getById("hourglass_row");
423                         if(row)
424                                 row.parentNode.removeChild(row);
425
426                         var result = req.getResultObject();
427                         if(result == null) return;
428                         result.count = obj.hitCount;
429                         obj.gatherIDs(result) 
430                         obj.collectRecords();
431                         obj.requestBatch.remove(req);
432                 }
433         );
434         obj.requestBatch.add(request);
435         request.send();
436         debug("Sent mr id search");
437
438 }
439
440 MRResultPage.prototype.collectRecords = function() {
441
442         debug("Collecting records...");
443         var i = this.searchOffset;
444
445         var row = getById("hourglass_row");
446         if(row)
447                 row.parentNode.removeChild(row);
448
449         /* ------------------------------------------------- */
450
451         /*
452         var ids = new Array();
453         while( i < (this.searchOffset + this.hitsPerPage) ) 
454                 ids.push(this.recordIDs[i++]);
455
456         debug("Retrieving IDs " + ids);
457
458         var request = new RemoteRequest( "open-ils.search",
459                 "open-ils.search.biblio.metarecord.mods_slim.batch.retrieve", ids );
460         this.requestBatch.add(request);
461         var obj = this;
462
463
464         request.setCompleteCallback(
465                 function(req) {
466                         var records = req.getResultObject();
467                         //alert(records);
468
469                         for(var i = 0; i!= records.length; i++) {
470                                 var rec = records[i];
471                                 debug("Displaying recocord " + rec.doc_id());
472                                 obj.displayRecord( rec, obj.searchOffset, i );
473                                 obj.doCopyCount( rec, obj.searchOffset, i );
474                         }
475                         obj.requestBatch.remove(request);
476                 }
477         );              
478         request.send();
479         return;
480         */
481         /* ------------------------------------------------- */
482
483
484         while( i < (this.searchOffset + this.hitsPerPage) ) {
485                 var id = this.recordIDs[i];
486
487                 if(id==null){ i++;  continue; }
488
489                 var request = new RemoteRequest( "open-ils.search",
490                         "open-ils.search.biblio.metarecord.mods_slim.retrieve", id );
491                 this.requestBatch.add(request);
492                 debug( "Sending mods retrieval for metarecord " + id );
493
494                 request.name = "record_request_" + i;
495                 request.search_id = i;
496                 request.page_id = parseInt(i) - parseInt(this.searchOffset);
497
498                 /* define the callback for when we receive the record */
499                 var obj = this;
500                 request.setCompleteCallback(
501                         function(req) {
502                                 var record = req.getResultObject();
503                                 obj.displayRecord( record, req.search_id, req.page_id );
504                                 obj.doCopyCount( record, req.search_id, req.page_id );
505                                 obj.requestBatch.remove(req);
506                         }
507                 );
508
509                 debug("Sending mods retrieval request for " + id);
510                 request.send();
511                 i++;
512         }
513 }
514
515
516
517 MRResultPage.prototype.doCopyCount = function( record, search_id, page_id ) {
518
519         if(record==null || !record) return;
520
521         var copy_box    = getById("record_result_copy_count_box_" + page_id );
522
523         var orgunit = globalSelectedLocation;
524         if(!orgunit) orgunit = globalLocation;
525
526         var method = "open-ils.search.biblio.metarecord.copy_count";
527         if(isXUL())
528                 method = method + ".staff";
529
530         var copy_request = new RemoteRequest( 
531                 "open-ils.search", method,
532                 this.searchLocation, record.doc_id() );
533
534         copy_request.search_id = search_id;
535         copy_request.name = "copy_request_" + (search_id+this.searchOffset);
536
537         var obj = this;
538         copy_request.setCompleteCallback( 
539                 function(req) {
540                         try {   
541                                 obj.displayCopyCounts(req.getResultObject(), search_id, page_id );
542                         } catch(E) { 
543                                 debug("****** Copy Count Retrieval Error:\n" + E ); 
544                         }
545                 }
546         );
547
548         copy_request.send();
549 }
550
551