7 function $(id) { return document.getElementById(id); }
11 /******************************************************************************************************/
12 /* setup JSAN and some initial libraries */
14 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
15 if (typeof JSAN == 'undefined') {
16 throw( $('commonStrings').getString('common.jsan.missing') );
18 JSAN.errorLevel = "die"; // none, warn, or die
19 JSAN.addRepository('/xul/server/');
20 JSAN.use('util.error'); g.error = new util.error();
21 g.error.sdump('D_TRACE','my_init() for cat/copy_editor.xul');
23 JSAN.use('util.functional');
24 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
25 JSAN.use('util.network'); g.network = new util.network();
27 g.docid = xul_param('docid',{'modal_xulG':true});
28 g.handle_update = xul_param('handle_update',{'modal_xulG':true});
30 /******************************************************************************************************/
31 /* Get the copy ids from various sources and flesh them */
33 var copy_ids = xul_param('copy_ids',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xulG':true,'JSON2js_if_xpcom':true,'stash_name':'temp_copy_ids','clear_xpcom':true,'modal_xulG':true});
34 if (!copy_ids) copy_ids = [];
36 if (copy_ids.length > 0) g.copies = g.network.simple_request(
37 'FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative',
41 /******************************************************************************************************/
42 /* And other fleshed copies if any */
44 if (!g.copies) g.copies = [];
45 var c = xul_param('copies',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_copies','clear_xpcom':true,'modal_xulG':true})
46 if (c) g.copies = g.copies.concat(c);
48 /******************************************************************************************************/
49 /* We try to retrieve callnumbers for existing copies, but for new copies, we rely on this */
51 g.callnumbers = xul_param('callnumbers',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_callnumbers','clear_xpcom':true,'modal_xulG':true});
54 /******************************************************************************************************/
55 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
59 /******************************************************************************************************/
60 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
62 if (xul_param('edit',{'modal_xulG':true}) == '1') {
64 // Editor desired, but let's check permissions
68 var check = g.network.simple_request(
69 'PERM_MULTI_ORG_CHECK',
72 g.data.list.au[0].id(),
73 util.functional.map_list(
77 var cn_id = o.call_number();
79 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
81 if (! g.map_acn[ cn_id ]) {
82 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
83 if (typeof req.ilsevent == 'undefined') {
84 g.map_acn[ cn_id ] = req;
85 lib = g.map_acn[ cn_id ].owning_lib();
90 lib = g.map_acn[ cn_id ].owning_lib();
93 return typeof lib == 'object' ? lib.id() : lib;
96 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
99 g.edit = check.length == 0;
101 g.error.standard_unexpected_error_alert('batch permission check',E);
105 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
106 $('save').setAttribute('hidden','false');
107 g.retrieve_templates();
109 $('top_nav').setAttribute('hidden','true');
112 $('top_nav').setAttribute('hidden','true');
115 if (g.copies.length > 0 && g.copies[0].id() < 0) {
116 document.getElementById('copy_notes').setAttribute('hidden','true');
117 g.apply("status",5 /* In Process */);
118 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
120 g.panes_and_field_names.left_pane =
123 $('catStrings').getString('staff.cat.copy_editor.status'),
125 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
126 input: g.safe_to_edit_copy_status() ? 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.ccs, function(obj) { return [ obj.name(), obj.id(), typeof my_constants.magical_statuses[obj.id()] != "undefined" ? true : false ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);' : undefined,
127 //input: 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( util.functional.filter_list( g.data.list.ccs, function(obj) { return typeof my_constants.magical_statuses[obj.id()] == "undefined"; } ), function(obj) { return [ obj.name(), obj.id() ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
130 ].concat(g.panes_and_field_names.left_pane);
133 if (g.copies.length != 1) {
134 document.getElementById('copy_notes').setAttribute('hidden','true');
137 /******************************************************************************************************/
138 /* Show the Record Details? */
141 document.getElementById('brief_display').setAttribute(
143 urls.XUL_BIB_BRIEF + '?docid=' + g.docid
146 document.getElementById('brief_display').setAttribute('hidden','true');
149 /******************************************************************************************************/
150 /* Add stat cats to the panes_and_field_names.right_pane4 */
152 g.populate_stat_cats();
154 /******************************************************************************************************/
155 /* Backup copies :) */
157 g.original_copies = js2JSON( g.copies );
159 /******************************************************************************************************/
162 g.summarize( g.copies );
166 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
167 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
172 /******************************************************************************************************/
173 /* Retrieve Templates */
175 g.retrieve_templates = function() {
177 JSAN.use('util.widgets'); JSAN.use('util.functional');
179 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
180 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
181 g.templates = robj['staff_client.copy_editor.templates'];
183 util.widgets.remove_children('template_placeholder');
184 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
186 g.template_menu = util.widgets.make_menulist( list );
187 g.template_menu.setAttribute('id','template_menu');
188 $('template_placeholder').appendChild(g.template_menu);
189 g.template_menu.addEventListener(
191 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
195 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
199 /******************************************************************************************************/
202 g.apply_template = function() {
204 var name = g.template_menu.value;
205 if (g.templates[ name ] != 'undefined') {
206 var template = g.templates[ name ];
207 for (var i in template) {
208 g.changed[ i ] = template[ i ];
209 switch( template[i].type ) {
211 g.apply(template[i].field,template[i].value);
214 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
217 g.apply_owning_lib(template[i].value);
221 g.summarize( g.copies );
225 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
229 /******************************************************************************************************/
230 /* Save as Template */
232 g.save_template = function() {
234 var name = window.prompt(
235 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
237 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
240 g.templates[name] = g.changed;
241 var robj = g.network.simple_request(
242 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
244 if (typeof robj.ilsevent != 'undefined') {
247 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
251 g.retrieve_templates();
253 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
259 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
263 /******************************************************************************************************/
264 /* Delete Template */
266 g.delete_template = function() {
268 var name = g.template_menu.value;
270 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name])) return;
271 delete(g.templates[name]);
272 var robj = g.network.simple_request(
273 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
275 if (typeof robj.ilsevent != 'undefined') {
278 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
282 g.retrieve_templates();
284 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
290 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
294 /******************************************************************************************************/
295 /* Export Templates */
297 g.export_templates = function() {
299 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
300 JSAN.use('util.file'); var f = new util.file('');
301 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
303 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
307 /******************************************************************************************************/
308 /* Import Templates */
310 g.import_templates = function() {
312 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
313 JSAN.use('util.file'); var f = new util.file('');
314 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
316 for (var i in temp) {
318 if (g.templates[i]) {
320 var r = g.error.yns_alert(
321 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
322 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
323 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
324 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
326 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
329 if (r == 0 /* Yes */) g.templates[i] = temp[i];
333 g.templates[i] = temp[i];
339 var r = g.error.yns_alert(
340 'Save all of these imported templates permanently to this account?',
341 'Final Warning', 'Yes', 'No', null, 'Click here'
344 if (r == 0 /* Yes */) {
345 var robj = g.network.simple_request(
346 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
348 if (typeof robj.ilsevent != 'undefined') {
351 alert('All templates saved.');
355 g.retrieve_templates();
357 g.error.standard_unexpected_error_alert('Error saving templates',E);
363 util.widgets.remove_children('template_placeholder');
364 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
365 g.template_menu = util.widgets.make_menulist( list );
366 $('template_placeholder').appendChild(g.template_menu);
367 alert("Note: These imported templates will get saved along with any new template you try to create, but if that doesn't happen, then these templates will disappear with the next invocation of the item attribute editor.");
372 g.error.standard_unexpected_error_alert('Error importing templates',E);
377 /******************************************************************************************************/
378 /* Restore backup copies */
380 g.reset = function() {
382 g.copies = JSON2js( g.original_copies );
383 g.summarize( g.copies );
387 /******************************************************************************************************/
388 /* Apply a value to a specific field on all the copies being edited */
390 g.apply = function(field,value) {
391 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
392 if (value == '<HACK:KLUDGE:NULL>') value = null;
393 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
394 if (field == 'price' || field == 'deposit_amount') {
395 if (value == '') { value = null; } else { JSAN.use('util.money'); value = util.money.sanitize( value ); }
397 for (var i = 0; i < g.copies.length; i++) {
398 var copy = g.copies[i];
400 copy[field]( value ); copy.ischanged('1');
407 /******************************************************************************************************/
408 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
410 g.apply_stat_cat = function(sc_id,entry_id) {
411 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
412 for (var i = 0; i < g.copies.length; i++) {
413 var copy = g.copies[i];
416 var temp = copy.stat_cat_entries();
417 if (!temp) temp = [];
418 temp = util.functional.filter_list(
421 return (obj.stat_cat() != sc_id);
424 if (entry_id > -1) temp.push(
425 util.functional.find_id_object_in_list(
426 g.data.hash.asc[sc_id].entries(),
430 copy.stat_cat_entries( temp );
433 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
438 /******************************************************************************************************/
439 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
441 g.apply_owning_lib = function(ou_id) {
442 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
443 for (var i = 0; i < g.copies.length; i++) {
444 var copy = g.copies[i];
446 if (!g.map_acn[copy.call_number()]) {
447 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
448 if (typeof volume.ilsevent != 'undefined') {
449 g.error.standard_unexpected_error_alert('Error retrieving Volume information for copy ' + copy.barcode() + ". The owning library for this copy won't be changed.",volume);
452 g.map_acn[copy.call_number()] = volume;
454 var old_volume = g.map_acn[copy.call_number()];
455 var acn_id = g.network.simple_request(
456 'FM_ACN_FIND_OR_CREATE',
457 [ses(),old_volume.label(),old_volume.record(),ou_id]
459 if (typeof acn_id.ilsevent != 'undefined') {
460 g.error.standard_unexpected_error_alert('Error changing owning lib for copy ' + copy.barcode() + ". The owning library for this copy won't be changed.",acn_id);
463 copy.call_number(acn_id);
466 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
471 /******************************************************************************************************/
472 /* This returns true if none of the copies being edited are pre-cats */
474 g.safe_to_change_owning_lib = function() {
477 for (var i = 0; i < g.copies.length; i++) {
478 var cn = g.copies[i].call_number();
479 if (typeof cn == 'object') { cn = cn.id(); }
480 if (cn == -1) { safe = false; }
484 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
489 /******************************************************************************************************/
490 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
492 g.safe_to_edit_copy_status = function() {
495 for (var i = 0; i < g.copies.length; i++) {
496 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
497 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
501 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
506 /******************************************************************************************************/
507 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
509 g.populate_alert_message_input = function(tb) {
511 var seen = {}; var s = '';
512 for (var i = 0; i < g.copies.length; i++) {
513 var msg = g.copies[i].alert_message();
515 if (typeof seen[msg] == 'undefined') {
521 tb.setAttribute('value',s);
523 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
527 /***************************************************************************************************************/
528 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
530 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
531 g.data.stash_retrieve();
532 var label = 'acpl_list_for_lib_'+lib_id;
533 if (typeof g.data[label] == 'undefined') {
534 var robj = g.network.simple_request('FM_ACPL_RETRIEVE', [ lib_id ]); // This returns acpl's for all ancestors and descendants as well as the lib
535 if (typeof robj.ilsevent != 'undefined') throw(robj);
537 for (var j = 0; j < robj.length; j++) {
538 var my_acpl = robj[j];
539 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
540 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
541 g.data.list.acpl.push( my_acpl );
543 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
544 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
545 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
546 temp_list.push( my_acpl );
549 g.data[label] = temp_list; g.data.stash(label,'hash','list');
551 return g.data[label];
554 /******************************************************************************************************/
555 /* This returns a list of acpl's appropriate for the copies being edited */
557 g.get_acpl_list = function() {
560 JSAN.use('util.functional');
564 /**************************************/
565 /* get owning libs from call numbers */
567 var owning_libs = {};
568 for (var i = 0; i < g.copies.length; i++) {
569 var callnumber = g.copies[i].call_number();
570 if (!callnumber) continue;
571 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
573 if (! g.map_acn[ cn_id ]) {
574 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
575 if (typeof req.ilsevent == 'undefined') {
576 g.map_acn[ cn_id ] = req;
581 var consider_lib = g.map_acn[ cn_id ].owning_lib();
582 if (!consider_lib) continue;
583 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
587 for (var i in g.callnumbers) {
588 var consider_lib = g.callnumbers[i].owning_lib;
589 if (!consider_lib) continue;
590 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
594 /***************************************************************************************************/
595 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
597 JSAN.use('util.fm_utils');
598 var libs = []; for (var i in owning_libs) libs.push(i);
599 if (libs.length > 0) {
600 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
601 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
604 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
605 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
606 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
607 if (acpl_list[i] != null) {
608 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
619 for (var i = 0; i < g.copies.length; i++) {
620 var consider_lib = g.copies[i].circ_lib();
621 if (!consider_lib) continue;
622 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
625 /***************************************************************************************************/
626 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
628 libs = []; for (var i in circ_libs) libs.push(i);
629 if (libs.length > 0) {
630 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
631 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
634 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
635 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
636 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
637 if (acpl_list[i] != null) {
638 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
644 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
645 return acpl_list.sort(
647 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
648 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
649 if (label_a < label_b) return -1;
650 if (label_a > label_b) return 1;
656 g.error.standard_unexpected_error_alert('get_acpl_list',E);
662 /******************************************************************************************************/
663 /* This keeps track of what fields have been edited for styling purposes */
667 /******************************************************************************************************/
668 /* These need data from the middle layer to render */
670 g.special_exception = {
671 'Owning Lib : Call Number' : function(label,value) {
672 JSAN.use('util.widgets');
673 if (value>0) { /* an existing call number */
674 g.network.simple_request(
675 'FM_ACN_RETRIEVE.authoritative',
678 var cn = '??? id = ' + value;
680 cn = req.getResultObject();
682 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
684 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
687 } else { /* a yet to be created call number */
689 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
693 'Creator' : function(label,value) {
694 if (value == null || value == '' || value == 'null') return;
695 g.network.simple_request(
696 'FM_AU_RETRIEVE_VIA_ID',
699 var p = '??? id = ' + value;
701 p = req.getResultObject();
705 g.error.sdump('D_ERROR','patron retrieve: ' + E);
707 JSAN.use('util.widgets');
708 util.widgets.set_text(label,p);
712 'Last Editor' : function(label,value) {
713 if (value == null || value == '' || value == 'null') return;
714 g.network.simple_request(
715 'FM_AU_RETRIEVE_VIA_ID',
718 var p = '??? id = ' + value;
720 p = req.getResultObject();
724 g.error.sdump('D_ERROR','patron retrieve: ' + E);
726 util.widgets.set_text(label,p);
733 /******************************************************************************************************/
734 g.readonly_stat_cat_names = [];
735 g.editable_stat_cat_names = [];
737 /******************************************************************************************************/
738 /* These get show in the left panel */
740 function init_panes() {
741 g.panes_and_field_names = {
748 render: 'fm.barcode();',
754 render: 'util.date.formatted_date( fm.create_date(), "%F");',
760 render: 'fm.creator();',
766 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
772 render: 'fm.editor();',
783 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
784 input: 'c = function(v){ g.apply("location",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.get_acpl_list(), function(obj) { return [ g.data.hash.aou[ obj.owning_lib() ].shortname() + " : " + obj.name(), obj.id() ]; }).sort()); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
789 "Circulation Library",
791 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
792 //input: 'c = function(v){ g.apply("circ_lib",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( util.functional.filter_list(g.data.list.my_aou, function(obj) { return g.data.hash.aout[ obj.ou_type() ].can_have_vols(); }), function(obj) { return [ obj.shortname(), obj.id() ]; }).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
793 input: 'c = function(v){ g.apply("circ_lib",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.aou, function(obj) { var sname = obj.shortname(); for (i = sname.length; i < 20; i++) sname += " "; return [ obj.name() ? sname + " " + obj.name() : obj.shortname(), obj.id(), ( ! get_bool( g.data.hash.aout[ obj.ou_type() ].can_have_vols() ) ), ( g.data.hash.aout[ obj.ou_type() ].depth() * 2), ]; }), g.data.list.au[0].ws_ou()); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
797 "Owning Lib : Call Number",
799 render: 'fm.call_number();',
800 input: g.safe_to_change_owning_lib() ? 'c = function(v){ g.apply_owning_lib(v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.aou, function(obj) { var sname = obj.shortname(); for (i = sname.length; i < 20; i++) sname += " "; return [ obj.name() ? sname + " " + obj.name() : obj.shortname(), obj.id(), ( ! get_bool( g.data.hash.aout[ obj.ou_type() ].can_have_vols() ) ), ( g.data.hash.aout[ obj.ou_type() ].depth() * 2), ]; }), g.data.list.au[0].ws_ou()); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);' : undefined,
806 render: 'fm.copy_number() == null ? "<Unset>" : fm.copy_number()',
807 input: 'c = function(v){ g.apply("copy_number",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
819 render: 'fm.circulate() == null ? "<Unset>" : ( get_bool( fm.circulate() ) ? "Yes" : "No" )',
820 input: 'c = function(v){ g.apply("circulate",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "Yes", get_db_true() ], [ "No", get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
826 render: 'fm.holdable() == null ? "<Unset>" : ( get_bool( fm.holdable() ) ? "Yes" : "No" )',
827 input: 'c = function(v){ g.apply("holdable",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "Yes", get_db_true() ], [ "No", get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
833 render: 'fm.age_protect() == null ? "<Unset>" : ( typeof fm.age_protect() == "object" ? fm.age_protect().name() : g.data.hash.crahp[ fm.age_protect() ].name() )',
834 input: 'c = function(v){ g.apply("age_protect",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "<Remove Protection>", "<HACK:KLUDGE:NULL>" ] ].concat( util.functional.map_list( g.data.list.crahp, function(obj) { return [ obj.name(), obj.id() ]; }).sort() ) ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
841 render: 'switch(Number(fm.loan_duration())){ case 1: "Short"; break; case 2: "Normal"; break; case 3: "Long"; break; }',
842 input: 'c = function(v){ g.apply("loan_duration",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "Short", "1" ], [ "Normal", "2" ], [ "Long", "3" ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
849 render: 'switch(Number(fm.fine_level())){ case 1: "Low"; break; case 2: "Normal"; break; case 3: "High"; break; }',
850 input: 'c = function(v){ g.apply("fine_level",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "Low", "1" ], [ "Normal", "2" ], [ "High", "3" ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
857 render: 'fm.circ_as_type() == null ? "<Unset>" : g.data.hash.citm[ fm.circ_as_type() ].value()',
858 input: 'c = function(v){ g.apply("circ_as_type",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.citm, function(n){return [ n.code() + " - " + n.value(), n.code()];} ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
862 "Circulation Modifier",
864 render: 'fm.circ_modifier() == null ? "<Unset>" : fm.circ_modifier()',
865 /*input: 'c = function(v){ g.apply("circ_modifier",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',*/
866 input: 'c = function(v){ g.apply("circ_modifier",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.circ_modifier, function(obj) { return [ obj, obj ]; } ).sort() ); x.setAttribute("editable","true"); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
875 render: 'fm.alert_message() == null ? "<Unset>" : fm.alert_message()',
876 input: 'c = function(v){ g.apply("alert_message",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.setAttribute("multiline",true); g.populate_alert_message_input(x); x.addEventListener("apply",function(f){ return function(ev) { f( ev.target.value ); } }(c), false);',
883 render: 'fm.deposit() == null ? "<Unset>" : ( get_bool( fm.deposit() ) ? "Yes" : "No" )',
884 input: 'c = function(v){ g.apply("deposit",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "Yes", get_db_true() ], [ "No", get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
890 render: 'if (fm.deposit_amount() == null) { "<Unset>"; } else { util.money.sanitize( fm.deposit_amount() ); }',
891 input: 'c = function(v){ g.apply("deposit_amount",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
897 render: 'if (fm.price() == null) { "<Unset>"; } else { util.money.sanitize( fm.price() ); }',
898 input: 'c = function(v){ g.apply("price",v); if (typeof post_c == "function") post_c(v); }; x = document.createElement("textbox"); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
905 render: 'fm.opac_visible() == null ? "<Unset>" : ( get_bool( fm.opac_visible() ) ? "Yes" : "No" )',
906 input: 'c = function(v){ g.apply("opac_visible",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "Yes", get_db_true() ], [ "No", get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
912 render: 'fm.ref() == null ? "<Unset>" : ( get_bool( fm.ref() ) ? "Yes" : "No" )',
913 input: 'c = function(v){ g.apply("ref",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "Yes", get_db_true() ], [ "No", get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
925 /******************************************************************************************************/
926 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
928 g.summarize = function( copies ) {
929 /******************************************************************************************************/
932 JSAN.use('util.date'); JSAN.use('util.money');
935 for (var i in g.panes_and_field_names) {
936 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
938 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
939 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
941 /******************************************************************************************************/
942 /* Loop through the field names */
944 for (var i = 0; i < g.field_names.length; i++) {
946 var field_name = g.field_names[i][0];
947 var render = g.field_names[i][1].render;
948 var attr = g.field_names[i][1].attr;
949 g.summary[ field_name ] = {};
951 /******************************************************************************************************/
952 /* Loop through the copies */
954 for (var j = 0; j < copies.length; j++) {
957 var cmd = render || ('fm.' + field_name + '();');
960 /**********************************************************************************************/
961 /* Try to retrieve the value for this field for this copy */
966 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
968 if (typeof value == 'object' && value != null) {
969 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
972 /**********************************************************************************************/
973 /* Tally the count */
975 if (g.summary[ field_name ][ value ]) {
976 g.summary[ field_name ][ value ]++;
978 g.summary[ field_name ][ value ] = 1;
982 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
985 /******************************************************************************************************/
986 /* Display the summarized data and inputs for editing */
988 g.render = function() {
990 /******************************************************************************************************/
991 /* Library setup and clear any existing interface */
993 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
995 for (var i in g.panes_and_field_names) {
996 var p = document.getElementById(i);
997 if (p) util.widgets.remove_children(p);
1000 /******************************************************************************************************/
1001 /* Populate the library filter menu for stat cats */
1004 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1005 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1008 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1010 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1011 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1012 for (var i = 0; i < sc_libs2.length; i++) {
1013 var menuitem = document.createElement('menuitem');
1014 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1015 menuitem.setAttribute('type','checkbox');
1016 menuitem.setAttribute('checked','true');
1017 menuitem.setAttribute('label',sc_libs2[i][0]);
1018 menuitem.setAttribute('value',sc_libs2[i][1]);
1019 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1020 x.appendChild(menuitem);
1023 /******************************************************************************************************/
1024 /* Prepare the panes */
1026 var groupbox; var caption; var vbox; var grid; var rows;
1028 /******************************************************************************************************/
1029 /* Loop through the field names */
1031 for (h in g.panes_and_field_names) {
1032 if (!document.getElementById(h)) continue;
1033 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1035 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1036 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1038 for (var a in attr) {
1039 groupbox.setAttribute(a,attr[a]);
1042 if (typeof g.changed[fn] != 'undefined') groupbox.setAttribute('class','copy_editor_field_changed');
1043 caption = document.createElement('caption'); groupbox.appendChild(caption);
1044 caption.setAttribute('label',fn); caption.setAttribute('id','caption_'+fn);
1045 vbox = document.createElement('vbox'); groupbox.appendChild(vbox);
1046 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1047 grid.setAttribute('flex','1');
1048 rows = grid.lastChild;
1051 /**************************************************************************************/
1052 /* Loop through each value for the field */
1054 for (var j in g.summary[fn]) {
1055 var value = j; var count = g.summary[fn][j];
1056 row = document.createElement('row'); rows.appendChild(row);
1057 var label1 = document.createElement('description'); row.appendChild(label1);
1058 if (g.special_exception[ fn ]) {
1059 g.special_exception[ fn ]( label1, value );
1061 label1.appendChild( document.createTextNode(value) );
1063 var label2 = document.createElement('description'); row.appendChild(label2);
1064 var unit = count == 1 ? 'copy' : 'copies';
1065 label2.appendChild( document.createTextNode(count + ' ' + unit) );
1067 var hbox = document.createElement('hbox');
1068 hbox.setAttribute('id',fn);
1069 groupbox.appendChild(hbox);
1070 var hbox2 = document.createElement('hbox');
1071 groupbox.appendChild(hbox2);
1073 /**************************************************************************************/
1074 /* Render the input widget */
1076 if (f[1].input && g.edit) {
1077 g.render_input(hbox,f[1]);
1081 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1087 /******************************************************************************************************/
1088 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1089 JSAN.use('util.file');
1090 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1091 g.copy_editor_prefs = util.widgets.load_attributes(file);
1092 for (var i in g.copy_editor_prefs) {
1093 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1095 g.toggle_stat_cat_display( document.getElementById(i) );
1096 } catch(E) { alert(E); }
1099 if (g.template_menu) g.template_menu.value = g.template_menu.getAttribute('value');
1103 /******************************************************************************************************/
1104 /* This actually draws the change button and input widget for a given field */
1105 g.render_input = function(node,blob) {
1107 // node = hbox ; groupbox -> hbox, hbox
1109 var groupbox = node.parentNode;
1110 var caption = groupbox.firstChild;
1111 var vbox = node.previousSibling;
1113 var hbox2 = node.nextSibling;
1115 var input_cmd = blob.input;
1116 var render_cmd = blob.render;
1117 var attr = blob.attr;
1119 var block = false; var first = true;
1121 function on_mouseover(ev) {
1122 groupbox.setAttribute('style','background: white');
1125 function on_mouseout(ev) {
1126 groupbox.setAttribute('style','');
1129 vbox.addEventListener('mouseover',on_mouseover,false);
1130 vbox.addEventListener('mouseout',on_mouseout,false);
1131 groupbox.addEventListener('mouseover',on_mouseover,false);
1132 groupbox.addEventListener('mouseout',on_mouseout,false);
1133 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1134 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1136 function on_click(ev){
1138 if (block) return; block = true;
1140 function post_c(v) {
1142 /* FIXME - kludgy */
1143 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1147 f = input_cmd.match(/apply\("(.+?)",/)[1];
1150 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1156 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1160 g.summarize( g.copies );
1162 document.getElementById(caption.id).focus();
1166 g.error.standard_unexpected_error_alert('post_c',E);
1169 var x; var c; eval( input_cmd );
1171 util.widgets.remove_children(vbox);
1172 util.widgets.remove_children(hbox);
1173 util.widgets.remove_children(hbox2);
1174 hbox.appendChild(x);
1175 var apply = document.createElement('button');
1176 apply.setAttribute('label','Apply');
1177 apply.setAttribute('accesskey','A');
1178 hbox2.appendChild(apply);
1179 apply.addEventListener('command',function() { c(x.value); },false);
1180 var cancel = document.createElement('button');
1181 cancel.setAttribute('label','Cancel');
1182 cancel.addEventListener('command',function() { setTimeout( function() { g.summarize( g.copies ); g.render(); document.getElementById(caption.id).focus(); }, 0); }, false);
1183 hbox2.appendChild(cancel);
1184 setTimeout( function() { x.focus(); }, 0 );
1187 g.error.standard_unexpected_error_alert('render_input',E);
1190 vbox.addEventListener('click',on_click, false);
1191 hbox.addEventListener('click',on_click, false);
1192 caption.addEventListener('click',on_click, false);
1193 caption.addEventListener('keypress',function(ev) {
1194 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1196 caption.setAttribute('style','-moz-user-focus: normal');
1197 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1198 caption.setAttribute('onblur','this.setAttribute("class","")');
1201 g.error.sdump('D_ERROR',E + '\n');
1205 /******************************************************************************************************/
1206 /* store the copies in the global xpcom stash */
1208 g.stash_and_close = function() {
1210 if (g.handle_update) {
1212 var r = g.network.request(
1213 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1214 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1215 [ ses(), g.copies, true ]
1217 if (typeof r.ilsevent != 'undefined') {
1218 g.error.standard_unexpected_error_alert('copy update',r);
1220 alert('Items added/modified.');
1222 /* FIXME -- revisit the return value here */
1224 alert('copy update error: ' + js2JSON(E));
1227 //g.data.temp_copies = js2JSON( g.copies );
1228 //g.data.stash('temp_copies');
1229 xulG.copies = g.copies;
1230 update_modal_xulG(xulG);
1233 g.error.standard_unexpected_error_alert('stash and close',E);
1237 /******************************************************************************************************/
1238 /* spawn copy notes interface */
1240 g.copy_notes = function() {
1241 JSAN.use('util.window'); var win = new util.window();
1243 urls.XUL_COPY_NOTES,
1244 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1245 'Copy Notes','chrome,resizable,modal',
1246 { 'copy_id' : g.copies[0].id() }
1250 /******************************************************************************************************/
1251 /* hides or unhides stat cats based on library stat cat filter menu */
1252 g.toggle_stat_cat_display = function(el) {
1254 var visible = el.getAttribute('checked');
1255 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1256 for (var n = 0; n < nl.length; n++) {
1258 nl[n].setAttribute('hidden','false');
1260 nl[n].setAttribute('hidden','true');
1263 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1264 g.save_attributes();
1267 /******************************************************************************************************/
1268 /* This adds a stat cat definition to the stat cat pane for rendering */
1269 g.save_attributes = function() {
1270 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1271 var what_to_save = {};
1272 for (var i in g.copy_editor_prefs) {
1273 what_to_save[i] = [];
1274 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1276 util.widgets.save_attributes(file, what_to_save );
1279 /******************************************************************************************************/
1280 /* This adds a stat cat definition to the stat cat pane for rendering */
1281 g.add_stat_cat = function(sc) {
1283 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1287 if (typeof sc == 'object') {
1292 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1294 g.stat_cat_seen[ sc_id ] = 1;
1296 if (typeof sc != 'object') {
1298 sc = g.network.simple_request(
1299 'FM_ASC_BATCH_RETRIEVE',
1300 [ ses(), [ sc_id ] ]
1305 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1307 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1312 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1313 + sc.id() + '; } ); l ? l.value() : "<Unset>";',
1314 input: 'c = function(v){ g.apply_stat_cat(' + sc.id() + ',v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ "<Remove Stat Cat>", -1 ] ].concat( util.functional.map_list( g.data.hash.asc[' + sc.id()
1315 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1316 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1323 g.panes_and_field_names.right_pane4.push( temp_array );
1325 g.error.standard_unexpected_error_alert('Error adding stat cat to display definition',E);
1329 /******************************************************************************************************/
1330 /* Add stat cats to the panes_and_field_names.right_pane4 */
1331 g.populate_stat_cats = function() {
1333 g.data.stash_retrieve();
1334 g.stat_cat_seen = {};
1336 function get(lib_id,only_these) {
1337 g.data.stash_retrieve();
1338 var label = 'asc_list_for_lib_'+lib_id;
1339 if (typeof g.data[label] == 'undefined') {
1340 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1341 if (typeof robj.ilsevent != 'undefined') throw(robj);
1343 for (var j = 0; j < robj.length; j++) {
1344 var my_asc = robj[j];
1345 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1346 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1347 g.data.hash.asc[ my_asc.id() ] = my_asc;
1349 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1350 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1351 temp_list.push( my_asc );
1354 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1356 return g.data[label];
1359 /* The stat cats for the pertinent library -- this is based on workstation ou */
1360 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1361 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1362 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1363 g.add_stat_cat( g.data.list.my_asc[i] );
1366 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1367 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1369 function add_common_ancestors(sc_libs) {
1370 JSAN.use('util.fm_utils');
1371 var libs = []; for (var i in sc_libs) libs.push(i);
1372 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1373 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1375 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1376 var asc_list = get(ancestor, ancestors);
1377 for (var i = 0; i < asc_list.length; i++) {
1378 g.add_stat_cat( asc_list[i] );
1383 /* stat cats based on stat cat entries present on these copies */
1385 for (var i = 0; i < g.copies.length; i++) {
1386 var entries = g.copies[i].stat_cat_entries();
1387 if (!entries) entries = [];
1388 for (var j = 0; j < entries.length; j++) {
1389 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1390 sc_libs[ lib ] = true;
1393 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1395 /* stat cats based on Circ Lib */
1397 for (var i = 0; i < g.copies.length; i++) {
1398 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1399 sc_libs[ circ_lib ] = true;
1401 add_common_ancestors(sc_libs);
1403 /* stat cats based on Owning Lib */
1405 for (var i = 0; i < g.copies.length; i++) {
1406 var cn_id = g.copies[i].call_number();
1408 if (! g.map_acn[ cn_id ]) {
1409 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1410 if (typeof req.ilsevent == 'undefined') {
1411 g.map_acn[ cn_id ] = req;
1416 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1417 sc_libs[ owning_lib ] = true;
1420 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1422 g.panes_and_field_names.right_pane4.sort();
1425 g.error.standard_unexpected_error_alert('Error populating stat cats for display',E);