2 var g = { 'disabled' : false };
5 function $(id) { return document.getElementById(id); }
6 function $_(x) { return $('catStrings').getString(x); }
10 /******************************************************************************************************/
11 /* setup JSAN and some initial libraries */
13 if (typeof JSAN == 'undefined') {
14 throw( $('commonStrings').getString('common.jsan.missing') );
16 JSAN.errorLevel = "die"; // none, warn, or die
17 JSAN.addRepository('/xul/server/');
18 JSAN.use('util.error'); g.error = new util.error();
19 g.error.sdump('D_TRACE','my_init() for cat/copy_editor.xul');
21 JSAN.use('util.functional');
22 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
23 JSAN.use('util.network'); g.network = new util.network();
25 if (xulG.unified_interface) {
26 $('non_unified_buttons').hidden = true;
29 g.docid = xul_param('docid');
30 g.handle_update = xul_param('handle_update');
32 /******************************************************************************************************/
33 /* Get the copy ids from various sources and flesh them */
35 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});
36 if (!copy_ids) copy_ids = [];
38 if (copy_ids.length > 0) g.copies = g.network.simple_request(
39 'FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative',
43 /******************************************************************************************************/
44 /* And other fleshed copies if any */
46 if (!g.copies) g.copies = [];
47 var c = xul_param('copies',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_copies','clear_xpcom':true})
48 if (c) g.copies = g.copies.concat(c);
50 /******************************************************************************************************/
51 /* We try to retrieve callnumbers for existing copies, but for new copies, we rely on this */
53 g.callnumbers = xul_param('callnumbers',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_callnumbers','clear_xpcom':true});
55 /******************************************************************************************************/
56 /* If invoked from the Local Admin menu, rig up a fake item and disable save/create functionality */
60 var fake_item = new acp();
62 fake_item.barcode( 'fake_item' );
63 fake_item.call_number( -1 );
64 fake_item.circ_lib(ses('ws_ou'));
65 /* FIXME -- use constants; really, refactor this into a library somewhere that can be used by chrome and
66 remote xul for new copies */
69 fake_item.deposit_amount(0);
70 fake_item.fine_level(2); // Normal
71 fake_item.loan_duration(2); // Normal
72 fake_item.location(1); // Stacks
74 fake_item.circulate(get_db_true());
75 fake_item.holdable(get_db_true());
76 fake_item.opac_visible(get_db_true());
77 fake_item.ref(get_db_false());
78 fake_item.mint_condition(get_db_true());
79 g.copies = [ fake_item ];
80 $('save').hidden = true;
81 $('save').disabled = true;
82 $('non_unified_buttons').hidden = true;
85 /******************************************************************************************************/
86 /* Get preference (if it exists) for copy location label order */
88 g.cl_first = false; // Default to legacy OU first mode
89 var prefs = Components.classes['@mozilla.org/preferences-service;1']
90 .getService(Components.interfaces['nsIPrefBranch']);
92 g.cl_first = prefs.getBoolPref('oils.copy_editor.copy_location_name_first');
95 /******************************************************************************************************/
96 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
97 /* Quick fix, messagecatalog only usable during/after onload */
102 /******************************************************************************************************/
103 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
105 if (xul_param('edit') == '1') {
109 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
111 // Editor desired, but let's check permissions
114 var check = g.network.simple_request(
115 'PERM_MULTI_ORG_CHECK',
118 g.data.list.au[0].id(),
119 util.functional.map_list(
123 var cn_id = o.call_number();
125 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
127 if (! g.map_acn[ cn_id ]) {
128 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
129 if (typeof req.ilsevent == 'undefined') {
130 g.map_acn[ cn_id ] = req;
131 lib = g.map_acn[ cn_id ].owning_lib();
136 lib = g.map_acn[ cn_id ].owning_lib();
139 return typeof lib == 'object' ? lib.id() : lib;
142 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
145 g.edit = check.length == 0;
147 g.error.standard_unexpected_error_alert('batch permission check',E);
153 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
154 $('save').setAttribute('hidden','false');
156 $('top_nav').setAttribute('hidden','true');
159 g.retrieve_templates();
162 $('top_nav').setAttribute('hidden','true');
165 g.panes_and_field_names.left_pane =
168 $('catStrings').getString('staff.cat.copy_editor.status'),
170 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
171 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,
172 //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);',
175 ].concat(g.panes_and_field_names.left_pane);
178 /******************************************************************************************************/
179 /* Show the Record Details? */
181 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
183 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
184 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
185 brief_display.setAttribute( 'flex','1' );
188 /******************************************************************************************************/
189 /* Add stat cats to the panes_and_field_names.right_pane4 */
191 g.populate_stat_cats();
193 /******************************************************************************************************/
194 /* Backup copies :) */
196 g.original_copies = js2JSON( g.copies );
198 /******************************************************************************************************/
201 g.summarize( g.copies );
203 g.check_for_unmet_required_fields();
205 if (xulG.unified_interface) {
206 xulG.disable_copy_editor = function(c) {
207 addCSSClass(document.documentElement,'disabled_copy_editor');
210 xulG.enable_copy_editor = function(c) {
211 removeCSSClass(document.documentElement,'disabled_copy_editor');
213 xulG.refresh_copy_editor();
215 xulG.refresh_copy_editor = function() {
216 dump('refresh_copy_editor\n');
217 addCSSClass(document.documentElement,'enabling_copy_editor');
219 xulG.clear_update_copy_editor_timeout();
220 g.copies = xulG.copies;
221 g.edit = g.copies.length > 0;
223 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
225 g.original_copies = js2JSON( g.copies );
226 g.hide_copy_notes_button();
227 for (var i = 0; i < g.applied_templates.length; i++) {
228 g._apply_template( g.applied_templates[i], false);
230 if (g.copies.length > 0) {
231 // Stop tracking these templates once they're applied
233 g.applied_templates = [];
235 g.summarize( g.copies );
237 g.check_for_unmet_required_fields();
240 removeCSSClass(document.documentElement,'enabling_copy_editor');
244 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
247 xulG.unlock_copy_editor = function() {
250 xulG.notify_of_templatable_field_change = function(id,v) {
251 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
254 g.hide_copy_notes_button();
257 JSAN.use('util.hide');
258 util.hide.generate_css('ui.hide_copy_editor_fields');
261 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
262 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
267 /******************************************************************************************************/
268 /* Show copy notes button */
269 g.hide_copy_notes_button = function() {
270 if (g.copies.length > 0 && g.copies[0].id() < 0) {
271 document.getElementById('copy_notes').setAttribute('hidden','true');
272 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
273 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
275 if (g.copies.length != 1) {
276 document.getElementById('copy_notes').setAttribute('hidden','true');
280 /******************************************************************************************************/
281 /* Retrieve Templates */
283 g.retrieve_templates = function() {
285 JSAN.use('util.widgets'); JSAN.use('util.functional');
287 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
288 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
289 g.templates = robj['staff_client.copy_editor.templates'];
291 util.widgets.remove_children('template_placeholder');
292 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
294 g.template_menu = util.widgets.make_menulist( list );
295 g.template_menu.setAttribute('id','template_menu');
296 $('template_placeholder').appendChild(g.template_menu);
297 g.template_menu.addEventListener(
299 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
303 if (xulG.unified_interface) {
304 if (typeof xulG.update_unified_template_list == 'function') {
305 xulG.update_unified_template_list(list);
306 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
307 xulG.update_item_editor_template_selection = function(new_value) {
308 g.template_menu.setAttribute('value', new_value);
309 g.template_menu.value = new_value;
310 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
313 xulG.item_editor_apply_template = function() { g.apply_template(true); };
314 xulG.item_editor_delete_template = function() { g.delete_template(); };
315 xulG.item_editor_save_template = function() { g.save_template(); };
316 xulG.item_editor_import_templates = function() { g.import_templates(); };
317 xulG.item_editor_export_templates = function() { g.export_templates(); };
318 xulG.item_editor_reset = function() { g.reset(); };
323 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
327 /******************************************************************************************************/
330 g.applied_templates = [];
332 g.apply_template = function(apply_volume_editor_template_changes) {
334 var name = g.template_menu.value;
335 if (g.templates[ name ] != 'undefined') {
337 // We're only tracking these applied templates temporarily,
338 // specifically when they're used prior to copies being
339 // created in the unified interface.
340 g.applied_templates.push( name );
342 g._apply_template(name,apply_volume_editor_template_changes);
343 g.summarize( g.copies );
345 g.check_for_unmet_required_fields();
348 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
352 g._apply_template = function(name,apply_volume_editor_template_changes) {
354 if (g.templates[ name ] != 'undefined') {
355 var template = g.templates[ name ];
356 for (var i in template) {
357 if (g.is_field_hidden(i)) {
358 alert($('catStrings').getFormattedString(
359 'staff.cat.copy_editor.apply_unsafe_field',
364 if (template[i].field == 'status') {
365 if (!g.safe_to_edit_copy_status()) {
366 alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_unsafe_field',[i]));
370 g.changed[ i ] = template[ i ];
371 switch( template[i].type ) {
373 g.apply(template[i].field,template[i].value);
376 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
379 g.apply_owning_lib(template[i].value);
381 case 'volume_copy_creator' :
382 if (xulG.unified_interface && apply_volume_editor_template_changes) {
383 xulG.apply_template_to_batch(template[i].field,template[i].value);
390 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
394 /******************************************************************************************************/
395 /* Save as Template */
397 g.save_template = function() {
399 var name = window.prompt(
400 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
402 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
405 g.templates[name] = g.changed;
406 var robj = g.network.simple_request(
407 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
409 if (typeof robj.ilsevent != 'undefined') {
412 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
416 g.retrieve_templates();
418 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
424 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
428 /******************************************************************************************************/
429 /* Delete Template */
431 g.delete_template = function() {
433 var name = g.template_menu.value;
435 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
436 delete(g.templates[name]);
437 var robj = g.network.simple_request(
438 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
440 if (typeof robj.ilsevent != 'undefined') {
443 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
447 g.retrieve_templates();
449 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
455 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
459 /******************************************************************************************************/
460 /* Export Templates */
462 g.export_templates = function() {
464 JSAN.use('util.file'); var f = new util.file('');
465 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
467 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
471 /******************************************************************************************************/
472 /* Import Templates */
474 g.import_templates = function() {
476 JSAN.use('util.file'); var f = new util.file('');
477 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
479 for (var i in temp) {
481 if (g.templates[i]) {
483 var r = g.error.yns_alert(
484 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
485 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
486 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
487 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
489 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
492 if (r == 0 /* Yes */) g.templates[i] = temp[i];
496 g.templates[i] = temp[i];
502 var r = g.error.yns_alert(
503 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
504 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
505 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
506 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
508 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
511 if (r == 0 /* Yes */) {
512 var robj = g.network.simple_request(
513 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
515 if (typeof robj.ilsevent != 'undefined') {
518 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
522 g.retrieve_templates();
524 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
530 util.widgets.remove_children('template_placeholder');
531 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
532 g.template_menu = util.widgets.make_menulist( list );
533 $('template_placeholder').appendChild(g.template_menu);
534 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
539 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
544 /******************************************************************************************************/
545 /* Restore backup copies */
547 g.reset = function() {
548 g.applied_templates = [];
550 g.copies = JSON2js( g.original_copies );
551 g.summarize( g.copies );
553 g.check_for_unmet_required_fields();
555 if (xulG.unified_interface) {
556 xulG.reset_batch_menus();
560 /******************************************************************************************************/
561 /* Apply a value to a specific field on all the copies being edited */
563 g.apply = function(field,value) {
564 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
565 if (value == '<HACK:KLUDGE:NULL>') {
568 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
569 if (field == 'price' || field == 'deposit_amount') {
573 JSAN.use('util.money'); value = util.money.sanitize( value );
576 for (var i = 0; i < g.copies.length; i++) {
577 var copy = g.copies[i];
579 copy[field]( value ); copy.ischanged('1');
588 /******************************************************************************************************/
589 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
591 g.apply_stat_cat = function(sc_id,entry_id) {
592 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
593 for (var i = 0; i < g.copies.length; i++) {
594 var copy = g.copies[i];
597 var temp = copy.stat_cat_entries();
598 if (!temp) temp = [];
599 temp = util.functional.filter_list(
602 return (obj.stat_cat() != sc_id);
607 util.functional.find_id_object_in_list(
608 g.data.hash.asc[sc_id].entries(),
613 copy.stat_cat_entries( temp );
616 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
623 /******************************************************************************************************/
624 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
626 g.apply_owning_lib = function(ou_id) {
627 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
628 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
629 if (! g.safe_to_change_owning_lib() ) { return; }
630 for (var i = 0; i < g.copies.length; i++) {
631 var copy = g.copies[i];
633 if (!g.map_acn[copy.call_number()]) {
634 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
635 if (typeof volume.ilsevent != 'undefined') {
636 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
639 g.map_acn[copy.call_number()] = volume;
641 var old_volume = g.map_acn[copy.call_number()];
644 acn_blob = g.network.simple_request(
645 'FM_ACN_FIND_OR_CREATE',
646 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
649 acn_blob = { 'acn_id' : -1 }; // spawned from Local Admin menu, so fake item and call number
651 if (typeof acn_blob.ilsevent != 'undefined') {
652 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
655 copy.call_number(acn_blob.acn_id);
658 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
665 /******************************************************************************************************/
666 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
668 g.safe_to_change_owning_lib = function() {
670 if (xulG.unified_interface) { return false; }
671 if (xulG.admin) { return false; }
673 for (var i = 0; i < g.copies.length; i++) {
674 var cn = g.copies[i].call_number();
675 if (typeof cn == 'object') { cn = cn.id(); }
676 if (cn == -1) { safe = false; }
680 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
685 /******************************************************************************************************/
686 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
688 g.safe_to_edit_copy_status = function() {
691 for (var i = 0; i < g.copies.length; i++) {
692 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
693 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
697 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
702 /******************************************************************************************************/
703 /* This returns true if the field has been hidden via util.hide */
705 g.is_field_hidden = function(field) {
707 g.data.stash_retrieve();
708 if (g.data.hash.aous['ui.hide_copy_editor_fields']
709 && g.data.hash.aous['ui.hide_copy_editor_fields'].indexOf(field) > -1) {
713 g.error.standard_unexpected_error_alert('is_field_hidden?',E);
719 /******************************************************************************************************/
720 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
722 g.populate_alert_message_input = function(tb) {
724 var seen = {}; var s = '';
725 for (var i = 0; i < g.copies.length; i++) {
726 var msg = g.copies[i].alert_message();
728 if (typeof seen[msg] == 'undefined') {
734 tb.setAttribute('value',s);
736 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
740 /***************************************************************************************************************/
741 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
743 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
744 g.data.stash_retrieve();
745 var label = 'acpl_list_for_lib_'+lib_id;
746 if (typeof g.data[label] == 'undefined') {
747 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
748 if (typeof robj.ilsevent != 'undefined') throw(robj);
750 for (var j = 0; j < robj.length; j++) {
751 var my_acpl = robj[j];
752 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
753 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
754 g.data.list.acpl.push( my_acpl );
756 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
757 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
758 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
759 temp_list.push( my_acpl );
762 g.data[label] = temp_list; g.data.stash(label,'hash','list');
764 return g.data[label];
767 /******************************************************************************************************/
768 /* This returns a list of acpl's appropriate for the copies being edited */
770 g.get_acpl_list = function() {
773 JSAN.use('util.functional');
777 /**************************************/
778 /* get owning libs from call numbers */
780 var owning_libs = {};
781 for (var i = 0; i < g.copies.length; i++) {
782 var callnumber = g.copies[i].call_number();
783 if (!callnumber) continue;
784 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
786 if (! g.map_acn[ cn_id ]) {
787 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
788 if (typeof req.ilsevent == 'undefined') {
789 g.map_acn[ cn_id ] = req;
794 var consider_lib = g.map_acn[ cn_id ].owning_lib();
795 if (!consider_lib) continue;
796 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
800 for (var i in g.callnumbers) {
801 var consider_lib = g.callnumbers[i].owning_lib;
802 if (!consider_lib) continue;
803 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
807 /***************************************************************************************************/
808 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
810 JSAN.use('util.fm_utils');
811 var libs = []; for (var i in owning_libs) libs.push(i);
812 if (libs.length > 0) {
813 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
814 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
817 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
818 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
819 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
820 if (acpl_list[i] != null) {
821 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
832 for (var i = 0; i < g.copies.length; i++) {
833 var consider_lib = g.copies[i].circ_lib();
834 if (!consider_lib) continue;
835 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
838 /***************************************************************************************************/
839 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
841 libs = []; for (var i in circ_libs) libs.push(i);
842 if (libs.length > 0) {
843 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
844 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
847 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
848 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
849 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
850 if (acpl_list[i] != null) {
851 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
857 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
858 return acpl_list.sort(
860 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
861 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
862 if (label_a < label_b) return -1;
863 if (label_a > label_b) return 1;
869 g.error.standard_unexpected_error_alert('get_acpl_list',E);
875 /******************************************************************************************************/
876 /* This keeps track of which fields have been edited for styling purposes */
880 /******************************************************************************************************/
881 /* This keeps track of which fields are required, and which fields have been populated */
886 /******************************************************************************************************/
887 /* These need data from the middle layer to render */
889 function init_panes0() {
890 g.special_exception = {};
891 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
892 JSAN.use('util.widgets');
893 if (value>0) { /* an existing call number */
894 g.network.simple_request(
895 'FM_ACN_RETRIEVE.authoritative',
898 var cn = '??? id = ' + value;
900 cn = req.getResultObject();
902 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
904 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
907 } else { /* a yet to be created call number */
909 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
913 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
914 if (!Number(value)) return;
915 g.network.simple_request(
916 'FM_AU_RETRIEVE_VIA_ID',
919 var p = '??? id = ' + value;
921 p = req.getResultObject();
925 g.error.sdump('D_ERROR','patron retrieve: ' + E);
927 JSAN.use('util.widgets');
928 util.widgets.set_text(label,p);
932 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
933 if (!Number(value)) return;
934 g.network.simple_request(
935 'FM_AU_RETRIEVE_VIA_ID',
938 var p = '??? id = ' + value;
940 p = req.getResultObject();
944 g.error.sdump('D_ERROR','patron retrieve: ' + E);
946 util.widgets.set_text(label,p);
952 /******************************************************************************************************/
953 g.readonly_stat_cat_names = [];
954 g.editable_stat_cat_names = [];
956 /******************************************************************************************************/
957 /* These get show in the left panel */
959 function init_panes() {
960 g.panes_and_field_names = {
965 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
967 render: 'fm.barcode();',
970 + 'g.apply("barcode", v);'
971 + 'if (typeof post_c === "function") post_c(v);'
973 + 'x = document.createElement("textbox");',
974 attr: { 'class': 'disabled' },
978 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
980 render: 'util.date.formatted_date( fm.create_date(), "%F");',
984 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
986 render: 'util.date.formatted_date( fm.active_date(), "%F");',
990 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
992 render: 'fm.creator();',
996 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
998 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
1002 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
1004 render: 'fm.editor();',
1013 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
1015 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
1016 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.cl_first ? 'obj.name() + " : " + g.data.hash.aou[ obj.owning_lib() ].shortname()' : '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);',
1021 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
1023 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
1024 //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);',
1025 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);',
1029 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
1031 render: 'fm.call_number();',
1032 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,
1036 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
1038 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
1039 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);',
1049 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
1051 render: 'fm.circulate() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( get_bool( fm.circulate() ) ? $("catStrings").getString("staff.cat.copy_editor.field.circulate.yes_or_true") : $("catStrings").getString("staff.cat.copy_editor.field.circulate.no_or_false") )',
1052 input: 'c = function(v){ g.apply("circulate",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.circulate.yes_or_true"), get_db_true() ], [ $("catStrings").getString("staff.cat.copy_editor.field.circulate.no_or_false"), get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1056 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
1058 render: 'fm.holdable() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( get_bool( fm.holdable() ) ? $("catStrings").getString("staff.cat.copy_editor.field.holdable.yes_or_true") : $("catStrings").getString("staff.cat.copy_editor.field.holdable.no_or_false") )',
1059 input: 'c = function(v){ g.apply("holdable",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.holdable.yes_or_true"), get_db_true() ], [ $("catStrings").getString("staff.cat.copy_editor.field.holdable.no_or_false"), get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1063 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
1065 render: 'fm.age_protect() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( typeof fm.age_protect() == "object" ? fm.age_protect().name() : g.data.hash.crahp[ fm.age_protect() ].name() )',
1066 input: 'c = function(v){ g.apply("age_protect",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.remove_age_based_hold_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);',
1071 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
1073 render: 'fm.floating() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( get_bool( fm.floating() ) ? $("catStrings").getString("staff.cat.copy_editor.field.floating.yes_or_true") : $("catStrings").getString("staff.cat.copy_editor.field.floating.no_or_false") )',
1074 input: 'c = function(v){ g.apply("floating",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.floating.yes_or_true"), get_db_true() ], [ $("catStrings").getString("staff.cat.copy_editor.field.floating.no_or_false"), get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1078 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1080 render: 'switch(Number(fm.loan_duration())){ case 1: $("catStrings").getString("staff.cat.copy_editor.field.loan_duration.short"); break; case 2: $("catStrings").getString("staff.cat.copy_editor.field.loan_duration.normal"); break; case 3: $("catStrings").getString("staff.cat.copy_editor.field.loan_duration.extended"); break; }',
1081 input: 'c = function(v){ g.apply("loan_duration",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.loan_duration.short"), "1" ], [ $("catStrings").getString("staff.cat.copy_editor.field.loan_duration.normal"), "2" ], [ $("catStrings").getString("staff.cat.copy_editor.field.loan_duration.extended"), "3" ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1086 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1088 render: 'switch(Number(fm.fine_level())){ case 1: $("catStrings").getString("staff.cat.copy_editor.field.fine_level.low"); break; case 2: $("catStrings").getString("staff.cat.copy_editor.field.fine_level.normal"); break; case 3: $("catStrings").getString("staff.cat.copy_editor.field.fine_level.high"); break; }',
1089 input: 'c = function(v){ g.apply("fine_level",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.fine_level.low"), "1" ], [ $("catStrings").getString("staff.cat.copy_editor.field.fine_level.normal"), "2" ], [ $("catStrings").getString("staff.cat.copy_editor.field.fine_level.high"), "3" ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1094 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1096 render: 'fm.circ_as_type() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : g.data.hash.citm[ fm.circ_as_type() ].value',
1097 input: 'c = function(v){ g.apply("circ_as_type",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.remove_circulate_as_type"), "<HACK:KLUDGE:NULL>" ] ].concat( 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);',
1101 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1103 render: 'fm.circ_modifier() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : $("commonStrings").getFormattedString("staff.circ_modifier.display",[fm.circ_modifier(),g.data.hash.ccm[fm.circ_modifier()].name(),g.data.hash.ccm[fm.circ_modifier()].description()])',
1104 input: 'c = function(v){ g.apply("circ_modifier",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"), "<HACK:KLUDGE:NULL>" ] ].concat( util.functional.map_list( g.data.list.ccm, function(obj) { return [ $("commonStrings").getFormattedString("staff.circ_modifier.display",[obj.code(),obj.name(),obj.description()]), obj.code() ]; } ).sort() ) ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1111 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1113 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1114 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);',
1119 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1121 render: 'fm.deposit() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( get_bool( fm.deposit() ) ? $("catStrings").getString("staff.cat.copy_editor.field.deposit.yes_or_true") : $("catStrings").getString("staff.cat.copy_editor.field.deposit.no_or_false") )',
1122 input: 'c = function(v){ g.apply("deposit",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.deposit.yes_or_true"), get_db_true() ], [ $("catStrings").getString("staff.cat.copy_editor.field.deposit.no_or_false"), get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1126 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1128 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1129 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);',
1133 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1135 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1136 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);',
1141 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1143 render: 'fm.opac_visible() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( get_bool( fm.opac_visible() ) ? $("catStrings").getString("staff.cat.copy_editor.field.opac_visible.yes_or_true") : $("catStrings").getString("staff.cat.copy_editor.field.opac_visible.no_or_false") )',
1144 input: 'c = function(v){ g.apply("opac_visible",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.opac_visible.yes_or_true"), get_db_true() ], [ $("catStrings").getString("staff.cat.copy_editor.field.opac_visible.no_or_false"), get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1148 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1150 render: 'fm.ref() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( get_bool( fm.ref() ) ? $("catStrings").getString("staff.cat.copy_editor.field.reference.yes_or_true") : $("catStrings").getString("staff.cat.copy_editor.field.reference.no_or_false") )',
1151 input: 'c = function(v){ g.apply("ref",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.reference.yes_or_true"), get_db_true() ], [ $("catStrings").getString("staff.cat.copy_editor.field.reference.no_or_false"), get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1155 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1157 render: 'get_bool( fm.mint_condition() ) ? $("catStrings").getString("staff.cat.copy_editor.field.mint_condition.yes_or_true") : $("catStrings").getString("staff.cat.copy_editor.field.mint_condition.no_or_false")',
1158 input: 'c = function(v){ g.apply("mint_condition",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.field.mint_condition.yes_or_true"), get_db_true() ], [ $("catStrings").getString("staff.cat.copy_editor.field.mint_condition.no_or_false"), get_db_false() ] ] ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1170 /******************************************************************************************************/
1171 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1173 g.summarize = function( copies ) {
1174 /******************************************************************************************************/
1177 JSAN.use('util.date'); JSAN.use('util.money');
1180 for (var i in g.panes_and_field_names) {
1181 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1183 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1184 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1186 /******************************************************************************************************/
1187 /* Loop through the field names */
1189 for (var i = 0; i < g.field_names.length; i++) {
1191 var field_name = g.field_names[i][0];
1192 var render = g.field_names[i][1].render;
1193 var attr = g.field_names[i][1].attr;
1194 g.summary[ field_name ] = {};
1195 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1197 /******************************************************************************************************/
1198 /* Loop through the copies */
1200 for (var j = 0; j < copies.length; j++) {
1203 var cmd = render || ('fm.' + field_name + '();');
1204 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1206 /**********************************************************************************************/
1207 /* Try to retrieve the value for this field for this copy */
1210 value = eval( cmd );
1212 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1214 if (typeof value == 'object' && value != null) {
1215 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1217 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1218 delete g.populated[field_name];
1221 /**********************************************************************************************/
1222 /* Tally the count */
1224 if (g.summary[ field_name ][ value ]) {
1225 g.summary[ field_name ][ value ]++;
1227 g.summary[ field_name ][ value ] = 1;
1231 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1234 /******************************************************************************************************/
1235 /* Display the summarized data and inputs for editing */
1237 g.render = function() {
1239 /******************************************************************************************************/
1240 /* Library setup and clear any existing interface */
1242 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1244 for (var i in g.panes_and_field_names) {
1245 var p = document.getElementById(i);
1246 if (p) util.widgets.remove_children(p);
1249 /******************************************************************************************************/
1250 /* Populate the library filter menu for stat cats */
1253 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1254 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1257 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1259 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1260 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1261 for (var i = 0; i < sc_libs2.length; i++) {
1262 var menuitem = document.createElement('menuitem');
1263 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1264 menuitem.setAttribute('type','checkbox');
1265 menuitem.setAttribute('checked','true');
1266 menuitem.setAttribute('label',sc_libs2[i][0]);
1267 menuitem.setAttribute('value',sc_libs2[i][1]);
1268 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1269 x.appendChild(menuitem);
1272 /******************************************************************************************************/
1273 /* Prepare the panes */
1275 var groupbox; var caption; var vbox; var grid; var rows;
1277 /******************************************************************************************************/
1278 /* Loop through the field names */
1280 for (h in g.panes_and_field_names) {
1281 if (!document.getElementById(h)) continue;
1282 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1284 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1285 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1286 groupbox.setAttribute('hideable',fn);
1288 for (var a in attr) {
1289 groupbox.setAttribute(a,attr[a]);
1292 caption = document.createElement('caption'); groupbox.appendChild(caption);
1293 caption.setAttribute('label',fn);
1294 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1295 caption.setAttribute('hideable',fn);
1296 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1297 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1298 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1299 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1300 grid.setAttribute('flex','1');
1301 rows = grid.lastChild;
1304 /**************************************************************************************/
1305 /* Loop through each value for the field */
1307 for (var j in g.summary[fn]) {
1308 var value = j; var count = g.summary[fn][j];
1309 row = document.createElement('row'); rows.appendChild(row);
1310 var label1 = document.createElement('description'); row.appendChild(label1);
1311 if (g.special_exception[ fn ]) {
1312 g.special_exception[ fn ]( label1, value );
1314 label1.appendChild( document.createTextNode(value) );
1316 var label2 = document.createElement('description'); row.appendChild(label2);
1319 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1321 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1323 label2.appendChild( document.createTextNode(copy_count) );
1325 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1326 var hbox = document.createElement('hbox'); // main input controls go here
1327 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1328 groupbox.appendChild(hbox);
1329 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1330 groupbox.appendChild(hbox2);
1332 /**************************************************************************************/
1333 /* Render the input widget */
1335 if (f[1].input && g.edit) {
1336 g.render_input(hbox,f[1]);
1340 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1346 /******************************************************************************************************/
1347 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1348 JSAN.use('util.file');
1349 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1350 g.copy_editor_prefs = util.widgets.load_attributes(file);
1351 for (var i in g.copy_editor_prefs) {
1352 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1354 g.toggle_stat_cat_display( document.getElementById(i) );
1355 } catch(E) { alert(E); }
1358 if (g.template_menu) {
1359 g.template_menu.value = g.template_menu.getAttribute('value');
1360 if (xulG.unified_interface) {
1361 if (typeof xulG.update_unified_template_selection == 'function') {
1362 xulG.update_unified_template_selection(g.template_menu.value);
1367 util.hide.generate_css('ui.hide_copy_editor_fields');
1370 /******************************************************************************************************/
1371 /* This actually draws the change button and input widget for a given field */
1372 g.render_input = function(node,blob) {
1374 // node = hbox ; groupbox -> hbox, hbox
1376 var groupbox = node.parentNode;
1377 var caption = groupbox.firstChild;
1378 var vbox = node.previousSibling;
1380 var hbox2 = node.nextSibling;
1382 var input_cmd = blob.input;
1383 var render_cmd = blob.render;
1384 var attr = blob.attr;
1386 var block = false; var first = true;
1388 function on_mouseover(ev) {
1389 groupbox.setAttribute('style','background: white');
1392 function on_mouseout(ev) {
1393 groupbox.setAttribute('style','');
1396 groupbox.addEventListener('mouseover',on_mouseover,false);
1397 groupbox.addEventListener('mouseout',on_mouseout,false);
1399 function on_click(ev){
1401 if (block || g.disabled || !g.edit || ev.currentTarget.classList.contains('disabled')) {
1408 function post_c(v) {
1410 /* FIXME - kludgy */
1411 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1415 f = input_cmd.match(/apply\("(.+?)",/)[1];
1418 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1424 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1428 g.summarize( g.copies );
1430 g.check_for_unmet_required_fields();
1431 document.getElementById(caption.id).focus();
1435 g.error.standard_unexpected_error_alert('post_c',E);
1438 var x; var c; eval( input_cmd );
1440 util.widgets.remove_children(vbox);
1441 util.widgets.remove_children(hbox);
1442 util.widgets.remove_children(hbox2);
1443 hbox.appendChild(x);
1444 var apply = document.createElement('button');
1445 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1446 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1447 hbox2.appendChild(apply);
1448 apply.addEventListener('command',function() { c(x.value); },false);
1449 var cancel = document.createElement('button');
1450 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1451 cancel.addEventListener('command',function() {
1452 setTimeout( function() {
1453 g.summarize( g.copies );
1455 g.check_for_unmet_required_fields();
1456 document.getElementById(caption.id).focus();
1461 hbox2.appendChild(cancel);
1462 setTimeout( function() { x.focus(); }, 0 );
1465 g.error.standard_unexpected_error_alert('render_input',E);
1468 groupbox.addEventListener('click',on_click, false);
1469 groupbox.addEventListener('keypress',function(ev) {
1470 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1472 caption.setAttribute('style','-moz-user-focus: normal');
1473 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1474 caption.setAttribute('onblur','this.setAttribute("class","")');
1477 g.error.sdump('D_ERROR',E + '\n');
1481 /******************************************************************************************************/
1482 /* store the copies in the global xpcom stash */
1484 g.stash_and_close = function() {
1485 var r = {textcode: ''};
1489 if (g.handle_update) {
1491 r = g.network.request(
1492 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1493 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1494 [ ses(), g.copies, true ]
1496 if (r.textcode === 'ITEM_BARCODE_EXISTS') {
1497 alert('error with item update: ' + r.desc);
1498 var barcode = $($_('staff.cat.copy_editor.field.barcode.label'));
1499 barcode.parentNode.classList.remove('disabled');
1502 else if (typeof r.ilsevent !== 'undefined') {
1503 g.error.standard_unexpected_error_alert('copy update',r);
1505 /* FIXME -- revisit the return value here */
1507 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1510 //g.data.temp_copies = js2JSON( g.copies );
1511 //g.data.stash('temp_copies');
1512 xulG.copies = g.copies;
1513 if (r.textcode !== 'ITEM_BARCODE_EXISTS') {
1514 JSAN.use('util.widgets');
1515 util.widgets.dispatch('close',window);
1518 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1522 /******************************************************************************************************/
1523 /* spawn copy notes interface */
1525 g.copy_notes = function() {
1526 JSAN.use('util.window'); var win = new util.window();
1528 urls.XUL_COPY_NOTES,
1529 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1530 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1531 { 'copy_id' : g.copies[0].id() }
1535 /******************************************************************************************************/
1536 /* hides or unhides stat cats based on library stat cat filter menu */
1537 g.toggle_stat_cat_display = function(el) {
1539 var visible = el.getAttribute('checked');
1540 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1541 for (var n = 0; n < nl.length; n++) {
1543 nl[n].setAttribute('hidden','false');
1545 nl[n].setAttribute('hidden','true');
1548 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1549 g.save_attributes();
1552 /******************************************************************************************************/
1553 /* This adds a stat cat definition to the stat cat pane for rendering */
1554 g.save_attributes = function() {
1555 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1556 var what_to_save = {};
1557 for (var i in g.copy_editor_prefs) {
1558 what_to_save[i] = [];
1559 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1561 util.widgets.save_attributes(file, what_to_save );
1564 /******************************************************************************************************/
1565 /* This adds a stat cat definition to the stat cat pane for rendering */
1566 g.add_stat_cat = function(sc) {
1568 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1572 if (typeof sc == 'object') {
1577 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1579 g.stat_cat_seen[ sc_id ] = 1;
1581 if (typeof sc != 'object') {
1583 sc = g.network.simple_request(
1584 'FM_ASC_BATCH_RETRIEVE',
1585 [ ses(), [ sc_id ] ]
1590 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1592 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1594 if (get_bool( sc.required() )) {
1595 g.required[ label_name ] = 1;
1601 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1602 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1603 input: 'c = function(v){ g.apply_stat_cat(' + sc.id() + ',v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( [ [ $("catStrings").getString("staff.cat.copy_editor.remove_stat_cat_entry"), -1 ] ].concat( util.functional.map_list( g.data.hash.asc[' + sc.id()
1604 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1605 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1612 g.panes_and_field_names.right_pane4.push( temp_array );
1614 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1618 /******************************************************************************************************/
1619 /* Add stat cats to the panes_and_field_names.right_pane4 */
1620 g.populate_stat_cats = function() {
1622 g.data.stash_retrieve();
1623 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1625 function get(lib_id,only_these) {
1626 g.data.stash_retrieve();
1627 var label = 'asc_list_for_lib_'+lib_id;
1628 if (typeof g.data[label] == 'undefined') {
1629 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1630 if (typeof robj.ilsevent != 'undefined') throw(robj);
1632 for (var j = 0; j < robj.length; j++) {
1633 var my_asc = robj[j];
1634 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1635 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1636 g.data.hash.asc[ my_asc.id() ] = my_asc;
1638 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1639 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1640 temp_list.push( my_asc );
1643 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1645 return g.data[label];
1648 /* The stat cats for the pertinent library -- this is based on workstation ou */
1649 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1650 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1651 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1652 g.add_stat_cat( g.data.list.my_asc[i] );
1655 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1656 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1658 function add_common_ancestors(sc_libs) {
1659 JSAN.use('util.fm_utils');
1660 var libs = []; for (var i in sc_libs) libs.push(i);
1661 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1662 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1664 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1665 var asc_list = get(ancestor, ancestors);
1666 for (var i = 0; i < asc_list.length; i++) {
1667 g.add_stat_cat( asc_list[i] );
1672 /* stat cats based on stat cat entries present on these copies */
1674 for (var i = 0; i < g.copies.length; i++) {
1675 var entries = g.copies[i].stat_cat_entries();
1676 if (!entries) entries = [];
1677 for (var j = 0; j < entries.length; j++) {
1678 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1679 sc_libs[ lib ] = true;
1682 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1684 /* stat cats based on Circ Lib */
1686 for (var i = 0; i < g.copies.length; i++) {
1687 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1688 sc_libs[ circ_lib ] = true;
1690 add_common_ancestors(sc_libs);
1692 /* stat cats based on Owning Lib */
1694 for (var i = 0; i < g.copies.length; i++) {
1695 var cn_id = g.copies[i].call_number();
1697 if (! g.map_acn[ cn_id ]) {
1698 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1699 if (typeof req.ilsevent == 'undefined') {
1700 g.map_acn[ cn_id ] = req;
1705 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1706 sc_libs[ owning_lib ] = true;
1709 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1711 g.panes_and_field_names.right_pane4.sort();
1715 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1719 g.check_for_unmet_required_fields = function() {
1721 for (var fn in g.required) {
1722 if (typeof g.populated[fn] == 'undefined') {
1726 if (xulG.unified_interface) {
1727 if (abort.length > 0) {
1728 if (typeof xulG.lock_save_button == 'function') {
1729 xulG.lock_save_button();
1732 if (typeof xulG.unlock_save_button == 'function') {
1733 xulG.unlock_save_button();
1737 if (abort.length > 0) {
1738 $('save').setAttribute('disabled','true');
1740 $('save').setAttribute('disabled','false');