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