]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/holds.js
paging interface for one of the hold pull lists, and lib filter infrastructure for...
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / holds.js
1 dump('entering patron.holds.js\n');
2
3 if (typeof patron == 'undefined') patron = {};
4 patron.holds = function (params) {
5
6         JSAN.use('util.error'); this.error = new util.error();
7         JSAN.use('util.network'); this.network = new util.network();
8         JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
9 }
10
11 patron.holds.prototype = {
12
13     'hold_interface_type' : null,
14
15     'pull_from_shelf_interface' : {
16         'default' : { 'limit' : 50, 'offset' : 0 },
17         'current' : { 'limit' : 50, 'offset' : 0 }
18     },
19
20         'filter_lib' : null,
21
22         'retrieve_ids' : [],
23
24         'holds_map' : {},
25
26         'init' : function( params ) {
27
28                 var obj = this;
29
30                 obj.patron_id = params['patron_id'];
31                 obj.docid = params['docid'];
32                 obj.shelf = params['shelf'];
33                 obj.tree_id = params['tree_id'];
34
35                 JSAN.use('circ.util');
36                 var columns = circ.util.hold_columns( 
37                         { 
38                                 'title' : { 'hidden' : false, 'flex' : '3' },
39                                 'request_time' : { 'hidden' : false },
40                                 'pickup_lib_shortname' : { 'hidden' : false },
41                                 'hold_type' : { 'hidden' : false },
42                                 'current_copy' : { 'hidden' : false },
43                                 'capture_time' : { 'hidden' : false },
44                                 'notify_time' : { 'hidden' : false },
45                                 'notify_count' : { 'hidden' : false },
46                         } 
47                 );
48
49                 JSAN.use('util.list'); obj.list = new util.list( obj.tree_id || 'holds_list');
50                 obj.list.init(
51                         {
52                                 'columns' : columns,
53                                 'map_row_to_columns' : circ.util.std_map_row_to_columns(),
54                                 'retrieve_row' : function(params) {
55                                         var row = params.row;
56                                         try {
57                                                 obj.network.simple_request('FM_AHR_BLOB_RETRIEVE', [ ses(), row.my.hold_id ],
58                                                         function(blob_req) {
59                                                                 try {
60                                                                         var blob = blob_req.getResultObject();
61                                                                         if (typeof blob.ilsevent != 'undefined') throw(blob);
62                                                                         row.my.ahr = blob.hold;
63                                                                         row.my.status = blob.status;
64                                                                         row.my.acp = blob.copy;
65                                                                         row.my.acn = blob.volume;
66                                                                         row.my.mvr = blob.mvr;
67                                                                         row.my.patron_family_name = blob.patron_last;
68                                                                         row.my.patron_first_given_name = blob.patron_first;
69                                                                         row.my.patron_barcode = blob.patron_barcode;
70
71                                                                         var copy_id = row.my.ahr.current_copy();
72                                                                         if (typeof copy_id == 'object') {
73                                                                                 if (copy_id == null) {
74                                                                                         if (typeof row.my.acp == 'object' && row.my.acp != null) copy_id = row.my.acp.id();
75                                                                                 } else {
76                                                                                         copy_id = copy_id.id();
77                                                                                 }
78                                                                         } else {
79                                                                                 copy_id = row.my.acp.id();
80                                                                         }
81
82                                                                         obj.holds_map[ row.my.ahr.id() ] = row.my.ahr;
83                                                                         params.row_node.setAttribute('retrieve_id', 
84                                                                                 js2JSON({
85                                                                                         'copy_id':copy_id,
86                                             'barcode':row.my.acp ? row.my.acp.barcode() : null,
87                                                                                         'id':row.my.ahr.id(),
88                                                                                         'type':row.my.ahr.hold_type(),
89                                                                                         'target':row.my.ahr.target(),
90                                                                                         'usr':row.my.ahr.usr(),
91                                                                                 })
92                                                                         );
93                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
94
95                                                                 } catch(E) {
96                                                                         obj.error.standard_unexpected_error_alert('Error retrieving details for hold #' + row.my.hold_id, E);
97                                                                 }
98                                                         }
99                                                 );
100                                         } catch(E) {
101                                                 obj.error.sdump('D_ERROR','retrieve_row: ' + E );
102                                         }
103                                         return row;
104                                 },
105                                 'on_select' : function(ev) {
106                                         JSAN.use('util.functional');
107                                         var sel = obj.list.retrieve_selection();
108                                         obj.controller.view.sel_clip.setAttribute('disabled',sel.length < 1);
109                                         obj.retrieve_ids = util.functional.map_list(
110                                                 sel,
111                                                 function(o) { return JSON2js( o.getAttribute('retrieve_id') ); }
112                                         );
113                                         if (obj.retrieve_ids.length > 0) {
114                                                 obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','false');
115                                                 obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');
116                                                 obj.controller.view.sel_copy_details.setAttribute('disabled','false');
117                                                 obj.controller.view.sel_patron.setAttribute('disabled','false');
118                                                 obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','false');
119                                                 obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','false');
120                                                 obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','false');
121                                                 obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','false');
122                                                 obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','false');
123                                                 obj.controller.view.cmd_holds_edit_thaw_date.setAttribute('disabled','false');
124                                                 obj.controller.view.cmd_holds_edit_freeze.setAttribute('disabled','false');
125                                                 obj.controller.view.cmd_show_notifications.setAttribute('disabled','false');
126                                                 obj.controller.view.cmd_holds_retarget.setAttribute('disabled','false');
127                                                 obj.controller.view.cmd_holds_cancel.setAttribute('disabled','false');
128                                                 obj.controller.view.cmd_show_catalog.setAttribute('disabled','false');
129                                         } else {
130                                                 obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','true');
131                                                 obj.controller.view.sel_mark_items_missing.setAttribute('disabled','true');
132                                                 obj.controller.view.sel_copy_details.setAttribute('disabled','true');
133                                                 obj.controller.view.sel_patron.setAttribute('disabled','true');
134                                                 obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','true');
135                                                 obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','true');
136                                                 obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','true');
137                                                 obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','true');
138                                                 obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','true');
139                                                 obj.controller.view.cmd_holds_edit_thaw_date.setAttribute('disabled','true');
140                                                 obj.controller.view.cmd_holds_edit_freeze.setAttribute('disabled','true');
141                                                 obj.controller.view.cmd_show_notifications.setAttribute('disabled','true');
142                                                 obj.controller.view.cmd_holds_retarget.setAttribute('disabled','true');
143                                                 obj.controller.view.cmd_holds_cancel.setAttribute('disabled','true');
144                                                 obj.controller.view.cmd_show_catalog.setAttribute('disabled','true');
145                                         }
146                                 },
147
148                         }
149                 );
150                 
151                 JSAN.use('util.controller'); obj.controller = new util.controller();
152                 obj.controller.init(
153                         {
154                                 'control_map' : {
155                                         'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
156                                         'sel_clip' : [
157                                                 ['command'],
158                                                 function() { obj.list.clipboard(); }
159                                         ],
160                                         'cmd_broken' : [
161                                                 ['command'],
162                                                 function() { alert('Not Yet Implemented'); }
163                                         ],
164                                         'sel_patron' : [
165                                                 ['command'],
166                                                 function() {
167                                                         JSAN.use('circ.util');
168                                                         circ.util.show_last_few_circs(obj.retrieve_ids);
169                                                 }
170                                         ],
171                                         'sel_mark_items_damaged' : [
172                                                 ['command'],
173                                                 function() {
174                                                         JSAN.use('cat.util'); JSAN.use('util.functional');
175                                                         cat.util.mark_item_damaged( util.functional.map_list( obj.retrieve_ids, function(o) { return o.copy_id; } ) );
176                                                 }
177                                         ],
178                                         'sel_mark_items_missing' : [
179                                                 ['command'],
180                                                 function() {
181                                                         JSAN.use('cat.util'); JSAN.use('util.functional');
182                                                         cat.util.mark_item_missing( util.functional.map_list( obj.retrieve_ids, function(o) { return o.copy_id; } ) );
183                                                 }
184                                         ],
185                                         'sel_copy_details' : [
186                                                 ['command'],
187                                                 function() {
188                                                         JSAN.use('circ.util');
189                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
190                                                                 if (obj.retrieve_ids[i].copy_id) circ.util.show_copy_details( obj.retrieve_ids[i].copy_id );
191                                                         }
192                                                 }
193                                         ],
194                                         'cmd_holds_print' : [
195                                                 ['command'],
196                                                 function() {
197                                                         try {
198                                                                 dump(js2JSON(obj.list.dump_with_keys()) + '\n');
199                                                                 function flesh_callback() {
200                                                                         try {
201                                                                                 JSAN.use('patron.util');
202                                                                                 var params = { 
203                                                                                         'patron' : patron.util.retrieve_au_via_id(ses(),obj.patron_id), 
204                                                                                         'lib' : obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ],
205                                                                                         'staff' : obj.data.list.au[0],
206                                                                                         'header' : obj.data.print_list_templates.holds.header,
207                                                                                         'line_item' : obj.data.print_list_templates.holds.line_item,
208                                                                                         'footer' : obj.data.print_list_templates.holds.footer,
209                                                                                         'type' : obj.data.print_list_templates.holds.type,
210                                                                                         'list' : obj.list.dump_with_keys(),
211                                                                                 };
212                                                                                 JSAN.use('util.print'); var print = new util.print();
213                                                                                 print.tree_list( params );
214                                                                                 setTimeout(function(){obj.list.on_all_fleshed = null;},0);
215                                                                         } catch(E) {
216                                                                                 obj.error.standard_unexpected_error_alert('print 2',E);
217                                                                         }
218                                                                 }
219                                                                 obj.list.on_all_fleshed = flesh_callback;
220                                                                 obj.list.full_retrieve();
221                                                         } catch(E) {
222                                                                 obj.error.standard_unexpected_error_alert('print 1',E);
223                                                         }
224                                                 }
225                                         ],
226                                         'cmd_holds_export' : [
227                                                 ['command'],
228                                                 function() {
229                                                         try {
230                                                                 function flesh_callback() {
231                                                                         try {
232                                                                                 dump(obj.list.dump_csv() + '\n');
233                                                                                 copy_to_clipboard(obj.list.dump_csv());
234                                                                                 setTimeout(function(){obj.list.on_all_fleshed = null;},0);
235                                                                         } catch(E) {
236                                                                                 obj.error.standard_unexpected_error_alert('export 2',E);
237                                                                         }
238                                                                 }
239                                                                 obj.list.on_all_fleshed = flesh_callback;
240                                                                 obj.list.full_retrieve();
241                                                         } catch(E) {
242                                                                 obj.error.standard_unexpected_error_alert('export 1',E);
243                                                         }
244                                                 }
245                                         ],
246
247                                         'cmd_show_notifications' : [
248                                                 ['command'],
249                                                 function() {
250                                                         try {
251                                                                 JSAN.use('util.window'); var win = new util.window();
252                                                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
253                                                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
254                                                                         win.open(
255                                                                                 xulG.url_prefix(urls.XUL_HOLD_NOTICES), // + '?ahr_id=' + obj.retrieve_ids[i].id,
256                                                                                 'hold_notices_' + obj.retrieve_ids[i].id,
257                                                                                 'chrome,resizable',
258                                                                                 { 'ahr_id' : obj.retrieve_ids[i].id }
259                                                                         );
260                                                                 }
261                                                         } catch(E) {
262                                                                 obj.error.standard_unexpected_error_alert('Error rendering/retrieving hold notifications.',E);
263                                                         }
264                                                 }
265                                         ],
266                                         'cmd_holds_edit_selection_depth' : [
267                                                 ['command'],
268                                                 function() {
269                                                         try {
270                                                                 JSAN.use('util.widgets'); JSAN.use('util.functional'); 
271                                                                 var ws_type = obj.data.hash.aout[ obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ].ou_type() ];
272                                                                 var list = util.functional.map_list(
273                                                                         util.functional.filter_list(    
274                                                                                 obj.data.list.aout,
275                                                                                 function(o) {
276                                                                                         if (o.depth() > ws_type.depth()) return false;
277                                                                                         if (o.depth() < ws_type.depth()) return true;
278                                                                                         return (o.id() == ws_type.id());
279                                                                                 }
280                                                                         ),
281                                                                         function(o) { 
282                                                                                 return [
283                                                                                         o.opac_label(),
284                                                                                         o.id(),
285                                                                                         false,
286                                                                                         ( o.depth() * 2),
287                                                                                 ]; 
288                                                                         }
289                                                                 );
290                                                                 ml = util.widgets.make_menulist( list, obj.data.list.au[0].ws_ou() );
291                                                                 ml.setAttribute('id','selection');
292                                                                 ml.setAttribute('name','fancy_data');
293                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
294                                                                 xml += '<description>Please choose a Hold Range:</description>';
295                                                                 xml += util.widgets.serialize_node(ml);
296                                                                 xml += '</vbox>';
297                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
298                                                                 bot_xml += '<spacer flex="1"/><button label="Done" accesskey="D" name="fancy_submit"/>';
299                                                                 bot_xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
300                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
301                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
302                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
303                                                                 JSAN.use('util.window'); var win = new util.window();
304                                                                 var fancy_prompt_data = win.open(
305                                                                         urls.XUL_FANCY_PROMPT,
306                                                                         //+ '?xml_in_stash=temp_mid'
307                                                                         //+ '&bottom_xml_in_stash=temp_bot'
308                                                                         //+ '&title=' + window.escape('Choose a Pick Up Library'),
309                                                                         'fancy_prompt', 'chrome,resizable,modal',
310                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Choose a Pick Up Library' }
311                                                                 );
312                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
313                                                                 var selection = fancy_prompt_data.selection;
314                                                                 var msg = 'Are you sure you would like to change the Hold Range for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + ' to "' + obj.data.hash.aout[selection].opac_label() + '"?';
315                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
316                                                                 if (r == 0) {
317                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
318                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
319                                                                                 hold.selection_depth( obj.data.hash.aout[selection].depth() ); hold.ischanged('1');
320                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
321                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
322                                                                         }
323                                                                         obj.clear_and_retrieve(true);
324                                                                 }
325                                                         } catch(E) {
326                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
327                                                         }
328                                                 }
329                                         ],
330
331                                         'cmd_holds_edit_pickup_lib' : [
332                                                 ['command'],
333                                                 function() {
334                                                         try {
335                                                                 JSAN.use('util.widgets'); JSAN.use('util.functional'); 
336                                                                 var list = util.functional.map_list(
337                                                                         obj.data.list.aou,
338                                                                         function(o) { 
339                                                                                 var sname = o.shortname(); for (i = sname.length; i < 20; i++) sname += ' ';
340                                                                                 return [
341                                                                                         o.name() ? sname + ' ' + o.name() : o.shortname(),
342                                                                                         o.id(),
343                                                                                         ( obj.data.hash.aout[ o.ou_type() ].can_have_users() == 0),
344                                                                                         ( obj.data.hash.aout[ o.ou_type() ].depth() * 2),
345                                                                                 ]; 
346                                                                         }
347                                                                 );
348                                                                 ml = util.widgets.make_menulist( list, obj.data.list.au[0].ws_ou() );
349                                                                 ml.setAttribute('id','lib');
350                                                                 ml.setAttribute('name','fancy_data');
351                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
352                                                                 xml += '<description>Please choose a new Pickup Library:</description>';
353                                                                 xml += util.widgets.serialize_node(ml);
354                                                                 xml += '</vbox>';
355                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
356                                                                 bot_xml += '<spacer flex="1"/><button label="Done" accesskey="D" name="fancy_submit"/>';
357                                                                 bot_xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
358                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
359                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
360                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
361                                                                 JSAN.use('util.window'); var win = new util.window();
362                                                                 var fancy_prompt_data = win.open(
363                                                                         urls.XUL_FANCY_PROMPT,
364                                                                         //+ '?xml_in_stash=temp_mid'
365                                                                         //+ '&bottom_xml_in_stash=temp_bot'
366                                                                         //+ '&title=' + window.escape('Choose a Pick Up Library'),
367                                                                         'fancy_prompt', 'chrome,resizable,modal',
368                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Choose a Pick Up Library' }
369                                                                 );
370                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
371                                                                 var pickup_lib = fancy_prompt_data.lib;
372                                                                 var msg = 'Are you sure you would like to change the Pick Up Lib for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + ' to ' + obj.data.hash.aou[pickup_lib].shortname() + '?';
373                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
374                                                                 if (r == 0) {
375                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
376                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
377                                                                                 hold.pickup_lib(  pickup_lib ); hold.ischanged('1');
378                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
379                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
380                                                                         }
381                                                                         obj.clear_and_retrieve(true);
382                                                                 }
383                                                         } catch(E) {
384                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
385                                                         }
386                                                 }
387                                         ],
388                                         'cmd_holds_edit_phone_notify' : [
389                                                 ['command'],
390                                                 function() {
391                                                         try {
392                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
393                                                                 xml += '<description>Please enter a new phone number for hold notification (leave the field empty to disable phone notification):</description>';
394                                                                 xml += '<textbox id="phone" name="fancy_data"/>';
395                                                                 xml += '</vbox>';
396                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
397                                                                 bot_xml += '<spacer flex="1"/><button label="Done" accesskey="D" name="fancy_submit"/>';
398                                                                 bot_xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
399                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
400                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
401                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
402                                                                 JSAN.use('util.window'); var win = new util.window();
403                                                                 var fancy_prompt_data = win.open(
404                                                                         urls.XUL_FANCY_PROMPT,
405                                                                         //+ '?xml_in_stash=temp_mid'
406                                                                         //+ '&bottom_xml_in_stash=temp_bot'
407                                                                         //+ '&title=' + window.escape('Choose a Hold Notification Phone Number')
408                                                                         //+ '&focus=phone',
409                                                                         'fancy_prompt', 'chrome,resizable,modal',
410                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Choose a Hold Notification Phone Number', 'focus' : 'phone' }
411                                                                 );
412                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
413                                                                 var phone = fancy_prompt_data.phone;
414                                                                 var msg = 'Are you sure you would like to change the Notification Phone Number for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + ' to "' + phone + '"?';
415                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
416                                                                 if (r == 0) {
417                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
418                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
419                                                                                 hold.phone_notify(  phone ); hold.ischanged('1');
420                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
421                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
422                                                                         }
423                                                                         obj.clear_and_retrieve(true);
424                                                                 }
425                                                         } catch(E) {
426                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
427                                                         }
428                                                 }
429                                         ],
430                                         'cmd_holds_edit_email_notify' : [
431                                                 ['command'],
432                                                 function() {
433                                                         try {
434                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
435                                                                 xml += '<description>Send email notifications (when appropriate)?  The email address used is found in the hold recipient account.</description>';
436                                                                 xml += '<hbox><button value="email" label="Email" accesskey="E" name="fancy_submit"/>';
437                                                                 xml += '<button value="noemail" label="No Email" accesskey="N" name="fancy_submit"/></hbox>';
438                                                                 xml += '</vbox>';
439                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
440                                                                 bot_xml += '<spacer flex="1"/><button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
441                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
442                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
443                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
444                                                                 JSAN.use('util.window'); var win = new util.window();
445                                                                 var fancy_prompt_data = win.open(
446                                                                         urls.XUL_FANCY_PROMPT,
447                                                                         //+ '?xml_in_stash=temp_mid'
448                                                                         //+ '&bottom_xml_in_stash=temp_bot'
449                                                                         //+ '&title=' + window.escape('Set Email Notification for Holds'),
450                                                                         'fancy_prompt', 'chrome,resizable,modal',
451                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Set Email Notification for Holds' }
452                                                                 );
453                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
454                                                                 var email = fancy_prompt_data.fancy_submit == 'email' ? get_db_true() : get_db_false();
455                                                                 var msg = 'Are you sure you would like ' + ( get_bool( email ) ? 'enable' : 'disable' ) + ' email notification for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '?';
456                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
457                                                                 if (r == 0) {
458                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
459                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
460                                                                                 hold.email_notify(  email ); hold.ischanged('1');
461                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
462                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
463                                                                         }
464                                                                         obj.clear_and_retrieve(true);
465                                                                 }
466                                                         } catch(E) {
467                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
468                                                         }
469                                                 }
470                                         ],
471                     'cmd_holds_edit_freeze' : [
472                                                 ['command'],
473                                                 function() {
474                                                         try {
475                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
476                                                                 xml += '<description>Freeze or un-freeze these holds?</description>';
477                                                                 xml += '<hbox><button value="freeze" label="Freeze" accesskey="F" name="fancy_submit"/>';
478                                                                 xml += '<button value="unfreeze" label="Un-Freeze" accesskey="U" name="fancy_submit"/></hbox>';
479                                                                 xml += '</vbox>';
480                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
481                                                                 bot_xml += '<spacer flex="1"/><button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
482                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
483                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
484                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
485                                                                 JSAN.use('util.window'); var win = new util.window();
486                                                                 var fancy_prompt_data = win.open(
487                                                                         urls.XUL_FANCY_PROMPT,
488                                                                         //+ '?xml_in_stash=temp_mid'
489                                                                         //+ '&bottom_xml_in_stash=temp_bot'
490                                                                         //+ '&title=' + window.escape('Set Email Notification for Holds'),
491                                                                         'fancy_prompt', 'chrome,resizable,modal',
492                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Set Email Notification for Holds' }
493                                                                 );
494                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
495                                                                 var freeze = fancy_prompt_data.fancy_submit == 'freeze' ? get_db_true() : get_db_false();
496                                                                 var msg = 'Are you sure you would like to ' + ( get_bool( freeze ) ? 'freeze' : 'un-freeze' ) + ' hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '?';
497                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
498                                                                 if (r == 0) {
499                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
500                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
501                                                                                 hold.frozen(  freeze ); 
502                                                                                 if ( ! get_bool( freeze ) ) {
503                                                                                         hold.thaw_date( null );
504                                                                                 }
505                                                                                 hold.ischanged('1');
506                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
507                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
508                                                                         }
509                                                                         obj.clear_and_retrieve(true);
510                                                                 }
511                                                         } catch(E) {
512                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
513                                                         }
514                                                 }
515                                         ],
516
517                     'cmd_holds_edit_thaw_date' : [
518                                                 ['command'],
519                                                 function() {
520                                                         try {
521                                 JSAN.use('util.date');
522                                 function check_date(value) {
523                                     try {
524                                         if (! util.date.check('YYYY-MM-DD',value) ) { throw('Invalid Date'); }
525                                         if (util.date.check_past('YYYY-MM-DD',value) ) { 
526                                             throw('Thaw date for frozen holds needs to be after today.'); 
527                                         }
528                                         return true;
529                                     } catch(E) {
530                                         alert(E);
531                                         return false;
532                                     }
533                                 }
534
535                                                                 var msg = 'Please enter a thaw date for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '\nOr set to blank to unset the thaw date for these holds.  Frozen holds without a thaw date will remain frozen until manually unfrozen, otherwise they unfreeze on the thaw date.';
536                                 var value = 'YYYY-MM-DD';
537                                 var title = 'Modifying Holds';
538                                                                 var thaw_date; var invalid = true;
539                                 while(invalid) {
540                                     thaw_date = window.prompt(msg,value,title);
541                                     if (thaw_date) {
542                                         invalid = ! check_date(thaw_date);
543                                     } else { 
544                                         invalid = false;
545                                     }
546                                 }
547                                 if (thaw_date || thaw_date == '') {
548                                     for (var i = 0; i < obj.retrieve_ids.length; i++) {
549                                         var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
550                                         hold.thaw_date(  thaw_date == '' ? null : util.date.formatted_date(thaw_date + ' 00:00:00','%{iso8601}') ); hold.ischanged('1');
551                                         var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
552                                         if (typeof robj.ilsevent != 'undefined') throw(robj);
553                                     }
554                                                                         obj.clear_and_retrieve(true);
555                                 }
556                                                         } catch(E) {
557                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
558                                                         }
559                                                 }
560                                         ],
561
562                                         'cmd_holds_retarget' : [
563                                                 ['command'],
564                                                 function() {
565                                                         try {
566                                                                 JSAN.use('util.functional');
567                                                                 var msg = 'Are you sure you would like to reset hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '?';
568                                                                 var r = obj.error.yns_alert(msg,'Resetting Holds','Yes','No',null,'Check here to confirm this message');
569                                                                 if (r == 0) {
570                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
571                                                                                 var robj = obj.network.simple_request('FM_AHR_RESET',[ ses(), obj.retrieve_ids[i].id]);
572                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
573                                                                         }
574                                                                         obj.clear_and_retrieve();
575                                                                 }
576                                                         } catch(E) {
577                                                                 obj.error.standard_unexpected_error_alert('Holds not likely reset.',E);
578                                                         }
579
580                                                 }
581                                         ],
582
583                                         'cmd_holds_cancel' : [
584                                                 ['command'],
585                                                 function() {
586                                                         try {
587                                                                 JSAN.use('util.functional');
588                                                                 var msg = 'Are you sure you would like to cancel hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '?';
589                                                                 var r = obj.error.yns_alert(msg,'Cancelling Holds','Yes','No',null,'Check here to confirm this message');
590                                                                 if (r == 0) {
591                                     var transits = [];
592                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
593                                         if (obj.holds_map[ obj.retrieve_ids[i].id ].transit()) {
594                                             transits.push( obj.retrieve_ids[i].barcode );
595                                         }
596                                                                                 var robj = obj.network.simple_request('FM_AHR_CANCEL',[ ses(), obj.retrieve_ids[i].id]);
597                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
598                                                                         }
599                                     if (transits.length > 0) {
600                                         var msg2 = 'For barcodes ' + transits.join(', ') + ' cancel the transits as well?';
601                                         var r2 = obj.error.yns_alert(msg2,'Cancelling Transits','Yes','No',null,'Check here to confirm this message');
602                                         if (r2 == 0) {
603                                             try {
604                                                 for (var i = 0; i < transits.length; i++) {
605                                                     var robj = obj.network.simple_request('FM_ATC_VOID',[ ses(), { 'barcode' : transits[i] } ]);
606                                                     if (typeof robj.ilsevent != 'undefined') {
607                                                         switch(robj.ilsevent) {
608                                                             case 1225 /* TRANSIT_ABORT_NOT_ALLOWED */ :
609                                                                 alert(robj.desc);
610                                                             break;
611                                                             case 5000 /* PERM_FAILURE */ :
612                                                             break;
613                                                             default:
614                                                                 throw(robj);
615                                                             break;
616                                                         }
617                                                                                             }
618                                                 }
619                                             } catch(E) {
620                                                                             obj.error.standard_unexpected_error_alert('Hold-transits not likely cancelled.',E);
621                                             }
622                                         }
623                                     }
624                                                                         obj.clear_and_retrieve();
625                                                                 }
626                                                         } catch(E) {
627                                                                 obj.error.standard_unexpected_error_alert('Holds not likely cancelled.',E);
628                                                         }
629                                                 }
630                                         ],
631                                         'cmd_retrieve_patron' : [
632                                                 ['command'],
633                                                 function() {
634                                                         try {
635                                                                 var seen = {};
636                                                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
637                                                                         var patron_id = obj.retrieve_ids[i].usr;
638                                                                         if (seen[patron_id]) continue; seen[patron_id] = true;
639                                                                         xulG.new_tab(
640                                                                                 xulG.url_prefix(urls.XUL_PATRON_DISPLAY), // + '?id=' + patron_id, 
641                                                                                 {}, 
642                                                                                 { 'id' : patron_id }
643                                                                         );
644                                                                 }
645                                                         } catch(E) {
646                                                                 obj.error.standard_unexpected_error_alert('',E);
647                                                         }
648                                                 }
649                                         ],
650                                         'cmd_show_catalog' : [
651                                                 ['command'],
652                                                 function() {
653                                                         try {
654                                                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
655                                                                         var htarget = obj.retrieve_ids[i].target;
656                                                                         var htype = obj.retrieve_ids[i].type;
657                                                                         var opac_url;
658                                                                         switch(htype) {
659                                                                                 case 'M' :
660                                                                                         opac_url = xulG.url_prefix( urls.opac_rresult ) + '?m=' + htarget;
661                                                                                 break;
662                                                                                 case 'T' : 
663                                                                                         opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + htarget;
664                                                                                 break;
665                                                                                 case 'V' :
666                                                                                         var my_acn = obj.network.simple_request( 'FM_ACN_RETRIEVE', [ htarget ]);
667                                                                                         opac_url = xulG.url_prefix( urls.opac_rdetail) + '?r=' + my_acn.record();
668                                                                                 break;
669                                                                                 case 'C' :
670                                                                                         var my_acp = obj.network.simple_request( 'FM_ACP_RETRIEVE', [ htarget ]);
671                                                                                         var my_acn;
672                                                                                         if (typeof my_acp.call_number() == 'object') {
673                                                                                                 my_acn = my.acp.call_number();
674                                                                                         } else {
675                                                                                                 my_acn = obj.network.simple_request( 'FM_ACN_RETRIEVE', 
676                                                                                                         [ my_acp.call_number() ]);
677                                                                                         }
678                                                                                         opac_url = xulG.url_prefix( urls.opac_rdetail) + '?r=' + my_acn.record();
679                                                                                 break;
680                                                                                 default:
681                                                                                         obj.error.standard_unexpected_error_alert("I don't understand the hold type of " + htype + ", so I can't jump to the appropriate record in the catalog.", obj.retrieve_ids[i]);
682                                                                                         continue;
683                                                                                 break;
684                                                                         }
685                                                                         var content_params = { 
686                                                                                 'session' : ses(),
687                                                                                 'authtime' : ses('authtime'),
688                                                                                 'opac_url' : opac_url,
689                                                                         };
690                                                                         xulG.new_tab(
691                                                                                 xulG.url_prefix(urls.XUL_OPAC_WRAPPER), 
692                                                                                 {'tab_name': htype == 'M' ? 'Catalog' : 'Retrieving title...'}, 
693                                                                                 content_params
694                                                                         );
695                                                                 }
696                                                         } catch(E) {
697                                                                 obj.error.standard_unexpected_error_alert('',E);
698                                                         }
699                                                 }
700                                         ],
701                     'fetch_more' : [
702                         ['command'],
703                         function() {
704                             obj.pull_from_shelf_interface.current.offset += obj.pull_from_shelf_interface.current.limit;
705                             obj.retrieve();
706                         }
707                     ],
708                     'lib_filter_checkbox' : [
709                         ['command'],
710                         function(ev) {
711                             var x_lib_type_menu = document.getElementById('lib_type_menu');
712                             if (x_lib_type_menu) x_lib_type_menu.disabled = ! ev.target.checked;
713                             if (obj.controller.view.lib_menu) obj.controller.view.lib_menu.disabled = ! ev.target.checked;
714                             obj.clear_and_retrieve();
715                             ev.target.setAttribute('checked',ev.target.checked);
716                         }
717                     ]
718                                 }
719                         }
720                 );
721         
722         obj.determine_hold_interface_type();
723         var x_fetch_more = document.getElementById('fetch_more');
724         var x_lib_type_menu = document.getElementById('lib_type_menu');
725         var x_lib_menu_placeholder = document.getElementById('lib_menu_placeholder');
726         var x_lib_filter_checkbox = document.getElementById('lib_filter_checkbox');
727         switch(obj.hold_interface_type) {
728             case 'shelf':
729                 obj.render_lib_menus({'pickup_lib':true});
730                 if (x_lib_type_menu) x_lib_type_menu.hidden = false;
731                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = false;
732             break;
733             case 'pull' :
734                 if (x_fetch_more) x_fetch_more.hidden = false;
735                 if (x_lib_type_menu) x_lib_type_menu.hidden = true;
736                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = true;
737             break;
738             case 'record' :
739                 obj.render_lib_menus({'pickup_lib':true,'request_lib':true});
740                 if (x_lib_filter_checkbox) x_lib_filter_checkbox.hidden = false;
741                 if (x_lib_type_menu) x_lib_type_menu.hidden = false;
742                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = false;
743             break;
744             default:
745                 if (x_fetch_more) x_fetch_more.hidden = true;
746                 if (x_lib_type_menu) x_lib_type_menu.hidden = true;
747                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = true;
748             break;
749         }
750         setTimeout( // We do this because render_lib_menus above creates and appends a DOM node, but until this thread exits, it doesn't really happen
751             function() {
752                 if (x_lib_filter_checkbox) if (!x_lib_filter_checkbox.checked) {
753                     if (x_lib_type_menu) x_lib_type_menu.disabled = true;
754                     if (obj.controller.view.lib_menu) obj.controller.view.lib_menu.disabled = true;
755                 }
756                 obj.controller.render();
757                 obj.retrieve();
758
759                 obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','true');
760                 obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','true');
761                 obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','true');
762                 obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','true');
763                 obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','true');
764                 obj.controller.view.cmd_show_notifications.setAttribute('disabled','true');
765                 obj.controller.view.cmd_holds_retarget.setAttribute('disabled','true');
766                 obj.controller.view.cmd_holds_cancel.setAttribute('disabled','true');
767                 obj.controller.view.cmd_show_catalog.setAttribute('disabled','true');
768             }, 0
769         );
770         },
771
772     'determine_hold_interface_type' : function() {
773                 var obj = this;
774         if (obj.patron_id) { /*************************************************** PATRON ******************************/
775             obj.hold_interface_type = 'patron';
776                 } else if (obj.docid) { /*************************************************** RECORD ******************************/
777             obj.hold_interface_type = 'record';
778                 } else if (obj.pull) { /*************************************************** PULL ******************************/
779             obj.hold_interface_type = 'pull';
780                 } else if (obj.shelf) { /*************************************************** HOLD SHELF ******************************/
781             obj.hold_interface_type = 'shelf';
782                 } else { /*************************************************** PULL ******************************/
783             obj.hold_interface_type = 'pull';
784                 }
785     },
786
787     'clear_and_retrieve' : function(dont_show_me_the_list_change) {
788         this.list.clear();
789         this.pull_from_shelf_interface.current.offset = this.pull_from_shelf_interface.default.offset;
790         this.retrieve(dont_show_me_the_list_change);
791     },
792
793         'retrieve' : function(dont_show_me_the_list_change) {
794                 var obj = this; var holds = [];
795                 if (window.xulG && window.xulG.holds) {
796                         holds = window.xulG.holds;
797                 } else {
798                         var method; var params = [ ses() ];
799             switch(obj.hold_interface_type) {
800                 case 'patron' :
801                                     method = 'FM_AHR_ID_LIST_RETRIEVE_VIA_AU'; 
802                                 params.push( obj.patron_id ); 
803                                 obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','true');
804                 break;
805                 case 'record' :
806                                     method = 'FM_AHR_RETRIEVE_ALL_VIA_BRE'; 
807                                 params.push( obj.docid ); 
808                     var x_lib_filter = document.getElementById('lib_filter_checkbox');
809                     var x_lib_type_menu = document.getElementById('lib_type_menu');
810                     if (x_lib_filter) {
811                         if (x_lib_filter.checked) {
812                             if (x_lib_type_menu && obj.controller.view.lib_menu) {
813                                 var x = {};
814                                 x[ x_lib_type_menu.value ] = obj.controller.view.lib_menu.value;
815                                 params.push( x );
816                             } else { alert('3'); }
817                         } else { alert('2'); }
818                     } else { alert('1'); }
819                                 obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
820                 break;
821                 case 'shelf' : 
822                                     method = 'FM_AHR_ID_LIST_ONSHELF_RETRIEVE';
823                     params.push( obj.filter_lib || obj.data.list.au[0].ws_ou() ); 
824                                 obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
825                 break;
826                 case 'pull' : 
827                 default:
828                                     method = 'FM_AHR_ID_LIST_PULL_LIST'; 
829                                 params.push( obj.pull_from_shelf_interface.current.limit ); params.push( obj.pull_from_shelf_interface.current.offset );
830                                     //obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
831                 break;
832                         }
833                         var robj = obj.network.simple_request( method, params );
834                         if (typeof robj.ilsevent != 'undefined') throw(robj);
835                         if (method == 'FM_AHR_RETRIEVE_ALL_VIA_BRE') {
836                                 holds = [];
837                                 holds = holds.concat( robj.copy_holds );
838                                 holds = holds.concat( robj.volume_holds );
839                                 holds = holds.concat( robj.title_holds );
840                                 holds = holds.sort();
841                         } else {
842                                 holds = robj;
843                         }
844                         //alert('method = ' + method + ' params = ' + js2JSON(params));
845                 }
846
847         var x_fetch_more = document.getElementById('fetch_more');
848         if (holds.length == 0) {
849             if (x_fetch_more) x_fetch_more.disabled = true;
850         } else {
851             if (x_fetch_more) x_fetch_more.disabled = false;
852             obj.render(holds,dont_show_me_the_list_change);
853         }
854
855     },
856
857     'render' : function(holds,dont_show_me_the_list_change) {
858         var obj = this;
859
860                 function list_append(hold_id) {
861                         obj.list.append(
862                                 {
863                                         'row' : {
864                                                 'my' : {
865                                                         'hold_id' : hold_id,
866                                                 }
867                                         }
868                                 }
869                         );
870                 }
871
872                 function gen_list_append(hold) {
873                         return function() {
874                                 if (typeof obj.controller.view.lib_menu == 'undefined') {
875                                         list_append(typeof hold == 'object' ? hold.id() : hold);
876                                 } else {
877                                         list_append(typeof hold == 'object' ? hold.id() : hold);
878                                 }
879                         };
880                 }
881
882                 //obj.list.clear();
883
884                 JSAN.use('util.exec'); var exec = new util.exec(2);
885                 var rows = [];
886                 for (var i in holds) {
887                         rows.push( gen_list_append(holds[i]) );
888                 }
889                 exec.chain( rows );
890         
891                 if (!dont_show_me_the_list_change) {
892                         if (window.xulG && typeof window.xulG.on_list_change == 'function') {
893                                 try { window.xulG.on_list_change(holds); } catch(E) { this.error.sdump('D_ERROR',E); }
894                         }
895                 }
896         },
897
898         'render_lib_menus' : function(types) {
899                 try {
900                         var obj = this;
901                         JSAN.use('util.widgets'); JSAN.use('util.functional'); JSAN.use('util.fm_utils');
902
903             var x = document.getElementById('lib_type_menu');
904             if (types) {
905                 var nodes = x.firstChild.childNodes;
906                 for (var i = 0; i < nodes.length; i++) nodes[i].hidden = true;
907                 for (var i in types) document.getElementById(i).hidden = false;
908             }
909             x.setAttribute('oncommand','g.holds.clear_and_retrieve()');
910
911                         x = document.getElementById('lib_menu_placeholder');
912                         util.widgets.remove_children( x );
913
914             JSAN.use('util.file');
915                         var file = new util.file('offline_ou_list'); 
916                         if (file._file.exists()) {
917                                 var list_data = file.get_object(); file.close();
918                                 var ml = util.widgets.make_menulist( list_data[0], obj.data.list.au[0].ws_ou() );
919                 ml.setAttribute('id','lib_menu');
920                 x.appendChild( ml );
921                         ml.addEventListener(
922                                 'command',
923                                 function(ev) {
924                                         obj.filter_lib = ev.target.value;
925                                         obj.clear_and_retrieve();
926                                 },
927                                 false
928                         );
929                         obj.controller.view.lib_menu = ml;
930                         } else {
931                                 throw('Missing library list.\n');
932                         }
933
934                 } catch(E) {
935                         this.error.standard_unexpected_error_alert('rendering lib menu',E);
936                 }
937         },
938 }
939
940 dump('exiting patron.holds.js\n');