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