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