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