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 */
70 fake_item.deposit_amount(0);
71 fake_item.fine_level(2); // Normal
72 fake_item.loan_duration(2); // Normal
73 fake_item.location(1); // Stacks
75 fake_item.circulate(get_db_true());
76 fake_item.holdable(get_db_true());
77 fake_item.opac_visible(get_db_true());
78 fake_item.ref(get_db_false());
79 fake_item.mint_condition(get_db_true());
80 g.copies = [ fake_item ];
81 $('save').hidden = true;
82 $('save').disabled = true;
83 $('non_unified_buttons').hidden = true;
86 /******************************************************************************************************/
87 /* Get preference (if it exists) for copy location label order */
89 g.cl_first = false; // Default to legacy OU first mode
90 var prefs = Components.classes['@mozilla.org/preferences-service;1']
91 .getService(Components.interfaces['nsIPrefBranch']);
93 g.cl_first = prefs.getBoolPref('oils.copy_editor.copy_location_name_first');
96 /******************************************************************************************************/
97 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
98 /* Quick fix, messagecatalog only usable during/after onload */
103 /******************************************************************************************************/
104 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
106 if (xul_param('edit') == '1') {
110 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
112 // Editor desired, but let's check permissions
115 var check = g.network.simple_request(
116 'PERM_MULTI_ORG_CHECK',
119 g.data.list.au[0].id(),
120 util.functional.map_list(
124 var cn_id = o.call_number();
126 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
128 if (! g.map_acn[ cn_id ]) {
129 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
130 if (typeof req.ilsevent == 'undefined') {
131 g.map_acn[ cn_id ] = req;
132 lib = g.map_acn[ cn_id ].owning_lib();
137 lib = g.map_acn[ cn_id ].owning_lib();
140 return typeof lib == 'object' ? lib.id() : lib;
143 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
146 g.edit = check.length == 0;
148 g.error.standard_unexpected_error_alert('batch permission check',E);
154 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
155 $('save').setAttribute('hidden','false');
157 $('top_nav').setAttribute('hidden','true');
160 g.retrieve_templates();
163 $('top_nav').setAttribute('hidden','true');
166 g.panes_and_field_names.left_pane =
169 $('catStrings').getString('staff.cat.copy_editor.status'),
171 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
172 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,
173 //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);',
176 ].concat(g.panes_and_field_names.left_pane);
179 /******************************************************************************************************/
180 /* Show the Record Details? */
182 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
184 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
185 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
186 brief_display.setAttribute( 'flex','1' );
189 /******************************************************************************************************/
190 /* Add stat cats to the panes_and_field_names.right_pane4 */
192 g.populate_stat_cats();
194 /******************************************************************************************************/
195 /* Backup copies :) */
197 g.original_copies = js2JSON( g.copies );
199 /******************************************************************************************************/
202 g.summarize( g.copies );
204 g.check_for_unmet_required_fields();
206 if (xulG.unified_interface) {
207 xulG.disable_copy_editor = function(c) {
208 addCSSClass(document.documentElement,'disabled_copy_editor');
211 xulG.enable_copy_editor = function(c) {
212 removeCSSClass(document.documentElement,'disabled_copy_editor');
214 xulG.refresh_copy_editor();
216 xulG.refresh_copy_editor = function() {
217 dump('refresh_copy_editor\n');
218 addCSSClass(document.documentElement,'enabling_copy_editor');
220 xulG.clear_update_copy_editor_timeout();
221 g.copies = xulG.copies;
222 g.edit = g.copies.length > 0;
224 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
226 g.original_copies = js2JSON( g.copies );
227 g.hide_copy_notes_button();
228 for (var i = 0; i < g.applied_templates.length; i++) {
229 g._apply_template( g.applied_templates[i], false);
231 if (g.copies.length > 0) {
232 // Stop tracking these templates once they're applied
234 g.applied_templates = [];
236 g.summarize( g.copies );
238 g.check_for_unmet_required_fields();
241 removeCSSClass(document.documentElement,'enabling_copy_editor');
245 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
248 xulG.unlock_copy_editor = function() {
251 xulG.notify_of_templatable_field_change = function(id,v) {
252 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
255 g.hide_copy_notes_button();
258 JSAN.use('util.hide');
259 util.hide.generate_css('ui.hide_copy_editor_fields');
262 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
263 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
268 /******************************************************************************************************/
269 /* Show copy notes button */
270 g.hide_copy_notes_button = function() {
271 if (g.copies.length > 0 && g.copies[0].id() < 0) {
272 document.getElementById('copy_notes').setAttribute('hidden','true');
273 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
274 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
276 if (g.copies.length != 1) {
277 document.getElementById('copy_notes').setAttribute('hidden','true');
281 /******************************************************************************************************/
282 /* Retrieve Templates */
284 g.retrieve_templates = function() {
286 JSAN.use('util.widgets'); JSAN.use('util.functional');
288 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
289 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
290 g.templates = robj['staff_client.copy_editor.templates'];
292 util.widgets.remove_children('template_placeholder');
293 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
295 g.template_menu = util.widgets.make_menulist( list );
296 g.template_menu.setAttribute('id','template_menu');
297 $('template_placeholder').appendChild(g.template_menu);
298 g.template_menu.addEventListener(
300 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
304 if (xulG.unified_interface) {
305 if (typeof xulG.update_unified_template_list == 'function') {
306 xulG.update_unified_template_list(list);
307 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
308 xulG.update_item_editor_template_selection = function(new_value) {
309 g.template_menu.setAttribute('value', new_value);
310 g.template_menu.value = new_value;
311 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
314 xulG.item_editor_apply_template = function() { g.apply_template(true); };
315 xulG.item_editor_delete_template = function() { g.delete_template(); };
316 xulG.item_editor_save_template = function() { g.save_template(); };
317 xulG.item_editor_import_templates = function() { g.import_templates(); };
318 xulG.item_editor_export_templates = function() { g.export_templates(); };
319 xulG.item_editor_reset = function() { g.reset(); };
324 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
328 /******************************************************************************************************/
331 g.applied_templates = [];
333 g.apply_template = function(apply_volume_editor_template_changes) {
335 var name = g.template_menu.value;
336 if (g.templates[ name ] != 'undefined') {
338 // We're only tracking these applied templates temporarily,
339 // specifically when they're used prior to copies being
340 // created in the unified interface.
341 g.applied_templates.push( name );
343 g._apply_template(name,apply_volume_editor_template_changes);
344 g.summarize( g.copies );
346 g.check_for_unmet_required_fields();
349 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
353 g._apply_template = function(name,apply_volume_editor_template_changes) {
355 if (g.templates[ name ] != 'undefined') {
356 var template = g.templates[ name ];
357 for (var i in template) {
358 if (g.is_field_hidden(i)) {
359 alert($('catStrings').getFormattedString(
360 'staff.cat.copy_editor.apply_unsafe_field',
365 if (template[i].field == 'status') {
366 if (!g.safe_to_edit_copy_status()) {
367 alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_unsafe_field',[i]));
371 g.changed[ i ] = template[ i ];
372 switch( template[i].type ) {
374 g.apply(template[i].field,template[i].value);
377 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
380 g.apply_owning_lib(template[i].value);
382 case 'volume_copy_creator' :
383 if (xulG.unified_interface && apply_volume_editor_template_changes) {
384 xulG.apply_template_to_batch(template[i].field,template[i].value);
391 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
395 /******************************************************************************************************/
396 /* Save as Template */
398 g.save_template = function() {
400 var name = window.prompt(
401 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
403 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
406 g.templates[name] = g.changed;
407 var robj = g.network.simple_request(
408 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
410 if (typeof robj.ilsevent != 'undefined') {
413 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
417 g.retrieve_templates();
419 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
425 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
429 /******************************************************************************************************/
430 /* Delete Template */
432 g.delete_template = function() {
434 var name = g.template_menu.value;
436 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
437 delete(g.templates[name]);
438 var robj = g.network.simple_request(
439 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
441 if (typeof robj.ilsevent != 'undefined') {
444 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.success', [name]));
448 g.retrieve_templates();
450 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
456 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
460 /******************************************************************************************************/
461 /* Export Templates */
463 g.export_templates = function() {
465 JSAN.use('util.file'); var f = new util.file('');
466 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
468 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
472 /******************************************************************************************************/
473 /* Import Templates */
475 g.import_templates = function() {
477 JSAN.use('util.file'); var f = new util.file('');
478 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
480 for (var i in temp) {
482 if (g.templates[i]) {
484 var r = g.error.yns_alert(
485 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
486 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
487 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
488 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
490 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
493 if (r == 0 /* Yes */) g.templates[i] = temp[i];
497 g.templates[i] = temp[i];
503 var r = g.error.yns_alert(
504 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
505 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
506 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
507 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
509 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
512 if (r == 0 /* Yes */) {
513 var robj = g.network.simple_request(
514 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
516 if (typeof robj.ilsevent != 'undefined') {
519 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
523 g.retrieve_templates();
525 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
531 util.widgets.remove_children('template_placeholder');
532 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
533 g.template_menu = util.widgets.make_menulist( list );
534 $('template_placeholder').appendChild(g.template_menu);
535 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
540 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
545 /******************************************************************************************************/
546 /* Restore backup copies */
548 g.reset = function() {
549 g.applied_templates = [];
551 g.copies = JSON2js( g.original_copies );
552 g.summarize( g.copies );
554 g.check_for_unmet_required_fields();
556 if (xulG.unified_interface) {
557 xulG.reset_batch_menus();
561 /******************************************************************************************************/
562 /* Apply a value to a specific field on all the copies being edited */
564 g.apply = function(field,value) {
565 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
566 if (value == '<HACK:KLUDGE:NULL>') {
569 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
570 if (field == 'price' || field == 'deposit_amount' || field == 'cost'){
574 JSAN.use('util.money'); value = util.money.sanitize( value );
577 for (var i = 0; i < g.copies.length; i++) {
578 var copy = g.copies[i];
580 copy[field]( value ); copy.ischanged('1');
589 /******************************************************************************************************/
590 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
592 g.apply_stat_cat = function(sc_id,entry_id) {
593 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
594 for (var i = 0; i < g.copies.length; i++) {
595 var copy = g.copies[i];
598 var temp = copy.stat_cat_entries();
599 if (!temp) temp = [];
600 temp = util.functional.filter_list(
603 return (obj.stat_cat() != sc_id);
608 util.functional.find_id_object_in_list(
609 g.data.hash.asc[sc_id].entries(),
614 copy.stat_cat_entries( temp );
617 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
624 /******************************************************************************************************/
625 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
627 g.apply_owning_lib = function(ou_id) {
628 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
629 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
630 if (! g.safe_to_change_owning_lib() ) { return; }
631 for (var i = 0; i < g.copies.length; i++) {
632 var copy = g.copies[i];
634 if (!g.map_acn[copy.call_number()]) {
635 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
636 if (typeof volume.ilsevent != 'undefined') {
637 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
640 g.map_acn[copy.call_number()] = volume;
642 var old_volume = g.map_acn[copy.call_number()];
645 acn_blob = g.network.simple_request(
646 'FM_ACN_FIND_OR_CREATE',
647 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
650 acn_blob = { 'acn_id' : -1 }; // spawned from Local Admin menu, so fake item and call number
652 if (typeof acn_blob.ilsevent != 'undefined') {
653 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
656 copy.call_number(acn_blob.acn_id);
659 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
666 /******************************************************************************************************/
667 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
669 g.safe_to_change_owning_lib = function() {
671 if (xulG.unified_interface) { return false; }
672 if (xulG.admin) { return false; }
674 for (var i = 0; i < g.copies.length; i++) {
675 var cn = g.copies[i].call_number();
676 if (typeof cn == 'object') { cn = cn.id(); }
677 if (cn == -1) { safe = false; }
681 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
686 /******************************************************************************************************/
687 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
689 g.safe_to_edit_copy_status = function() {
692 for (var i = 0; i < g.copies.length; i++) {
693 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
694 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
698 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
703 /******************************************************************************************************/
704 /* This returns true if the field has been hidden via util.hide */
706 g.is_field_hidden = function(field) {
708 g.data.stash_retrieve();
709 if (g.data.hash.aous['ui.hide_copy_editor_fields']
710 && g.data.hash.aous['ui.hide_copy_editor_fields'].indexOf(field) > -1) {
714 g.error.standard_unexpected_error_alert('is_field_hidden?',E);
720 /******************************************************************************************************/
721 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
723 g.populate_alert_message_input = function(tb) {
725 var seen = {}; var s = '';
726 for (var i = 0; i < g.copies.length; i++) {
727 var msg = g.copies[i].alert_message();
729 if (typeof seen[msg] == 'undefined') {
735 tb.setAttribute('value',s);
737 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
741 /***************************************************************************************************************/
742 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
744 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
745 g.data.stash_retrieve();
746 var label = 'acpl_list_for_lib_'+lib_id;
747 if (typeof g.data[label] == 'undefined') {
748 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
749 if (typeof robj.ilsevent != 'undefined') throw(robj);
751 for (var j = 0; j < robj.length; j++) {
752 var my_acpl = robj[j];
753 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
754 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
755 g.data.list.acpl.push( my_acpl );
757 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
758 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
759 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
760 temp_list.push( my_acpl );
763 g.data[label] = temp_list; g.data.stash(label,'hash','list');
765 return g.data[label];
768 /******************************************************************************************************/
769 /* This returns a list of acpl's appropriate for the copies being edited */
771 g.get_acpl_list = function() {
774 JSAN.use('util.functional');
778 /**************************************/
779 /* get owning libs from call numbers */
781 var owning_libs = {};
782 for (var i = 0; i < g.copies.length; i++) {
783 var callnumber = g.copies[i].call_number();
784 if (!callnumber) continue;
785 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
787 if (! g.map_acn[ cn_id ]) {
788 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
789 if (typeof req.ilsevent == 'undefined') {
790 g.map_acn[ cn_id ] = req;
795 var consider_lib = g.map_acn[ cn_id ].owning_lib();
796 if (!consider_lib) continue;
797 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
801 for (var i in g.callnumbers) {
802 var consider_lib = g.callnumbers[i].owning_lib;
803 if (!consider_lib) continue;
804 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
808 /***************************************************************************************************/
809 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
811 JSAN.use('util.fm_utils');
812 var libs = []; for (var i in owning_libs) libs.push(i);
813 if (libs.length > 0) {
814 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
815 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
818 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
819 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
820 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
821 if (acpl_list[i] != null) {
822 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
833 for (var i = 0; i < g.copies.length; i++) {
834 var consider_lib = g.copies[i].circ_lib();
835 if (!consider_lib) continue;
836 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
839 /***************************************************************************************************/
840 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
842 libs = []; for (var i in circ_libs) libs.push(i);
843 if (libs.length > 0) {
844 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
845 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
848 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
849 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
850 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
851 if (acpl_list[i] != null) {
852 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
858 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
859 return acpl_list.sort(
861 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
862 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
863 if (label_a < label_b) return -1;
864 if (label_a > label_b) return 1;
870 g.error.standard_unexpected_error_alert('get_acpl_list',E);
876 /******************************************************************************************************/
877 /* This keeps track of which fields have been edited for styling purposes */
881 /******************************************************************************************************/
882 /* This keeps track of which fields are required, and which fields have been populated */
887 /******************************************************************************************************/
888 /* These need data from the middle layer to render */
890 function init_panes0() {
891 g.special_exception = {};
892 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
893 JSAN.use('util.widgets');
894 if (value>0) { /* an existing call number */
895 g.network.simple_request(
896 'FM_ACN_RETRIEVE.authoritative',
899 var cn = '??? id = ' + value;
901 cn = req.getResultObject();
903 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
905 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
908 } else { /* a yet to be created call number */
910 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
914 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
915 if (!Number(value)) return;
916 g.network.simple_request(
917 'FM_AU_RETRIEVE_VIA_ID',
920 var p = '??? id = ' + value;
922 p = req.getResultObject();
926 g.error.sdump('D_ERROR','patron retrieve: ' + E);
928 JSAN.use('util.widgets');
929 util.widgets.set_text(label,p);
933 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
934 if (!Number(value)) return;
935 g.network.simple_request(
936 'FM_AU_RETRIEVE_VIA_ID',
939 var p = '??? id = ' + value;
941 p = req.getResultObject();
945 g.error.sdump('D_ERROR','patron retrieve: ' + E);
947 util.widgets.set_text(label,p);
953 /******************************************************************************************************/
954 g.readonly_stat_cat_names = [];
955 g.editable_stat_cat_names = [];
957 /******************************************************************************************************/
958 /* These get show in the left panel */
960 function init_panes() {
961 g.panes_and_field_names = {
966 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
968 render: 'fm.barcode();',
971 + 'g.apply("barcode", v);'
972 + 'if (typeof post_c === "function") post_c(v);'
974 + 'x = document.createElement("textbox");',
975 attr: { 'class': 'disabled' },
979 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
981 render: 'util.date.formatted_date( fm.create_date(), "%F");',
985 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
987 render: 'util.date.formatted_date( fm.active_date(), "%F");',
991 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
993 render: 'fm.creator();',
997 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
999 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
1003 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
1005 render: 'fm.editor();',
1014 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
1016 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
1017 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);',
1022 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
1024 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
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( 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);',
1026 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);',
1030 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
1032 render: 'fm.call_number();',
1033 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,
1037 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
1039 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
1040 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);',
1050 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
1052 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") )',
1053 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);',
1057 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
1059 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") )',
1060 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);',
1064 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
1066 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() )',
1067 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);',
1072 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
1074 render: 'fm.floating() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : ( typeof fm.floating() == "object" ? fm.floating().name() : g.data.hash.cfg[ fm.floating() ].name() )',
1075 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.remove_floating"), "<HACK:KLUDGE:NULL>" ] ].concat( util.functional.map_list( g.data.list.cfg, function(obj) { return [ obj.name(), obj.id() ]; }).sort() ) ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
1079 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1081 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; }',
1082 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);',
1087 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1089 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; }',
1090 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);',
1095 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1097 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',
1098 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);',
1102 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1104 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()])',
1105 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);',
1112 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1114 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1115 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);',
1120 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1122 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") )',
1123 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);',
1127 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1129 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1130 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);',
1134 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1136 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1137 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);',
1142 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1144 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") )',
1145 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);',
1149 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1151 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") )',
1152 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);',
1156 $('catStrings').getString('staff.cat.copy_editor.field.cost.label'),
1158 render: 'if (fm.cost() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.cost() ); }',
1159 input: 'c = function(v){ g.apply("cost",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);',
1163 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1165 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")',
1166 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);',
1178 /******************************************************************************************************/
1179 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1181 g.summarize = function( copies ) {
1182 /******************************************************************************************************/
1185 JSAN.use('util.date'); JSAN.use('util.money');
1188 for (var i in g.panes_and_field_names) {
1189 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1191 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1192 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1194 /******************************************************************************************************/
1195 /* Loop through the field names */
1197 for (var i = 0; i < g.field_names.length; i++) {
1199 var field_name = g.field_names[i][0];
1200 var render = g.field_names[i][1].render;
1201 var attr = g.field_names[i][1].attr;
1202 g.summary[ field_name ] = {};
1203 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1205 /******************************************************************************************************/
1206 /* Loop through the copies */
1208 for (var j = 0; j < copies.length; j++) {
1211 var cmd = render || ('fm.' + field_name + '();');
1212 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1214 /**********************************************************************************************/
1215 /* Try to retrieve the value for this field for this copy */
1218 value = eval( cmd );
1220 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1222 if (typeof value == 'object' && value != null) {
1223 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1225 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1226 delete g.populated[field_name];
1229 /**********************************************************************************************/
1230 /* Tally the count */
1232 if (g.summary[ field_name ][ value ]) {
1233 g.summary[ field_name ][ value ]++;
1235 g.summary[ field_name ][ value ] = 1;
1239 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1242 /******************************************************************************************************/
1243 /* Display the summarized data and inputs for editing */
1245 g.render = function() {
1247 /******************************************************************************************************/
1248 /* Library setup and clear any existing interface */
1250 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1252 for (var i in g.panes_and_field_names) {
1253 var p = document.getElementById(i);
1254 if (p) util.widgets.remove_children(p);
1257 /******************************************************************************************************/
1258 /* Populate the library filter menu for stat cats */
1261 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1262 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1265 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1267 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1268 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1269 for (var i = 0; i < sc_libs2.length; i++) {
1270 var menuitem = document.createElement('menuitem');
1271 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1272 menuitem.setAttribute('type','checkbox');
1273 menuitem.setAttribute('checked','true');
1274 menuitem.setAttribute('label',sc_libs2[i][0]);
1275 menuitem.setAttribute('value',sc_libs2[i][1]);
1276 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1277 x.appendChild(menuitem);
1280 /******************************************************************************************************/
1281 /* Prepare the panes */
1283 var groupbox; var caption; var vbox; var grid; var rows;
1285 /******************************************************************************************************/
1286 /* Loop through the field names */
1288 for (h in g.panes_and_field_names) {
1289 if (!document.getElementById(h)) continue;
1290 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1292 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1293 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1294 groupbox.setAttribute('hideable',fn);
1296 for (var a in attr) {
1297 groupbox.setAttribute(a,attr[a]);
1300 caption = document.createElement('caption'); groupbox.appendChild(caption);
1301 caption.setAttribute('label',fn);
1302 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1303 caption.setAttribute('hideable',fn);
1304 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1305 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1306 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1307 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1308 grid.setAttribute('flex','1');
1309 rows = grid.lastChild;
1312 /**************************************************************************************/
1313 /* Loop through each value for the field */
1315 for (var j in g.summary[fn]) {
1316 var value = j; var count = g.summary[fn][j];
1317 row = document.createElement('row'); rows.appendChild(row);
1318 var label1 = document.createElement('description'); row.appendChild(label1);
1319 if (g.special_exception[ fn ]) {
1320 g.special_exception[ fn ]( label1, value );
1322 label1.appendChild( document.createTextNode(value) );
1324 var label2 = document.createElement('description'); row.appendChild(label2);
1327 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1329 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1331 label2.appendChild( document.createTextNode(copy_count) );
1333 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1334 var hbox = document.createElement('hbox'); // main input controls go here
1335 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1336 groupbox.appendChild(hbox);
1337 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1338 groupbox.appendChild(hbox2);
1340 /**************************************************************************************/
1341 /* Render the input widget */
1343 if (f[1].input && g.edit) {
1344 g.render_input(hbox,f[1]);
1348 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1354 /******************************************************************************************************/
1355 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1356 JSAN.use('util.file');
1357 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1358 g.copy_editor_prefs = util.widgets.load_attributes(file);
1359 for (var i in g.copy_editor_prefs) {
1360 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1362 g.toggle_stat_cat_display( document.getElementById(i) );
1363 } catch(E) { alert(E); }
1366 if (g.template_menu) {
1367 g.template_menu.value = g.template_menu.getAttribute('value');
1368 if (xulG.unified_interface) {
1369 if (typeof xulG.update_unified_template_selection == 'function') {
1370 xulG.update_unified_template_selection(g.template_menu.value);
1375 util.hide.generate_css('ui.hide_copy_editor_fields');
1378 /******************************************************************************************************/
1379 /* This actually draws the change button and input widget for a given field */
1380 g.render_input = function(node,blob) {
1382 // node = hbox ; groupbox -> hbox, hbox
1384 var groupbox = node.parentNode;
1385 var caption = groupbox.firstChild;
1386 var vbox = node.previousSibling;
1388 var hbox2 = node.nextSibling;
1390 var input_cmd = blob.input;
1391 var render_cmd = blob.render;
1392 var attr = blob.attr;
1394 var block = false; var first = true;
1396 function on_mouseover(ev) {
1397 groupbox.setAttribute('style','background: white');
1400 function on_mouseout(ev) {
1401 groupbox.setAttribute('style','');
1404 groupbox.addEventListener('mouseover',on_mouseover,false);
1405 groupbox.addEventListener('mouseout',on_mouseout,false);
1407 function on_click(ev){
1409 if (block || g.disabled || !g.edit || ev.currentTarget.classList.contains('disabled')) {
1416 function post_c(v) {
1418 /* FIXME - kludgy */
1419 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1423 f = input_cmd.match(/apply\("(.+?)",/)[1];
1426 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1432 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1436 g.summarize( g.copies );
1438 g.check_for_unmet_required_fields();
1439 document.getElementById(caption.id).focus();
1443 g.error.standard_unexpected_error_alert('post_c',E);
1446 var x; var c; eval( input_cmd );
1448 util.widgets.remove_children(vbox);
1449 util.widgets.remove_children(hbox);
1450 util.widgets.remove_children(hbox2);
1451 hbox.appendChild(x);
1452 var apply = document.createElement('button');
1453 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1454 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1455 hbox2.appendChild(apply);
1456 apply.addEventListener('command',function() { c(x.value); },false);
1457 var cancel = document.createElement('button');
1458 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1459 cancel.addEventListener('command',function() {
1460 setTimeout( function() {
1461 g.summarize( g.copies );
1463 g.check_for_unmet_required_fields();
1464 document.getElementById(caption.id).focus();
1469 hbox2.appendChild(cancel);
1470 setTimeout( function() { x.focus(); }, 0 );
1473 g.error.standard_unexpected_error_alert('render_input',E);
1476 groupbox.addEventListener('click',on_click, false);
1477 groupbox.addEventListener('keypress',function(ev) {
1478 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1480 caption.setAttribute('style','-moz-user-focus: normal');
1481 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1482 caption.setAttribute('onblur','this.setAttribute("class","")');
1485 g.error.sdump('D_ERROR',E + '\n');
1489 /******************************************************************************************************/
1490 /* store the copies in the global xpcom stash */
1492 g.stash_and_close = function() {
1493 var r = {textcode: ''};
1497 if (g.handle_update) {
1499 r = g.network.request(
1500 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1501 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1502 [ ses(), g.copies, true ]
1504 if (r.textcode === 'ITEM_BARCODE_EXISTS') {
1505 alert('error with item update: ' + r.desc);
1506 var barcode = $($_('staff.cat.copy_editor.field.barcode.label'));
1507 barcode.parentNode.classList.remove('disabled');
1510 else if (typeof r.ilsevent !== 'undefined') {
1511 g.error.standard_unexpected_error_alert('copy update',r);
1513 /* FIXME -- revisit the return value here */
1515 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1518 //g.data.temp_copies = js2JSON( g.copies );
1519 //g.data.stash('temp_copies');
1520 xulG.copies = g.copies;
1521 if (r.textcode !== 'ITEM_BARCODE_EXISTS') {
1522 JSAN.use('util.widgets');
1523 util.widgets.dispatch('close',window);
1526 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1530 /******************************************************************************************************/
1531 /* spawn copy notes interface */
1533 g.copy_notes = function() {
1534 JSAN.use('util.window'); var win = new util.window();
1536 urls.XUL_COPY_NOTES,
1537 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1538 { 'copy_id' : g.copies[0].id() }
1542 /******************************************************************************************************/
1543 /* hides or unhides stat cats based on library stat cat filter menu */
1544 g.toggle_stat_cat_display = function(el) {
1546 var visible = el.getAttribute('checked');
1547 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1548 for (var n = 0; n < nl.length; n++) {
1550 nl[n].setAttribute('hidden','false');
1552 nl[n].setAttribute('hidden','true');
1555 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1556 g.save_attributes();
1559 /******************************************************************************************************/
1560 /* This adds a stat cat definition to the stat cat pane for rendering */
1561 g.save_attributes = function() {
1562 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1563 var what_to_save = {};
1564 for (var i in g.copy_editor_prefs) {
1565 what_to_save[i] = [];
1566 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1568 util.widgets.save_attributes(file, what_to_save );
1571 /******************************************************************************************************/
1572 /* This adds a stat cat definition to the stat cat pane for rendering */
1573 g.add_stat_cat = function(sc) {
1575 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1579 if (typeof sc == 'object') {
1584 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1586 g.stat_cat_seen[ sc_id ] = 1;
1588 if (typeof sc != 'object') {
1590 sc = g.network.simple_request(
1591 'FM_ASC_BATCH_RETRIEVE',
1592 [ ses(), [ sc_id ] ]
1597 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1599 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1601 if (get_bool( sc.required() )) {
1602 g.required[ label_name ] = 1;
1608 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1609 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1610 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()
1611 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1612 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1619 g.panes_and_field_names.right_pane4.push( temp_array );
1621 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1625 /******************************************************************************************************/
1626 /* Add stat cats to the panes_and_field_names.right_pane4 */
1627 g.populate_stat_cats = function() {
1629 g.data.stash_retrieve();
1630 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1632 function get(lib_id,only_these) {
1633 g.data.stash_retrieve();
1634 var label = 'asc_list_for_lib_'+lib_id;
1635 if (typeof g.data[label] == 'undefined') {
1636 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1637 if (typeof robj.ilsevent != 'undefined') throw(robj);
1639 for (var j = 0; j < robj.length; j++) {
1640 var my_asc = robj[j];
1641 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1642 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1643 g.data.hash.asc[ my_asc.id() ] = my_asc;
1645 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1646 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1647 temp_list.push( my_asc );
1650 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1652 return g.data[label];
1655 /* The stat cats for the pertinent library -- this is based on workstation ou */
1656 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1657 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1658 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1659 g.add_stat_cat( g.data.list.my_asc[i] );
1662 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1663 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1665 function add_common_ancestors(sc_libs) {
1666 JSAN.use('util.fm_utils');
1667 var libs = []; for (var i in sc_libs) libs.push(i);
1668 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1669 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1671 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1672 var asc_list = get(ancestor, ancestors);
1673 for (var i = 0; i < asc_list.length; i++) {
1674 g.add_stat_cat( asc_list[i] );
1679 /* stat cats based on stat cat entries present on these copies */
1681 for (var i = 0; i < g.copies.length; i++) {
1682 var entries = g.copies[i].stat_cat_entries();
1683 if (!entries) entries = [];
1684 for (var j = 0; j < entries.length; j++) {
1685 if (typeof g.data.hash.asc[ entries[j].stat_cat() ] != 'undefined') {
1686 continue; // We already have this stat cat, so assume we have everything we need for this lib
1688 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1689 sc_libs[ lib ] = true;
1692 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1694 /* stat cats based on Circ Lib */
1696 for (var i = 0; i < g.copies.length; i++) {
1697 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1698 if (typeof g.data.hash.my_aou[ circ_lib ] != 'undefined') {
1699 continue; // We should already have everything we need for this lib
1701 sc_libs[ circ_lib ] = true;
1703 add_common_ancestors(sc_libs);
1705 /* stat cats based on Owning Lib */
1707 for (var i = 0; i < g.copies.length; i++) {
1708 var cn_id = g.copies[i].call_number();
1710 if (! g.map_acn[ cn_id ]) {
1711 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1712 if (typeof req.ilsevent == 'undefined') {
1713 g.map_acn[ cn_id ] = req;
1718 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1719 if (typeof g.data.hash.my_aou[ owning_lib ] != 'undefined') {
1720 continue; // We should already have everything we need for this lib
1722 sc_libs[ owning_lib ] = true;
1725 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1727 g.panes_and_field_names.right_pane4.sort();
1731 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1735 g.check_for_unmet_required_fields = function() {
1737 for (var fn in g.required) {
1738 if (typeof g.populated[fn] == 'undefined') {
1742 if (xulG.unified_interface) {
1743 if (abort.length > 0) {
1744 if (typeof xulG.lock_save_button == 'function') {
1745 xulG.lock_save_button();
1748 if (typeof xulG.unlock_save_button == 'function') {
1749 xulG.unlock_save_button();
1753 if (abort.length > 0) {
1754 $('save').setAttribute('disabled','true');
1756 $('save').setAttribute('disabled','false');