]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/holds.js
disable org select if requestor does not have the change-pickup-lib while on holds...
[working/Evergreen.git] / Open-ILS / web / opac / skin / default / js / holds.js
1 var holdsOrgSelectorBuilt = false;
2 var holdArgs;
3
4 /* 
5 note: metarecord holds have a holdable_formats field that contains
6 item_type(s)-item_forms(s)-language
7 item_form and language are optional - if language exist and no 
8 item_form is specified, use item_type(s)--language
9 */
10
11 var noEmailMessage;
12 var noEmailMessageXUL;
13
14 function holdsHandleStaff() {
15         swapCanvas($('xulholds_box'));
16         $('xul_recipient_barcode').focus();
17         $('xul_recipient_barcode').onkeypress = function(evt) 
18                 {if(userPressedEnter(evt)) { _holdsHandleStaff(); } };
19         $('xul_recipient_barcode_submit').onclick = _holdsHandleStaff;
20         $('xul_recipient_me').onclick = _holdsHandleStaffMe;
21
22         $('xul_recipient_barcode').onkeyup = function(evt) {
23         if($('xul_recipient_barcode').value == '') 
24             $('xul_recipient_me').disabled = false;
25         else
26             $('xul_recipient_me').disabled = true;
27     };
28 }
29
30 $('holds_frozen_thaw_input').onchange = 
31         function(){holdsVerifyThawDateUI('holds_frozen_thaw_input');}
32 $('holds_frozen_thaw_input').onkeyup = 
33         function(){holdsVerifyThawDateUI('holds_frozen_thaw_input');}
34
35 function _holdsHandleStaffMe() {
36         holdArgs.recipient = G.user;
37         holdsDrawEditor();
38 }
39
40 function _holdsHandleStaff() {
41         var barcode = $('xul_recipient_barcode').value;
42         var user = grabUserByBarcode( G.user.session, barcode );
43
44         var evt;
45         if(evt = checkILSEvent(user)) {
46                 alertILSEvent(user);
47                 return;
48         }
49
50         if(!barcode || !user) {
51                 alertId('holds_invalid_recipient', barcode);
52                 return
53         }
54
55         holdArgs.recipient = user;
56         holdsDrawEditor();
57 }
58
59
60
61 /** args:
62   * record, volume, copy (ids)
63   * request, recipient, editHold (objects)
64   */
65
66 function holdsDrawEditor(args) {
67
68         holdArgs = (args) ? args : holdArgs;
69
70     if(!noEmailMessage)
71         noEmailMessage = $('holds_email').removeChild($('holds.no_email'));
72
73     if(!noEmailMessageXUL)
74         noEmailMessageXUL = $('holds_email').removeChild($('holds.no_email.xul'));
75
76         if(isXUL() && holdArgs.recipient == null 
77                         && holdArgs.editHold == null) {
78                 holdsHandleStaff();
79                 return;
80         }
81
82         if(!holdArgs.recipient) holdArgs.recipient = G.user;
83         if(!holdArgs.requestor) holdArgs.requestor = G.user;
84
85         if(!(holdArgs.requestor && holdArgs.requestor.session)) {
86                 detachAllEvt('common','locationChanged');
87                 attachEvt('common','loggedIn', holdsDrawEditor)
88                 initLogin();
89                 return;
90         }
91
92         if(holdArgs.editHold) // flesh the args with the existing hold 
93                 holdArgsFromHold(holdArgs.editHold, holdArgs);
94
95         holdsDrawWindow();
96 }
97
98
99 // updates the edit window with the existing hold's data 
100 function _holdsUpdateEditHold() {
101
102         var hold = holdArgs.editHold;
103         var status = holdArgs.status;
104
105         var orgsel = $('holds_org_selector');
106     var frozenbox = $('holds_frozen_chkbox');
107
108         setSelector(orgsel, hold.pickup_lib());
109
110         if( hold.capture_time() || status > 2 ) {
111         frozenbox.disabled = true;
112         $('holds_frozen_thaw_input').disabled = true;
113         if(status == 3) {
114             // no pickup lib changes while in-transit
115                     orgsel.disabled = true;
116         } else {
117             var orgs = fetchPermOrgs('UPDATE_PICKUP_LIB_FROM_HOLDS_SHELF');
118             if(orgs[0] == -1)
119                         orgsel.disabled = true;
120         }
121     } else {
122                 orgsel.disabled = false;
123         frozenbox.disabled = false;
124     }
125
126
127         $('holds_submit').onclick = holdsEditHold;
128         $('holds_update').onclick = holdsEditHold;
129
130         if(hold.phone_notify()) {
131                 $('holds_enable_phone').checked = true;
132                 $('holds_phone').value = hold.phone_notify();
133
134         } else {
135                 $('holds_phone').disabled = true;
136                 $('holds_enable_phone').checked = false;
137         }
138
139         if(isTrue(hold.email_notify())) {
140                 $('holds_enable_email').checked = true;
141
142         } else {
143                 $('holds_enable_email').checked = false;
144         }
145
146     /* populate the hold freezing info */
147     if(!frozenbox.disabled && isTrue(hold.frozen())) {
148         frozenbox.checked = true;
149         unHideMe($('hold_frozen_thaw_row'));
150         if(hold.thaw_date()) {
151             dijit.byId('holds_frozen_thaw_input').setValue(hold.thaw_date());
152         } else {
153             dijit.byId('holds_frozen_thaw_input').setValue('');
154         }
155     } else {
156         frozenbox.checked = false;
157         dijit.byId('holds_frozen_thaw_input').setValue('');
158         hideMe($('hold_frozen_thaw_row'));
159     }
160 }
161
162 function holdsEditHold() {
163         var hold = holdsBuildHoldFromWindow();
164         if(!hold) return;
165         holdsUpdate(hold);
166         showCanvas();
167         if(holdArgs.onComplete)
168                 holdArgs.onComplete(hold);
169 }
170
171 function holdArgsFromHold(hold, oargs) {
172         var args = (oargs) ? oargs : {};
173         args.type = hold.hold_type();
174         var target = hold.target();
175
176         switch(args.type) {
177                 case 'M':
178                         args.metarecord = target;
179                         break;
180                 case 'T':
181                         args.record = target;
182                         break;
183                 case 'V':
184                         args.volume = target;
185                         break;
186                 case 'C':
187                         args.copy = target;
188                         break;
189         }
190         return args;
191 }
192
193 function holdFetchObjects(hold, doneCallback) {
194
195         var args = (hold) ? holdArgsFromHold(hold) : holdArgs;
196
197         var type = args.type;
198
199         if( type == 'C' ) {
200
201                 if( args.copyObject ) {
202
203                         args.copy = args.copyObject.id();
204                         args.volume = args.copyObject.call_number();
205                         _h_set_vol(args, doneCallback);
206
207                 } else {
208                         var creq = new Request(FETCH_COPY, args.copy);
209
210                         creq.callback(
211                                 function(r) {
212                                         var cp = r.getResultObject();
213                                         args.copyObject = cp;
214                                         args.volume = args.copyObject.call_number();
215                                         _h_set_vol(args, doneCallback);
216                                 }
217                         );
218                         creq.send();
219                 }
220         } else {
221                 if( type == 'V' ) {
222                         _h_set_vol(args, doneCallback);
223
224                 } else {
225                         if( type == 'T' ) {
226                                 _h_set_rec(args, doneCallback);
227                         } else {
228                                 _h_set_rec_descriptors(args, doneCallback);
229                         }
230                 }
231         }
232
233         return args;
234 }
235
236 function _h_set_vol(args, doneCallback) {
237
238         if( args.volumeObject ) {
239                 args.volume = args.volumeObject.id();
240                 args.record = args.volumeObject.record();
241                 _h_set_rec(args, doneCallback);
242
243         } else {
244
245                 var vreq = new Request(FETCH_VOLUME, args.volume);
246                 vreq.callback(
247                         function(r) {
248                                 var vol = r.getResultObject();
249                                 args.volumeObject = vol;
250                                 args.record = vol.record();
251                                 _h_set_rec(args, doneCallback);
252                         }
253                 );
254                 vreq.send();
255         }
256 }
257
258 function _h_set_rec(args, doneCallback) {
259
260         if(args.recordObject) 
261                 args.record = args.recordObject.doc_id();
262         else 
263                 args.recordObject = findRecord( args.record, 'T' );
264         
265         if( args.type == 'T' || args.type == 'M' ) 
266                 _h_set_rec_descriptors(args, doneCallback);
267         else 
268                 if(doneCallback) doneCallback(args);
269 }
270
271
272 function _h_set_rec_descriptors(args, doneCallback) {
273
274         // grab the list of record desciptors attached to this records metarecord 
275         if( ! args.recordDescriptors )  {
276                 var params = { record: args.record };
277
278                 if( ! args.record ) {
279                         if( args.metarecord )
280                                 params = { metarecord : args.metarecord };
281                         else 
282                                 params = { metarecord : args.metarecordObject.doc_id() };
283                 }
284
285                 var req = new Request(FETCH_MR_DESCRIPTORS, params );
286                 req.callback(
287                         function(r) {
288                                 var data = r.getResultObject();
289                                 args.recordDescriptors = data.descriptors;
290                                 args.metarecord = data.metarecord;
291                                 if( args.type == 'M' && ! args.metarecordObject) 
292                                         args.metarecordObject = findRecord(args.metarecord, 'M');       
293                                  
294                                 if(doneCallback) doneCallback(args);
295                         }
296                 );
297                 req.send();
298
299         } else {
300                 if(doneCallback) doneCallback(args);
301         }
302
303         return args;
304 }
305
306
307
308 function holdsDrawWindow() {
309         swapCanvas($('holds_box'));
310         $('holds_cancel').onclick = function(){ runEvt('common', 'holdUpdateCanceled'), showCanvas() };
311         $('holds_submit').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
312         $('holds_update').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
313         holdFetchObjects(null, 
314                 function(){
315                         __holdsDrawWindow();
316
317                         if(holdArgs.editHold) {
318                                 hideMe($('holds_submit'));
319                                 unHideMe($('holds_update'));
320                                 var req = new Request(FETCH_HOLD_STATUS, 
321                                         G.user.session, holdArgs.editHold.id());
322                                 req.send(true);
323                                 holdArgs.status = req.result();
324                                 _holdsUpdateEditHold();
325                         }  
326                 }
327         );
328 }
329
330 function __holdsDrawWindow() {
331
332         var rec = holdArgs.recordObject;
333         var vol = holdArgs.volumeObject;
334         var copy = holdArgs.copyObject;
335         var mr = holdArgs.metarecordObject;
336
337         rec = (rec) ? rec : mr;
338
339         if(!holdsOrgSelectorBuilt) {
340                 holdsBuildOrgSelector(null,0);
341                 holdsOrgSelectorBuilt = true;
342                 var selector = $('holds_org_selector');
343
344                 /*
345                 var o_loc = findOrgUnit(getOrigLocation());
346                 var t = findOrgType(o_loc.ou_type());
347                 if( t.can_have_users() ) 
348                         setSelector(selector, o_loc.id());
349                 else 
350                 */
351
352                 setSelector(selector, holdArgs.recipient.home_ou());
353         
354         }
355
356         /*
357         if(isXUL()) {
358                 var dsel = $('holds_depth_selector');
359                 unHideMe($('holds_depth_selector_row'));
360                 if(dsel.getElementsByTagName('option').length == 0) {
361                         var types = globalOrgTypes;
362                         var depth = findOrgDepth(G.user.ws_ou());
363                         iterate(types, 
364                                 function(t) {
365                                         if(t.depth() > depth) return;
366                                         insertSelectorVal(dsel, -1, t.opac_label(), t.depth());
367                                 }
368                         );
369                 }
370         }
371         */
372
373         appendClear($('holds_recipient'), text(
374                 holdArgs.recipient.family_name() + ', ' +  
375                         holdArgs.recipient.first_given_name()));
376         appendClear($('holds_title'), text(rec.title()));
377         appendClear($('holds_author'), text(rec.author()));
378
379         if( holdArgs.type == 'V' || holdArgs.type == 'C' ) {
380
381                 unHideMe($('holds_type_row'));
382                 unHideMe($('holds_cn_row'));
383                 appendClear($('holds_cn'), text(holdArgs.volumeObject.label()));
384
385                 if( holdArgs.type == 'V'  ) {
386                         unHideMe($('holds_is_cn'));
387                         hideMe($('holds_is_copy'));
388
389                 } else {
390                         hideMe($('holds_is_cn'));
391                         unHideMe($('holds_is_copy'));
392                         unHideMe($('holds_copy_row'));
393                         appendClear($('holds_copy'), text(holdArgs.copyObject.barcode()));
394                 }
395
396         } else {
397                 hideMe($('holds_type_row'));
398                 hideMe($('holds_copy_row'));
399                 hideMe($('holds_cn_row'));
400         }
401
402         removeChildren($('holds_format'));
403
404         var mods_formats = rec.types_of_resource();
405         var formats;
406
407         if(holdArgs.recordDescriptors)
408                 formats = holdArgs.recordDescriptors[0].item_type();
409
410         if( holdArgs.type == 'T' ) {
411                 var desc = grep( holdArgs.recordDescriptors,
412                         function(i) {
413                                 return (i.record() == holdArgs.record); 
414                         }
415                 );
416                 formats = desc[0].item_type();
417         }
418
419         if( holdArgs.type == 'M' ) {
420                 var data = holdsParseMRFormats(holdArgs.editHold.holdable_formats());
421                 mods_formats = data.mods_formats;
422                 formats = data.formats;
423         }
424
425
426         for( var i in mods_formats ) {
427                 var res = mods_formats[i];
428                 var img = elem("img");
429                 setResourcePic(img, res);
430                 $('holds_format').appendChild(img);
431                 if(formats)
432                         $('holds_format').appendChild(text(' '+ MARCTypeToFriendly(formats[i]) +' '));
433                 else
434                         $('holds_format').appendChild(text(' '+ mods_formats[i] +' '));
435                 $('holds_format').appendChild(elem('br'));
436         }
437
438
439         $('holds_phone').value = holdArgs.recipient.day_phone();
440         appendClear( $('holds_email'), text(holdArgs.recipient.email()));
441
442         var pref = G.user.prefs[PREF_HOLD_NOTIFY];
443
444         if(pref) {
445                 if( ! pref.match(/email/i) ) 
446                         $('holds_enable_email').checked = false;
447
448                 if( ! pref.match(/phone/i) ) {
449                         $('holds_phone').disabled = true;
450                         $('holds_enable_phone').checked = false;
451                 }
452         }
453
454     //if(!G.user.email()) {
455     if(!holdArgs.recipient.email()) {
456                 $('holds_enable_email').checked = false;        
457                 $('holds_enable_email').disabled = true;
458         var message;
459         if(isXUL()) {
460             message = noEmailMessageXUL.cloneNode(true);
461                 appendClear($('holds_email'), message);
462         } else {
463             message = noEmailMessage.cloneNode(true);
464                 appendClear($('holds_email'), message);
465             $('holds.no_email.my_account').setAttribute('href', buildOPACLink({page:MYOPAC},null,true));
466         }
467         unHideMe(message);
468     }
469
470         if(!$('holds_phone').value) 
471                 $('holds_enable_phone').checked = false;        
472
473         appendClear($('holds_physical_desc'), text(rec.physical_description()));
474
475         if(holdArgs.type == 'M') hideMe($('hold_physical_desc_row'));
476
477         holdsSetFormatSelector();
478
479     $('holds_frozen_chkbox').checked = false;
480     hideMe($('hold_frozen_thaw_row'));
481
482 }
483
484 function holdsParseMRFormats(str) {
485         var data = str.split(/-/);      
486
487         var formats = [];
488         var mods_formats = [];
489
490         for( var i = 0; i < data[0].length; i++ ) {
491                 formats.push( data[0].charAt(i) );
492                 mods_formats.push( MARCFormatToMods( formats[i] ) );
493         }
494         
495         formats = uniquify(formats);
496         mods_formats = uniquify(mods_formats);
497
498         return {
499                 formats                 : formats,
500                 mods_formats    : mods_formats,
501                 lang                            : data[2],
502                 largeprint              : data[1]
503         };
504 }
505
506
507 function holdsSetFormatSelector() {
508         var type = holdArgs.type;
509         if( type == 'C' || type == 'V' || holdArgs.editHold ) return;
510
511         var data                                = holdsGetFormats();
512         var avail_formats       = data.avail_formats;
513         var sel_formats = data.sel_formats;
514         holdArgs.language = data.lang;
515
516         unHideMe($('holds_alt_formats_row_extras'));
517         var selector = $('hold_alt_form_selector');
518
519         for( var i = 0; i < avail_formats.length; i++ ) {
520                 var form = avail_formats[i];
521                 unHideMe(findSelectorOptByValue(selector, form));
522         }
523 }
524
525
526 function holdsGetFormats() {
527
528         var lang;
529         var formats = [];
530         var sformats = []; // selected formats 
531
532         var type = holdArgs.type;
533         var desc = holdArgs.recordDescriptors;
534         var rec = holdArgs.record;
535         var mrec = holdArgs.metarecord;
536
537         if( type == 'T' ) {
538
539                 for( var i = 0; i < desc.length; i++ ) {
540                         var d = desc[i];
541                         if( d.record() == holdArgs.record ) {
542                                 lang = d.item_lang();
543                                 holdArgs.myFormat =  _t_f_2_format(d.item_type(), d.item_form());
544                                 sformats.push(holdArgs.myFormat);
545                                 break;
546                         }
547                 }
548         }
549
550         for( var i = 0; i < desc.length; i++ ) {
551                 var d = desc[i];
552                 if( d.item_lang() != lang ) continue;
553                 formats.push( _t_f_2_format(d.item_type(), d.item_form()));
554         }
555
556         formats = uniquify(formats);
557
558         return {
559                 lang : lang,
560                 avail_formats : formats, 
561                 sel_formats : sformats
562         };
563 }
564
565
566
567 function _t_f_2_format(type, form) {
568         if( form == 'd' ) return 'at-d';
569         return (type == 'a' || type == 't') ? 'at' : 
570                 ( type == 'i' || type == 'g' || type == 'j' ) ? type : null;
571 }
572
573 function holdsSetSelectedFormats() {
574
575         var cn = $('holds_alt_formats_row').className;
576         if( cn && cn.match(/hide_me/) ) return;
577
578         var selector = $('hold_alt_form_selector');
579         var vals = getSelectedList(selector);
580
581         if(vals.length == 0) return;
582
583         var fstring = "";
584
585         if( contains(vals, 'at-d') ) {
586                 if( contains(vals, 'at') )
587                         fstring = 'at';
588                 else 
589                         fstring = 'at-d';
590         } else {
591                 if( contains(vals, 'at') )
592                         fstring = 'at';
593         }
594
595         for( var i = 0; i < vals.length; i++ ) {
596                 var val = vals[i];
597                 if( !val.match(/at/) ) fstring = val + fstring;
598         }
599
600         if( holdArgs.language ) {
601                 if( fstring.match(/-/) )
602                         fstring = fstring + '-' + holdArgs.language;
603                 else
604                         fstring = fstring + '--' + holdArgs.language;
605         }
606
607
608         return fstring;
609 }
610
611
612 function holdsCheckPossibility(pickuplib, hold, recurse) {
613
614         var args = { 
615                 titleid : holdArgs.record,
616                 volume_id : holdArgs.volume,
617                 copy_id : holdArgs.copy,
618                 hold_type : holdArgs.type,
619                 patronid : holdArgs.recipient.id(),
620                 depth : 0, 
621                 pickup_lib : pickuplib 
622         };
623
624         if(recurse) {
625                 /* if we're calling create again (recursing), 
626                         we know that the hold possibility check already succeeded */
627                 holdHandleCreateResponse({_recurse:true, _hold:hold}, true );
628
629         } else {
630                 _debug("hold possible args = "+js2JSON(args));
631         
632                 var req = new Request(CHECK_HOLD_POSSIBLE, G.user.session, args );
633         
634                 req.request.alertEvent = false;
635                 req.request._hold = hold;
636                 req.request._recurse = recurse;
637                 req.callback(holdHandleCreateResponse);
638                 req.send();
639         }
640 }
641
642
643 function holdsBuildOrgSelector(node) {
644
645         if(!node) node = globalOrgTree;
646     if(!isTrue(node.opac_visible())) return;
647
648         var selector = $('holds_org_selector');
649         var index = selector.options.length;
650
651         var type = findOrgType(node.ou_type());
652         var indent = type.depth() - 1;
653         var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
654         if(!type.can_have_users()) {
655                 opt.disabled = true;
656                 addCSSClass(opt, 'disabled_option');
657         }
658         
659         for( var i in node.children() ) {
660                 var child = node.children()[i];
661                 if(child) holdsBuildOrgSelector(child);
662         }
663 }
664
665 function holdsBuildHoldFromWindow() {
666
667         var org = getSelectorVal($('holds_org_selector'));
668         var node = findOrgUnit(org);
669         var ntype = findOrgType(node.ou_type());
670         if(!ntype.can_have_users()) {
671                 alertId('holds_pick_good_org');
672                 return;
673         }
674
675         var hold = new ahr();
676         if(holdArgs.editHold) {
677                 hold = holdArgs.editHold;
678                 holdArgs.editHold = null;
679         }
680
681         if( $('holds_enable_phone').checked ) {
682                 var phone = $('holds_phone').value;
683                 if( !phone || !phone.match(REGEX_PHONE) ) {
684                         alert($('holds_bad_phone').innerHTML);
685                         return null;
686                 }
687                 hold.phone_notify(phone);
688
689         } else {
690                 hold.phone_notify("");
691         }
692
693         if( $('holds_enable_email').checked ) 
694                 hold.email_notify(1);
695         else
696                 hold.email_notify(0);
697
698         var target;
699
700         switch(holdArgs.type) {
701                 case 'M':
702                         target = holdArgs.metarecord; break;
703                 case 'T':
704                         target = holdArgs.record; break;
705                 case 'V':
706                         target = holdArgs.volume; break;
707                 case 'C':
708                         target = holdArgs.copy; break;
709         }
710
711
712
713         hold.pickup_lib(org); 
714         //hold.request_lib(org); 
715         hold.requestor(holdArgs.requestor.id());
716         hold.usr(holdArgs.recipient.id());
717         hold.target(target);
718         hold.hold_type(holdArgs.type);
719
720     // see if this hold should be frozen and for how long
721     if($('holds_frozen_chkbox').checked) {
722         hold.frozen('t');
723         unHideMe($('hold_frozen_thaw_row'));
724         thawDate = dojo.date.stamp.toISOString(dijit.byId('holds_frozen_thaw_input').getValue());
725         if(thawDate) {
726             thawDate = holdsVerifyThawDate(thawDate); 
727             if(thawDate) 
728                 hold.thaw_date(thawDate);
729             else
730                 return;
731         } else {
732             hold.thaw_date(null);
733         }
734     } else {
735         hold.frozen('f');
736         hold.thaw_date(null);
737     }
738
739         //check for alternate hold formats 
740         var fstring = holdsSetSelectedFormats();
741         if(fstring) { 
742                 hold.hold_type('M'); 
743                 hold.holdable_formats(fstring);
744                 hold.target(holdArgs.metarecord);
745         }
746         return hold;
747 }
748         
749 function holdsPlaceHold(hold, recurse) {
750         if(!hold) return;
751         swapCanvas($('check_holds_box'));
752         holdsCheckPossibility(hold.pickup_lib(), hold, recurse);
753 }
754
755
756 function holdHandleCreateResponse(r, recurse) {
757
758         if(!recurse) {
759                 var res = r.getResultObject();
760                 if(checkILSEvent(res) || res.success != 1) {
761                         if(res.success != 1) {
762                                 alert($('hold_not_allowed').innerHTML);
763                         } else {
764                                 if( res.textcode == 'PATRON_BARRED' ) {
765                                         alertId('hold_failed_patron_barred');
766                         } else {
767                                         alert($('hold_not_allowed').innerHTML);
768                                 }
769                         }
770                         swapCanvas($('holds_box'));
771                         return;
772                 }
773         r._hold.selection_depth(res.depth);
774         }       
775
776         holdCreateHold(r._recurse, r._hold);
777 }
778
779
780 function holdCreateHold( recurse, hold ) {
781         var method = CREATE_HOLD;
782         if(recurse) method = CREATE_HOLD_OVERRIDE;
783         var req = new Request( method, holdArgs.requestor.session, hold );
784         req.request.alertEvent = false;
785         req.send(true);
786         var res = req.result();
787         holdProcessResult(hold, res, recurse);
788         
789         showCanvas();
790
791         runEvt('common', 'holdUpdated');
792 }
793
794
795 function holdProcessResult( hold, res, recurse ) {
796
797         if( res == '1' ) {
798                 alert($('holds_success').innerHTML);
799                 holdArgs = null;
800
801         } else {
802
803                 if( recurse ) {
804                         alert($('holds_failure').innerHTML);
805                         return;
806                 }
807
808                 if( grep(res, function(e) { return (e.textcode == 'HOLD_EXISTS'); }) ) {
809                         if( fetchPermOrgs('HOLD_EXISTS.override')[0] != -1 ) {
810                                 if( confirm($('hold_dup_exists_override').innerHTML) ) {
811                                         return holdsPlaceHold(hold, true);
812                                 }
813
814                         } else {
815                                 return alert($('hold_dup_exists').innerHTML);
816                         }
817                 }
818
819                 alert($('holds_failure').innerHTML);
820         }
821 }
822
823
824 function holdsCancel(holdid, user) {
825         if(!user) user = G.user;
826         var req = new Request(CANCEL_HOLD, user.session, holdid);
827         req.send(true);
828         return req.result();
829         runEvt('common', 'holdUpdated');
830 }
831
832 function holdsUpdate(hold, user) {
833         if(!user) user = G.user;
834         var req = new Request(UPDATE_HOLD, user.session, hold);
835         req.send(true);
836         var x = req.result(); // cause an exception if there is one 
837         runEvt('common', 'holdUpdated');
838 }
839
840 /* verify that the thaw date is valid and after today */
841 function holdsVerifyThawDate(dateString) {
842     thawDate = dojo.date.stamp.fromISOString(dateString);
843     if(thawDate && (dojo.date.compare(thawDate) > 0))
844         return dojo.date.stamp.toISOString(thawDate);
845     return null;
846 }
847
848 function holdsVerifyThawDateUI(element) {
849     value = dojo.date.stamp.toISOString(dijit.byId(element).getValue());
850
851     if(!value) {
852         removeCSSClass($(element), 'invalid_field');
853         return;
854     }
855
856     if(!holdsVerifyThawDate(value)) {
857         addCSSClass($(element), 'invalid_field');
858     } else {
859         removeCSSClass($(element), 'invalid_field');
860     }
861 }
862