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