]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/opac_utils.js
a6ec981452bdc603b2da7db9ea529d2371db5218
[Evergreen.git] / Open-ILS / web / opac / common / js / opac_utils.js
1 /* - Request ------------------------------------------------------------- */
2
3 /* define it again here for pages that don't load RemoteRequest */
4 function isXUL() { try { if(IAMXUL) return true;}catch(e){return false;}; }
5
6 var cookieManager = new HTTP.Cookies();
7
8 var __ilsEvent; /* the last event the occurred */
9
10 function Request(type) {
11         var s = type.split(":");
12         if(s[2] == "1" && isXUL()) s[1] += ".staff";
13         this.request = new RemoteRequest(s[0], s[1]);
14         for( var x = 1; x!= arguments.length; x++ ) 
15                 this.request.addParam(arguments[x]);
16 }
17
18 Request.prototype.callback = function(cal) {this.request.setCompleteCallback(cal);}
19 Request.prototype.send          = function(block){this.request.send(block);}
20 Request.prototype.result        = function(){return this.request.getResultObject();}
21
22 function showCanvas() {
23         for( var x in G.ui.altcanvas ) {
24                 hideMe(G.ui.altcanvas[x]);
25         }
26         hideMe(G.ui.common.loading);
27         unHideMe(G.ui.common.canvas_main);
28         try{G.ui.searchbar.text.focus();}catch(e){}
29 }
30
31 function swapCanvas(newNode) {
32         for( var x in G.ui.altcanvas ) 
33                 hideMe(G.ui.altcanvas[x]);
34
35         hideMe(G.ui.common.loading);
36         hideMe(G.ui.common.canvas_main);
37         unHideMe(newNode);
38 }
39
40 /* finds the name of the current page */
41 var currentPage = null;
42 function findCurrentPage() {
43         if(currentPage) return currentPage;
44
45         var pages = [];
46         for( var p in config.page ) pages.push(config.page[p]);
47         pages = pages.sort( function(a,b){ return - (a.length - b.length); } );
48
49         var path = location.pathname;
50         if(!path.match(/.*\.xml$/))
51                 path += "index.xml"; /* in case they go to  / */
52
53         var page = null;
54         for( var p in pages ) {
55                 if( path.indexOf(pages[p]) != -1)
56                         page = pages[p];
57         }
58
59         for( var p in config.page ) {
60                 if(config.page[p] == page) {
61                         currentPage = p;
62                         return p;
63                 }
64         }
65         return null;
66 }
67
68
69 /* sets all of the params values  ----------------------------- */
70 function initParams() {
71         var cgi = new CGI();    
72
73         TERM            = cgi.param(PARAM_TERM);
74         STYPE           = cgi.param(PARAM_STYPE);
75         FORM            = cgi.param(PARAM_FORM);
76         LOCATION        = parseInt(cgi.param(PARAM_LOCATION));
77         ORIGLOC = parseInt(cgi.param(PARAM_ORIGLOC));
78         DEPTH           = parseInt(cgi.param(PARAM_DEPTH));
79         OFFSET  = parseInt(cgi.param(PARAM_OFFSET));
80         COUNT           = parseInt(cgi.param(PARAM_COUNT));
81         HITCOUNT        = parseInt(cgi.param(PARAM_HITCOUNT));
82         MRID            = parseInt(cgi.param(PARAM_MRID));
83         RID             = parseInt(cgi.param(PARAM_RID));
84         AUTHTIME        = parseInt(cgi.param(PARAM_AUTHTIME));
85         ADVTERM = cgi.param(PARAM_ADVTERM);
86         ADVTYPE = cgi.param(PARAM_ADVTYPE);
87         RTYPE           = cgi.param(PARAM_RTYPE);
88         SORT            = cgi.param(PARAM_SORT);
89         SORT_DIR        = cgi.param(PARAM_SORT_DIR);
90
91         /* set up some sane defaults */
92         if(isNaN(LOCATION))     LOCATION        = 1;
93         if(isNaN(DEPTH))                DEPTH           = 0;
94         if(isNaN(OFFSET))               OFFSET  = 0;
95         if(isNaN(COUNT))                COUNT           = 10;
96         if(isNaN(HITCOUNT))     HITCOUNT        = 0;
97         if(isNaN(MRID))         MRID            = 0;
98         if(isNaN(RID))                  RID             = 0;
99         if(isNaN(ORIGLOC))      ORIGLOC = 1;
100         if(isNaN(AUTHTIME))     AUTHTIME        = 0;
101         if(ADVTERM==null)               ADVTERM = "";
102 }
103
104 function initCookies() {
105         FONTSIZE = "medium";
106         var font = cookieManager.read(COOKIE_FONT);
107         if(font) FONTSIZE = font;
108         SKIN = cookieManager.read(COOKIE_SKIN);
109 }
110
111 /* URL param accessors */
112 function getTerm(){return TERM;}
113 function getStype(){return STYPE;}
114 function getLocation(){return LOCATION;}
115 function getDepth(){return DEPTH;}
116 function getForm(){return FORM;}
117 function getOffset(){return OFFSET;}
118 function getDisplayCount(){return COUNT;}
119 function getHitCount(){return HITCOUNT;}
120 function getMrid(){return MRID;};
121 function getRid(){return RID;};
122 function getOrigLocation(){return ORIGLOC;}
123 function getAuthtime() { return AUTHTIME; }
124 function getSearchBarExtras(){return SBEXTRAS;}
125 function getFontSize(){return FONTSIZE;};
126 function getSkin(){return SKIN;};
127 function getAdvTerm(){return ADVTERM;}
128 function getAdvType(){return ADVTYPE;}
129 function getRtype(){return RTYPE;}
130 function getSort(){return SORT;}
131 function getSortDir(){return SORT_DIR;}
132
133
134 function findBasePath() {
135         var path = location.pathname;
136         if(!path.match(/.*\.xml$/)) path += "index.xml"; 
137         var idx = path.indexOf(config.page[findCurrentPage()]);
138         return path.substring(0, idx);
139 }
140
141 function findBaseURL(ssl) {
142         var path = findBasePath();
143         var proto = (ssl) ? "https:" : "http:";
144         return proto + "//" + location.host + path;
145         dump( 'ssl: ' + ssl + 'proto ' + proto );
146 }
147
148 /*
149 function buildISBNSrc(isbn) {
150         return "http://" + location.host + "/jackets/" + isbn;
151 }
152 */
153
154 function buildImageLink(name, ssl) {
155         return findBaseURL(ssl) + "../../../../images/" + name;
156 }
157
158 function buildExtrasLink(name, ssl) {
159         return findBaseURL(ssl) + "../../../../extras/" + name;
160 }
161
162 function _debug(str) { try { dump(str + '\n'); } catch(e) {} }
163
164 function  buildOPACLink(args, slim, ssl) {
165
166         if(!args) args = {};
167         var string = "";
168
169         if(!slim) {
170                 string = findBaseURL(ssl);
171                 if(args.page) string += config.page[args.page];
172                 else string += config.page[findCurrentPage()];
173         }
174
175         string += "?";
176
177         for( var x in args ) {
178                 var v = args[x];
179                 if(x == "page" || v == null || v == undefined || v+'' == 'NaN' ) continue;
180                 if(x == PARAM_OFFSET && v == 0) continue;
181                 if(x == PARAM_LOCATION && v == 1) continue;
182                 if(x == PARAM_DEPTH && v == 0) continue;
183                 if(x == PARAM_COUNT && v == 10) continue;
184                 if(x == PARAM_FORM && v == 'all' ) continue;
185                 if( instanceOf(v, Array) ) {
186                         for( var i = 0; i != v.length; i++ ) {
187                                 string += "&" + x + "=" + encodeURIComponent(v[i]);
188                         }
189                 } else {
190                         string += "&" + x + "=" + encodeURIComponent(v);
191                 }
192         }
193
194         if(getOrigLocation() != 1) 
195                 string += _appendParam(ORIGLOC, PARAM_ORIGLOC, args, getOrigLocation, string);
196         if(getTerm()) 
197                 string += _appendParam(TERM,            PARAM_TERM, args, getTerm, string);
198         if(getStype()) 
199                 string += _appendParam(STYPE,           PARAM_STYPE, args, getStype, string);
200         if(getLocation() != 1) 
201                 string += _appendParam(LOCATION, PARAM_LOCATION, args, getLocation, string);
202         if(getDepth() != 0) 
203                 string += _appendParam(DEPTH,           PARAM_DEPTH, args, getDepth, string);
204         if(getForm() && (getForm() != 'all') ) 
205                 string += _appendParam(FORM,            PARAM_FORM, args, getForm, string);
206         if(getOffset() != 0) 
207                 string += _appendParam(OFFSET,  PARAM_OFFSET, args, getOffset, string);
208         if(getDisplayCount() != 10) 
209                 string += _appendParam(COUNT,           PARAM_COUNT, args, getDisplayCount, string);
210         if(getHitCount()) 
211                 string += _appendParam(HITCOUNT, PARAM_HITCOUNT, args, getHitCount, string);
212         if(getMrid())
213                 string += _appendParam(MRID,            PARAM_MRID, args, getMrid, string);
214         if(getRid())
215                 string += _appendParam(RID,             PARAM_RID, args, getRid, string);
216         if(getAuthtime())
217                 string += _appendParam(AUTHTIME,        PARAM_AUTHTIME, args, getAuthtime, string);
218         if(getAdvTerm())
219                 string += _appendParam(ADVTERM, PARAM_ADVTERM, args, getAdvTerm, string);
220         if(getAdvType())
221                 string += _appendParam(ADVTYPE, PARAM_ADVTYPE, args, getAdvType, string);
222         if(getRtype())
223                 string += _appendParam(RTYPE,           PARAM_RTYPE, args, getRtype, string);
224
225         return string.replace(/\&$/,'').replace(/\?\&/,"?");    
226 }
227
228 function _appendParam( fieldVar, fieldName, overrideArgs, getFunc, string ) {
229         var ret = "";
230         if( fieldVar != null && (fieldVar +'' != 'NaN') && overrideArgs[fieldName] == null ) 
231                 ret = "&" + fieldName + "=" + encodeURIComponent(getFunc());
232         return ret;
233 }
234
235 /* ----------------------------------------------------------------------- */
236 function cleanISBN(isbn) {
237    if(isbn) {
238       isbn = isbn.toString().replace(/^\s+/,"");
239       var idx = isbn.indexOf(" ");
240       if(idx > -1) { isbn = isbn.substring(0, idx); }
241    } else isbn = "";
242    return isbn;
243 }       
244
245
246 /* builds a link that goes to the title listings for a metarecord */
247 function buildTitleLink(rec, link) {
248         if(!rec) return;
249         link.appendChild(text(normalize(truncate(rec.title(), 65))));
250         var args = {};
251         args.page = RRESULT;
252         args[PARAM_OFFSET] = 0;
253         args[PARAM_MRID] = rec.doc_id();
254         args[PARAM_RTYPE] = RTYPE_MRID;
255         link.setAttribute("href", buildOPACLink(args));
256 }
257
258 function buildTitleDetailLink(rec, link) {
259         if(!rec) return;
260         link.appendChild(text(normalize(truncate(rec.title(), 65))));
261         var args = {};
262         args.page = RDETAIL;
263         args[PARAM_OFFSET] = 0;
264         args[PARAM_RID] = rec.doc_id();
265         link.setAttribute("href", buildOPACLink(args));
266 }
267
268 /* 'type' is one of STYPE_AUTHOR, STYPE_SUBJECT, ... found in config.js 
269         'trunc' is the number of characters to show in the string, defaults to 65 */
270 function buildSearchLink(type, string, linknode, trunc) {
271         if(!trunc) trunc = 65;
272         var args = {};
273         args.page = MRESULT;
274         args[PARAM_OFFSET] = 0;
275         args[PARAM_TERM] = string;
276         args[PARAM_STYPE] = type;
277         linknode.appendChild(text(normalize(truncate(string, trunc))));
278         linknode.setAttribute("href", buildOPACLink(args));
279 }
280
281
282 /* ----------------------------------------------------------------------- */
283 /* user session handling */
284 /* ----------------------------------------------------------------------- */
285 /* session is the login session.  If no session is provided, we attempt
286         to find one in the cookies.  If 'force' is true we retrieve the 
287         user from the server even if there is already a global user present.
288         if ses != G.user.session, we also force a grab */
289 function grabUser(ses, force) {
290
291         if(!ses && isXUL()) ses = xulG['authtoken'];
292         if(!ses) ses = cookieManager.read(COOKIE_SES);
293         if(!ses) return false;
294
295         if(!force) 
296                 if(G.user && G.user.session == ses)
297                         return G.user;
298
299         /* first make sure the session is valid */
300         var request = new Request(FETCH_SESSION, ses, 1 );
301         request.send(true);
302         var user = request.result();
303
304         if(checkILSEvent(user)) {
305                 __ilsEvent = user;
306                 doLogout();
307                 return false; /* unable to grab the session */
308         }
309
310         if( !(typeof user == 'object' && user._isfieldmapper) ) {
311                 doLogout();
312                 return false;
313         }
314
315         G.user = user;
316         G.user.fleshed = false;
317         G.user.session = ses;
318         cookieManager.write(COOKIE_SES, ses, '+1y');
319
320         grabUserPrefs();
321         if(G.user.prefs['opac.hits_per_page'])
322                 COUNT = parseInt(G.user.prefs['opac.hits_per_page']);
323
324         var at = getAuthtime();
325         if(isXUL()) at = xulG['authtime'];
326
327         if(at) new AuthTimer(at).run(); 
328         return G.user;
329 }
330
331
332 /* sets the 'prefs' field of the user object to their preferences 
333         and returns the preferences */
334 function grabUserPrefs(user, force) {
335         if(user == null) user = G.user;
336         if(!force && user.prefs) return user.prefs;     
337         var req = new Request(FETCH_USER_PREFS, user.session, user.id());
338         req.send(true);
339         user.prefs = req.result();
340         return user.prefs;
341 }
342
343 function grabFleshedUser() {
344
345         if(!G.user || !G.user.session) {
346                 grabUser();     
347                 if(!G.user || !G.user.session) return null;
348         }
349
350         if(G.user.fleshed) return G.user;
351
352    var req = new Request(FETCH_FLESHED_USER, G.user.session);
353         req.send(true);
354
355         G.user = req.result();
356
357         if(!G.user || G.user.length == 0) { 
358                 G.user = null; return false; 
359                 cookieManager.remove(COOKIE_SES);
360         }
361
362         G.user.session = ses;
363         G.user.fleshed = true;
364
365         cookieManager.write(COOKIE_SES, ses, '+1y'); /*  update the cookie */
366         return G.user;
367 }
368
369 function checkUserSkin(new_skin) {
370
371         return; /* XXX do some debugging with this... */
372
373         var user_skin = getSkin();
374         var cur_skin = grabSkinFromURL();
375
376         if(new_skin) user_skin = new_skin;
377
378         if(!user_skin) {
379
380                 if(grabUser()) {
381                         if(grabUserPrefs()) {
382                                 user_skin = G.user.prefs["opac.skin"];
383                                 cookieManager.write( COOKIE_SKIN, user_skin, '+1y' );
384                         }
385                 }
386         }
387
388         if(!user_skin) return;
389
390         if( cur_skin != user_skin ) {
391                 var url = buildOPACLink();
392                 goTo(url.replace(cur_skin, user_skin));
393         }
394 }
395
396 function updateUserSetting(setting, value, user) {
397         if(user == null) user = G.user;
398         var a = {};
399         a[setting] = value;
400         var req = new Request( UPDATE_USER_PREFS, user.session, a );
401         req.send(true);
402         return req.result();
403 }
404
405 function commitUserPrefs() {
406         var req = new Request( 
407                 UPDATE_USER_PREFS, G.user.session, null, G.user.prefs );
408         req.send(true);
409         return req.result();
410 }
411
412 function grabSkinFromURL() {
413         var path = findBasePath();
414         path = path.replace("/xml/", "");
415         var skin = "";
416         for( var i = path.length - 1; i >= 0; i-- ) {
417                 var ch = path.charAt(i);
418                 if(ch == "/") break;
419                 skin += ch;
420         }
421
422         var skin2 = "";
423         for( i = skin.length - 1; i >= 0; i--)
424                 skin2 += skin.charAt(i);
425
426         return skin2;
427 }
428
429
430 /* returns a fleshed G.user on success, false on failure */
431 function doLogin() {
432
433         abortAllRequests();
434
435         var uname = G.ui.login.username.value;
436         var passwd = G.ui.login.password.value; 
437
438         var init_request = new Request( LOGIN_INIT, uname );
439    init_request.send(true);
440    var seed = init_request.result();
441
442    if( ! seed || seed == '0') {
443       alert( "Error Communicating with Authentication Server" );
444       return null;
445    }
446
447    var auth_request = new Request( LOGIN_COMPLETE, 
448                 uname, hex_md5(seed + hex_md5(passwd)), "opac", getOrigLocation());
449
450
451    auth_request.send(true);
452    var auth_result = auth_request.result();
453
454         var code = checkILSEvent(auth_result);
455         if(code) { alertILSEvent(code); return null; }
456
457         AUTHTIME = parseInt(auth_result.payload.authtime);
458         var u = grabUser(auth_result.payload.authtoken, true);
459         if(u) runEvt( "common", "locationChanged", u.home_ou(), findOrgDepth(u.home_ou()) );
460
461         checkUserSkin();
462
463         return u;
464 }
465
466 function doLogout(noredirect) {
467
468         /* cancel everything else */
469         abortAllRequests();
470
471         /* be nice and delete the session from the server */
472         if(G.user && G.user.session) { 
473                 var req = new Request(LOGIN_DELETE, G.user.session);
474       req.send(true);
475                 try { req.result(); } catch(E){}
476     }
477
478         G.user = null;
479         cookieManager.remove(COOKIE_SES);
480         cookieManager.remove(COOKIE_SKIN);
481         checkUserSkin("default");
482         COUNT = 10;
483
484         var args = {};
485         args[PARAM_TERM] = "";
486         args[PARAM_LOCATION] = globalOrgTree.id();
487         args[PARAM_DEPTH] = findOrgDepth(globalOrgTree);
488         args.page = "home";
489
490         var nored = false;
491         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
492         if(!nored) goTo(buildOPACLink(args));
493 }
494
495
496 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
497 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
498
499
500 /* ----------------------------------------------------------------------- */
501 /* build the org tree */
502 /* ----------------------------------------------------------------------- */
503 function drawOrgTree() {
504         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
505         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
506 }
507         
508 var orgTreeSelector;
509 function buildOrgSelector(node) {
510         var tree = new SlimTree(node,'orgTreeSelector');
511         orgTreeSelector = tree;
512         for( var i in orgArraySearcher ) { 
513                 var node = orgArraySearcher[i];
514                 if( node == null ) continue;
515                 if(node.parent_ou() == null)
516                         tree.addNode(node.id(), -1, node.name(), 
517                                 "javascript:orgSelect(" + node.id() + ");", node.name());
518                 else {
519                         tree.addNode(node.id(), findOrgUnit(node.parent_ou()).id(), node.name(), 
520                                 "javascript:orgSelect(" + node.id() + ");", node.name());
521                 }
522         }
523         hideMe($('org_loading_div'));
524         unHideMe($('org_selector_tip'));
525         return tree;
526 }
527
528 function orgSelect(id) {
529         showCanvas();
530         runEvt("common", "locationChanged", id, findOrgDepth(id) );
531
532         removeChildren(G.ui.common.now_searching);
533         G.ui.common.now_searching.appendChild(text(findOrgUnit(id).name()));
534 }
535
536 var fontCookie = new HTTP.Cookies();
537 function setFontSize(size) {
538         scaleFonts(size);
539         fontCookie.write(COOKIE_FONT, size, '+1y');
540 }
541
542
543 var resourceFormats = [
544    "text",
545    "moving image",
546    "sound recording", "software, multimedia",
547    "still images",
548    "cartographic",
549    "mixed material",
550    "notated music",
551    "three dimensional object" ];
552
553
554 function modsFormatToMARC(format) {
555    switch(format) {
556       case "text":
557          return "at";
558       case "moving image":
559          return "g";
560       case "sound recording":
561          return "ij";
562       case "sound recording-nonmusical":
563          return "i";
564       case "sound recording-musical":
565          return "j";
566       case "software, multimedia":
567          return "m";
568       case "still images":
569          return "k";
570       case "cartographic":
571          return "ef";
572       case "mixed material":
573          return "op";
574       case "notated music":
575          return "cd";
576       case "three dimensional object":
577          return "r";
578    }
579    return "at";
580 }
581
582
583 function MARCFormatToMods(format) {
584    switch(format) {
585       case "a":
586       case "t":
587          return "text";
588       case "g":
589          return "moving image";
590       case "i":
591          return "sound recording-nonmusical";
592       case "j":
593          return "sound recording-musical";
594       case "m":
595          return "software, multimedia";
596       case "k":
597          return "still images";
598       case "e":
599       case "f":
600          return "cartographic";
601       case "o":
602       case "p":
603          return "mixed material";
604       case "c":
605       case "d":
606          return "notated music";
607       case "r":
608          return "three dimensional object";
609    }
610    return "text";
611 }
612
613 function setResourcePic( img, resource ) {
614         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
615         img.title = resource;
616 }
617
618
619
620 function msg( text ) {
621         try { alert( text ); } catch(e) {}
622 }
623
624 function findRecord(id,type) {
625         try {
626                 for( var i = 0; i != recordsCache.length; i++ ) {
627                         var rec = recordsCache[i];
628                         if( rec && rec.doc_id() == id ) return rec;
629                 }
630         } catch(E){}
631         var meth = FETCH_RMODS
632         if(type == 'M') meth = FETCH_MRMODS;
633         var req = new Request(meth, id);
634         req.send(true);
635         return req.result();
636 }
637
638 function Timer(name, node){
639         this.name = name;
640         this.count = 1;
641         this.node = node;
642 }
643 Timer.prototype.start = 
644         function(){_timerRun(this.name);}
645 Timer.prototype.stop = 
646         function(){this.done = true;}
647 function _timerRun(tname) {
648         var _t;
649         eval('_t='+tname);
650         if(_t.done) return;
651         if(_t.count > 100) return;
652         var str = ' . ';
653         if( (_t.count % 5) == 0 ) 
654                 str = _t.count / 5;
655         _t.node.appendChild(text(str));
656         setTimeout("_timerRun('"+tname+"');", 200);
657         _t.count++;
658 }
659
660 function checkILSEvent(obj) {
661         if( obj.ilsevent != null && obj.ilsevent != 0 )
662                 return parseInt(obj.ilsevent);
663         return null;
664 }
665 function alertILSEvent(code, msg) {
666    if(!msg) msg = "";
667         alert( msg + '\n' + $('ilsevent.' + code).innerHTML );
668 }
669
670
671 var __authTimer;
672 function AuthTimer(time) { 
673         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
674         __authTimer = this;
675 }
676
677 AuthTimer.prototype.run = function() {
678         setTimeout('_authTimerAlert()', this.time);
679 }
680
681 function _authTimerAlert() {
682         alert( $('auth_session_expiring').innerHTML );
683         if(!grabUser(null, true)) doLogout();
684 }
685
686
687 function grabUserByBarcode( authtoken, barcode ) {
688         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
689         req.send(true);
690         return req.result();
691 }
692
693
694 function goHome() {
695         goTo(buildOPACLink({page:HOME}));
696 }
697
698
699