2 var g = { 'disabled' : false };
5 function $(id) { return document.getElementById(id); }
9 /******************************************************************************************************/
10 /* setup JSAN and some initial libraries */
12 if (typeof JSAN == 'undefined') {
13 throw( $('commonStrings').getString('common.jsan.missing') );
15 JSAN.errorLevel = "die"; // none, warn, or die
16 JSAN.addRepository('/xul/server/');
17 JSAN.use('util.error'); g.error = new util.error();
18 g.error.sdump('D_TRACE','my_init() for cat/copy_editor.xul');
20 JSAN.use('util.functional');
21 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
22 JSAN.use('util.network'); g.network = new util.network();
24 if (xulG.unified_interface) {
25 $('non_unified_buttons').hidden = true;
28 g.docid = xul_param('docid',{'modal_xulG':true});
29 g.handle_update = xul_param('handle_update',{'modal_xulG':true});
31 /******************************************************************************************************/
32 /* Get the copy ids from various sources and flesh them */
34 var copy_ids = xul_param('copy_ids',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xulG':true,'JSON2js_if_xpcom':true,'stash_name':'temp_copy_ids','clear_xpcom':true,'modal_xulG':true});
35 if (!copy_ids) copy_ids = [];
37 if (copy_ids.length > 0) g.copies = g.network.simple_request(
38 'FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative',
42 /******************************************************************************************************/
43 /* And other fleshed copies if any */
45 if (!g.copies) g.copies = [];
46 var c = xul_param('copies',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_copies','clear_xpcom':true,'modal_xulG':true})
47 if (c) g.copies = g.copies.concat(c);
49 /******************************************************************************************************/
50 /* We try to retrieve callnumbers for existing copies, but for new copies, we rely on this */
52 g.callnumbers = xul_param('callnumbers',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_callnumbers','clear_xpcom':true,'modal_xulG':true});
54 /******************************************************************************************************/
55 /* Get preference (if it exists) for copy location label order */
57 g.cl_first = false; // Default to legacy OU first mode
58 var prefs = Components.classes['@mozilla.org/preferences-service;1']
59 .getService(Components.interfaces['nsIPrefBranch']);
61 g.cl_first = prefs.getBoolPref('oils.copy_editor.copy_location_name_first');
64 /******************************************************************************************************/
65 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
66 /* Quick fix, messagecatalog only usable during/after onload */
71 /******************************************************************************************************/
72 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
74 if (xul_param('edit',{'modal_xulG':true}) == '1') {
78 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
80 // Editor desired, but let's check permissions
83 var check = g.network.simple_request(
84 'PERM_MULTI_ORG_CHECK',
87 g.data.list.au[0].id(),
88 util.functional.map_list(
92 var cn_id = o.call_number();
94 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
96 if (! g.map_acn[ cn_id ]) {
97 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
98 if (typeof req.ilsevent == 'undefined') {
99 g.map_acn[ cn_id ] = req;
100 lib = g.map_acn[ cn_id ].owning_lib();
105 lib = g.map_acn[ cn_id ].owning_lib();
108 return typeof lib == 'object' ? lib.id() : lib;
111 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
114 g.edit = check.length == 0;
116 g.error.standard_unexpected_error_alert('batch permission check',E);
122 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
123 $('save').setAttribute('hidden','false');
125 $('top_nav').setAttribute('hidden','true');
128 g.retrieve_templates();
131 $('top_nav').setAttribute('hidden','true');
134 g.panes_and_field_names.left_pane =
137 $('catStrings').getString('staff.cat.copy_editor.status'),
139 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
140 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,
141 //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);',
144 ].concat(g.panes_and_field_names.left_pane);
147 /******************************************************************************************************/
148 /* Show the Record Details? */
150 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
152 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
153 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
154 brief_display.setAttribute( 'flex','1' );
157 /******************************************************************************************************/
158 /* Add stat cats to the panes_and_field_names.right_pane4 */
160 g.populate_stat_cats();
162 /******************************************************************************************************/
163 /* Backup copies :) */
165 g.original_copies = js2JSON( g.copies );
167 /******************************************************************************************************/
170 g.summarize( g.copies );
172 g.check_for_unmet_required_fields();
174 if (xulG.unified_interface) {
175 xulG.disable_copy_editor = function(c) {
176 addCSSClass(document.documentElement,'disabled_copy_editor');
179 xulG.enable_copy_editor = function(c) {
180 removeCSSClass(document.documentElement,'disabled_copy_editor');
182 xulG.refresh_copy_editor();
184 xulG.refresh_copy_editor = function() {
185 dump('refresh_copy_editor\n');
186 addCSSClass(document.documentElement,'enabling_copy_editor');
188 xulG.clear_update_copy_editor_timeout();
189 g.copies = xulG.copies;
190 g.edit = g.copies.length > 0;
192 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
194 g.original_copies = js2JSON( g.copies );
195 g.hide_copy_notes_button();
196 for (var i = 0; i < g.applied_templates.length; i++) {
197 g._apply_template( g.applied_templates[i], false);
199 if (g.copies.length > 0) {
200 // Stop tracking these templates once they're applied
202 g.applied_templates = [];
204 g.summarize( g.copies );
206 g.check_for_unmet_required_fields();
209 removeCSSClass(document.documentElement,'enabling_copy_editor');
213 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
216 xulG.unlock_copy_editor = function() {
219 xulG.notify_of_templatable_field_change = function(id,v) {
220 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
223 g.hide_copy_notes_button();
226 JSAN.use('util.hide');
227 util.hide.generate_css('ui.hide_copy_editor_fields');
230 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
231 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
236 /******************************************************************************************************/
237 /* Show copy notes button */
238 g.hide_copy_notes_button = function() {
239 if (g.copies.length > 0 && g.copies[0].id() < 0) {
240 document.getElementById('copy_notes').setAttribute('hidden','true');
241 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
242 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
244 if (g.copies.length != 1) {
245 document.getElementById('copy_notes').setAttribute('hidden','true');
249 /******************************************************************************************************/
250 /* Retrieve Templates */
252 g.retrieve_templates = function() {
254 JSAN.use('util.widgets'); JSAN.use('util.functional');
256 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
257 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
258 g.templates = robj['staff_client.copy_editor.templates'];
260 util.widgets.remove_children('template_placeholder');
261 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
263 g.template_menu = util.widgets.make_menulist( list );
264 g.template_menu.setAttribute('id','template_menu');
265 $('template_placeholder').appendChild(g.template_menu);
266 g.template_menu.addEventListener(
268 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
272 if (xulG.unified_interface) {
273 if (typeof xulG.update_unified_template_list == 'function') {
274 xulG.update_unified_template_list(list);
275 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
276 xulG.update_item_editor_template_selection = function(new_value) {
277 g.template_menu.setAttribute('value', new_value);
278 g.template_menu.value = new_value;
279 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
282 xulG.item_editor_apply_template = function() { g.apply_template(true); };
283 xulG.item_editor_delete_template = function() { g.delete_template(); };
284 xulG.item_editor_save_template = function() { g.save_template(); };
285 xulG.item_editor_import_templates = function() { g.import_templates(); };
286 xulG.item_editor_export_templates = function() { g.export_templates(); };
287 xulG.item_editor_reset = function() { g.reset(); };
292 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
296 /******************************************************************************************************/
299 g.applied_templates = [];
301 g.apply_template = function(apply_volume_editor_template_changes) {
303 var name = g.template_menu.value;
304 if (g.templates[ name ] != 'undefined') {
306 // We're only tracking these applied templates temporarily,
307 // specifically when they're used prior to copies being
308 // created in the unified interface.
309 g.applied_templates.push( name );
311 g._apply_template(name,apply_volume_editor_template_changes);
312 g.summarize( g.copies );
314 g.check_for_unmet_required_fields();
317 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
321 g._apply_template = function(name,apply_volume_editor_template_changes) {
323 if (g.templates[ name ] != 'undefined') {
324 var template = g.templates[ name ];
325 for (var i in template) {
326 if (g.is_field_hidden(i)) {
327 alert($('catStrings').getFormattedString(
328 'staff.cat.copy_editor.apply_unsafe_field',
333 if (template[i].field == 'status') {
334 if (!g.safe_to_edit_copy_status()) {
335 alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_unsafe_field',[i]));
339 g.changed[ i ] = template[ i ];
340 switch( template[i].type ) {
342 g.apply(template[i].field,template[i].value);
345 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
348 g.apply_owning_lib(template[i].value);
350 case 'volume_copy_creator' :
351 if (xulG.unified_interface && apply_volume_editor_template_changes) {
352 xulG.apply_template_to_batch(template[i].field,template[i].value);
359 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
363 /******************************************************************************************************/
364 /* Save as Template */
366 g.save_template = function() {
368 var name = window.prompt(
369 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
371 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
374 g.templates[name] = g.changed;
375 var robj = g.network.simple_request(
376 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
378 if (typeof robj.ilsevent != 'undefined') {
381 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
385 g.retrieve_templates();
387 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
393 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
397 /******************************************************************************************************/
398 /* Delete Template */
400 g.delete_template = function() {
402 var name = g.template_menu.value;
404 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
405 delete(g.templates[name]);
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.delete_template.confirm', [name]));
416 g.retrieve_templates();
418 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
424 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
428 /******************************************************************************************************/
429 /* Export Templates */
431 g.export_templates = function() {
433 JSAN.use('util.file'); var f = new util.file('');
434 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
436 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
440 /******************************************************************************************************/
441 /* Import Templates */
443 g.import_templates = function() {
445 JSAN.use('util.file'); var f = new util.file('');
446 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
448 for (var i in temp) {
450 if (g.templates[i]) {
452 var r = g.error.yns_alert(
453 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
454 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
455 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
456 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
458 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
461 if (r == 0 /* Yes */) g.templates[i] = temp[i];
465 g.templates[i] = temp[i];
471 var r = g.error.yns_alert(
472 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
473 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
474 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
475 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
477 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
480 if (r == 0 /* Yes */) {
481 var robj = g.network.simple_request(
482 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
484 if (typeof robj.ilsevent != 'undefined') {
487 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
491 g.retrieve_templates();
493 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
499 util.widgets.remove_children('template_placeholder');
500 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
501 g.template_menu = util.widgets.make_menulist( list );
502 $('template_placeholder').appendChild(g.template_menu);
503 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
508 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
513 /******************************************************************************************************/
514 /* Restore backup copies */
516 g.reset = function() {
517 g.applied_templates = [];
519 g.copies = JSON2js( g.original_copies );
520 g.summarize( g.copies );
522 g.check_for_unmet_required_fields();
524 if (xulG.unified_interface) {
525 xulG.reset_batch_menus();
529 /******************************************************************************************************/
530 /* Apply a value to a specific field on all the copies being edited */
532 g.apply = function(field,value) {
533 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
534 if (value == '<HACK:KLUDGE:NULL>') {
537 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
538 if (field == 'price' || field == 'deposit_amount') {
542 JSAN.use('util.money'); value = util.money.sanitize( value );
545 for (var i = 0; i < g.copies.length; i++) {
546 var copy = g.copies[i];
548 copy[field]( value ); copy.ischanged('1');
557 /******************************************************************************************************/
558 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
560 g.apply_stat_cat = function(sc_id,entry_id) {
561 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
562 for (var i = 0; i < g.copies.length; i++) {
563 var copy = g.copies[i];
566 var temp = copy.stat_cat_entries();
567 if (!temp) temp = [];
568 temp = util.functional.filter_list(
571 return (obj.stat_cat() != sc_id);
576 util.functional.find_id_object_in_list(
577 g.data.hash.asc[sc_id].entries(),
582 copy.stat_cat_entries( temp );
585 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
592 /******************************************************************************************************/
593 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
595 g.apply_owning_lib = function(ou_id) {
596 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
597 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
598 if (! g.safe_to_change_owning_lib() ) { return; }
599 for (var i = 0; i < g.copies.length; i++) {
600 var copy = g.copies[i];
602 if (!g.map_acn[copy.call_number()]) {
603 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
604 if (typeof volume.ilsevent != 'undefined') {
605 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
608 g.map_acn[copy.call_number()] = volume;
610 var old_volume = g.map_acn[copy.call_number()];
611 var acn_blob = g.network.simple_request(
612 'FM_ACN_FIND_OR_CREATE',
613 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
615 if (typeof acn_blob.ilsevent != 'undefined') {
616 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
619 copy.call_number(acn_blob.acn_id);
622 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
629 /******************************************************************************************************/
630 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
632 g.safe_to_change_owning_lib = function() {
634 if (xulG.unified_interface) { return false; }
636 for (var i = 0; i < g.copies.length; i++) {
637 var cn = g.copies[i].call_number();
638 if (typeof cn == 'object') { cn = cn.id(); }
639 if (cn == -1) { safe = false; }
643 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
648 /******************************************************************************************************/
649 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
651 g.safe_to_edit_copy_status = function() {
654 for (var i = 0; i < g.copies.length; i++) {
655 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
656 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
660 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
665 /******************************************************************************************************/
666 /* This returns true if the field has been hidden via util.hide */
668 g.is_field_hidden = function(field) {
670 g.data.stash_retrieve();
671 if (g.data.hash.aous['ui.hide_copy_editor_fields']
672 && g.data.hash.aous['ui.hide_copy_editor_fields'].indexOf(field) > -1) {
676 g.error.standard_unexpected_error_alert('is_field_hidden?',E);
682 /******************************************************************************************************/
683 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
685 g.populate_alert_message_input = function(tb) {
687 var seen = {}; var s = '';
688 for (var i = 0; i < g.copies.length; i++) {
689 var msg = g.copies[i].alert_message();
691 if (typeof seen[msg] == 'undefined') {
697 tb.setAttribute('value',s);
699 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
703 /***************************************************************************************************************/
704 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
706 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
707 g.data.stash_retrieve();
708 var label = 'acpl_list_for_lib_'+lib_id;
709 if (typeof g.data[label] == 'undefined') {
710 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
711 if (typeof robj.ilsevent != 'undefined') throw(robj);
713 for (var j = 0; j < robj.length; j++) {
714 var my_acpl = robj[j];
715 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
716 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
717 g.data.list.acpl.push( my_acpl );
719 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
720 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
721 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
722 temp_list.push( my_acpl );
725 g.data[label] = temp_list; g.data.stash(label,'hash','list');
727 return g.data[label];
730 /******************************************************************************************************/
731 /* This returns a list of acpl's appropriate for the copies being edited */
733 g.get_acpl_list = function() {
736 JSAN.use('util.functional');
740 /**************************************/
741 /* get owning libs from call numbers */
743 var owning_libs = {};
744 for (var i = 0; i < g.copies.length; i++) {
745 var callnumber = g.copies[i].call_number();
746 if (!callnumber) continue;
747 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
749 if (! g.map_acn[ cn_id ]) {
750 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
751 if (typeof req.ilsevent == 'undefined') {
752 g.map_acn[ cn_id ] = req;
757 var consider_lib = g.map_acn[ cn_id ].owning_lib();
758 if (!consider_lib) continue;
759 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
763 for (var i in g.callnumbers) {
764 var consider_lib = g.callnumbers[i].owning_lib;
765 if (!consider_lib) continue;
766 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
770 /***************************************************************************************************/
771 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
773 JSAN.use('util.fm_utils');
774 var libs = []; for (var i in owning_libs) libs.push(i);
775 if (libs.length > 0) {
776 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
777 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
780 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
781 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
782 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
783 if (acpl_list[i] != null) {
784 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
795 for (var i = 0; i < g.copies.length; i++) {
796 var consider_lib = g.copies[i].circ_lib();
797 if (!consider_lib) continue;
798 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
801 /***************************************************************************************************/
802 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
804 libs = []; for (var i in circ_libs) libs.push(i);
805 if (libs.length > 0) {
806 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
807 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
810 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
811 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
812 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
813 if (acpl_list[i] != null) {
814 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
820 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
821 return acpl_list.sort(
823 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
824 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
825 if (label_a < label_b) return -1;
826 if (label_a > label_b) return 1;
832 g.error.standard_unexpected_error_alert('get_acpl_list',E);
838 /******************************************************************************************************/
839 /* This keeps track of which fields have been edited for styling purposes */
843 /******************************************************************************************************/
844 /* This keeps track of which fields are required, and which fields have been populated */
849 /******************************************************************************************************/
850 /* These need data from the middle layer to render */
852 function init_panes0() {
853 g.special_exception = {};
854 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
855 JSAN.use('util.widgets');
856 if (value>0) { /* an existing call number */
857 g.network.simple_request(
858 'FM_ACN_RETRIEVE.authoritative',
861 var cn = '??? id = ' + value;
863 cn = req.getResultObject();
865 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
867 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
870 } else { /* a yet to be created call number */
872 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
876 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
877 if (!Number(value)) return;
878 g.network.simple_request(
879 'FM_AU_RETRIEVE_VIA_ID',
882 var p = '??? id = ' + value;
884 p = req.getResultObject();
888 g.error.sdump('D_ERROR','patron retrieve: ' + E);
890 JSAN.use('util.widgets');
891 util.widgets.set_text(label,p);
895 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
896 if (!Number(value)) return;
897 g.network.simple_request(
898 'FM_AU_RETRIEVE_VIA_ID',
901 var p = '??? id = ' + value;
903 p = req.getResultObject();
907 g.error.sdump('D_ERROR','patron retrieve: ' + E);
909 util.widgets.set_text(label,p);
915 /******************************************************************************************************/
916 g.readonly_stat_cat_names = [];
917 g.editable_stat_cat_names = [];
919 /******************************************************************************************************/
920 /* These get show in the left panel */
922 function init_panes() {
923 g.panes_and_field_names = {
928 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
930 render: 'fm.barcode();',
934 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
936 render: 'util.date.formatted_date( fm.create_date(), "%F");',
940 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
942 render: 'util.date.formatted_date( fm.active_date(), "%F");',
946 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
948 render: 'fm.creator();',
952 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
954 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
958 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
960 render: 'fm.editor();',
969 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
971 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
972 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);',
977 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
979 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
980 //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);',
981 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);',
985 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
987 render: 'fm.call_number();',
988 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,
992 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
994 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
995 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);',
1005 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
1007 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") )',
1008 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);',
1012 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
1014 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") )',
1015 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);',
1019 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
1021 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() )',
1022 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);',
1027 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
1029 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") )',
1030 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);',
1034 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1036 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; }',
1037 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);',
1042 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1044 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; }',
1045 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);',
1050 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1052 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',
1053 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);',
1057 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1059 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()])',
1060 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);',
1067 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1069 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1070 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);',
1075 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1077 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") )',
1078 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);',
1082 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1084 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1085 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);',
1089 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1091 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1092 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);',
1097 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1099 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") )',
1100 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);',
1104 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1106 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") )',
1107 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);',
1111 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1113 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")',
1114 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);',
1126 /******************************************************************************************************/
1127 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1129 g.summarize = function( copies ) {
1130 /******************************************************************************************************/
1133 JSAN.use('util.date'); JSAN.use('util.money');
1136 for (var i in g.panes_and_field_names) {
1137 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1139 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1140 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1142 /******************************************************************************************************/
1143 /* Loop through the field names */
1145 for (var i = 0; i < g.field_names.length; i++) {
1147 var field_name = g.field_names[i][0];
1148 var render = g.field_names[i][1].render;
1149 var attr = g.field_names[i][1].attr;
1150 g.summary[ field_name ] = {};
1151 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1153 /******************************************************************************************************/
1154 /* Loop through the copies */
1156 for (var j = 0; j < copies.length; j++) {
1159 var cmd = render || ('fm.' + field_name + '();');
1160 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1162 /**********************************************************************************************/
1163 /* Try to retrieve the value for this field for this copy */
1166 value = eval( cmd );
1168 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1170 if (typeof value == 'object' && value != null) {
1171 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1173 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1174 delete g.populated[field_name];
1177 /**********************************************************************************************/
1178 /* Tally the count */
1180 if (g.summary[ field_name ][ value ]) {
1181 g.summary[ field_name ][ value ]++;
1183 g.summary[ field_name ][ value ] = 1;
1187 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1190 /******************************************************************************************************/
1191 /* Display the summarized data and inputs for editing */
1193 g.render = function() {
1195 /******************************************************************************************************/
1196 /* Library setup and clear any existing interface */
1198 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1200 for (var i in g.panes_and_field_names) {
1201 var p = document.getElementById(i);
1202 if (p) util.widgets.remove_children(p);
1205 /******************************************************************************************************/
1206 /* Populate the library filter menu for stat cats */
1209 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1210 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1213 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1215 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1216 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1217 for (var i = 0; i < sc_libs2.length; i++) {
1218 var menuitem = document.createElement('menuitem');
1219 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1220 menuitem.setAttribute('type','checkbox');
1221 menuitem.setAttribute('checked','true');
1222 menuitem.setAttribute('label',sc_libs2[i][0]);
1223 menuitem.setAttribute('value',sc_libs2[i][1]);
1224 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1225 x.appendChild(menuitem);
1228 /******************************************************************************************************/
1229 /* Prepare the panes */
1231 var groupbox; var caption; var vbox; var grid; var rows;
1233 /******************************************************************************************************/
1234 /* Loop through the field names */
1236 for (h in g.panes_and_field_names) {
1237 if (!document.getElementById(h)) continue;
1238 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1240 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1241 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1242 groupbox.setAttribute('hideable',fn);
1244 for (var a in attr) {
1245 groupbox.setAttribute(a,attr[a]);
1248 caption = document.createElement('caption'); groupbox.appendChild(caption);
1249 caption.setAttribute('label',fn);
1250 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1251 caption.setAttribute('hideable',fn);
1252 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1253 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1254 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1255 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1256 grid.setAttribute('flex','1');
1257 rows = grid.lastChild;
1260 /**************************************************************************************/
1261 /* Loop through each value for the field */
1263 for (var j in g.summary[fn]) {
1264 var value = j; var count = g.summary[fn][j];
1265 row = document.createElement('row'); rows.appendChild(row);
1266 var label1 = document.createElement('description'); row.appendChild(label1);
1267 if (g.special_exception[ fn ]) {
1268 g.special_exception[ fn ]( label1, value );
1270 label1.appendChild( document.createTextNode(value) );
1272 var label2 = document.createElement('description'); row.appendChild(label2);
1275 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1277 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1279 label2.appendChild( document.createTextNode(copy_count) );
1281 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1282 var hbox = document.createElement('hbox'); // main input controls go here
1283 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1284 groupbox.appendChild(hbox);
1285 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1286 groupbox.appendChild(hbox2);
1288 /**************************************************************************************/
1289 /* Render the input widget */
1291 if (f[1].input && g.edit) {
1292 g.render_input(hbox,f[1]);
1296 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1302 /******************************************************************************************************/
1303 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1304 JSAN.use('util.file');
1305 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1306 g.copy_editor_prefs = util.widgets.load_attributes(file);
1307 for (var i in g.copy_editor_prefs) {
1308 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1310 g.toggle_stat_cat_display( document.getElementById(i) );
1311 } catch(E) { alert(E); }
1314 if (g.template_menu) {
1315 g.template_menu.value = g.template_menu.getAttribute('value');
1316 if (xulG.unified_interface) {
1317 if (typeof xulG.update_unified_template_selection == 'function') {
1318 xulG.update_unified_template_selection(g.template_menu.value);
1323 util.hide.generate_css('ui.hide_copy_editor_fields');
1326 /******************************************************************************************************/
1327 /* This actually draws the change button and input widget for a given field */
1328 g.render_input = function(node,blob) {
1330 // node = hbox ; groupbox -> hbox, hbox
1332 var groupbox = node.parentNode;
1333 var caption = groupbox.firstChild;
1334 var vbox = node.previousSibling;
1336 var hbox2 = node.nextSibling;
1338 var input_cmd = blob.input;
1339 var render_cmd = blob.render;
1340 var attr = blob.attr;
1342 var block = false; var first = true;
1344 function on_mouseover(ev) {
1345 groupbox.setAttribute('style','background: white');
1348 function on_mouseout(ev) {
1349 groupbox.setAttribute('style','');
1352 vbox.addEventListener('mouseover',on_mouseover,false);
1353 vbox.addEventListener('mouseout',on_mouseout,false);
1354 groupbox.addEventListener('mouseover',on_mouseover,false);
1355 groupbox.addEventListener('mouseout',on_mouseout,false);
1356 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1357 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1359 function on_click(ev){
1361 if (block || g.disabled || !g.edit) {
1368 function post_c(v) {
1370 /* FIXME - kludgy */
1371 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1375 f = input_cmd.match(/apply\("(.+?)",/)[1];
1378 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1384 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1388 g.summarize( g.copies );
1390 g.check_for_unmet_required_fields();
1391 document.getElementById(caption.id).focus();
1395 g.error.standard_unexpected_error_alert('post_c',E);
1398 var x; var c; eval( input_cmd );
1400 util.widgets.remove_children(vbox);
1401 util.widgets.remove_children(hbox);
1402 util.widgets.remove_children(hbox2);
1403 hbox.appendChild(x);
1404 var apply = document.createElement('button');
1405 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1406 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1407 hbox2.appendChild(apply);
1408 apply.addEventListener('command',function() { c(x.value); },false);
1409 var cancel = document.createElement('button');
1410 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1411 cancel.addEventListener('command',function() {
1412 setTimeout( function() {
1413 g.summarize( g.copies );
1415 g.check_for_unmet_required_fields();
1416 document.getElementById(caption.id).focus();
1421 hbox2.appendChild(cancel);
1422 setTimeout( function() { x.focus(); }, 0 );
1425 g.error.standard_unexpected_error_alert('render_input',E);
1428 vbox.addEventListener('click',on_click, false);
1429 hbox.addEventListener('click',on_click, false);
1430 caption.addEventListener('click',on_click, false);
1431 caption.addEventListener('keypress',function(ev) {
1432 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1434 caption.setAttribute('style','-moz-user-focus: normal');
1435 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1436 caption.setAttribute('onblur','this.setAttribute("class","")');
1439 g.error.sdump('D_ERROR',E + '\n');
1443 /******************************************************************************************************/
1444 /* store the copies in the global xpcom stash */
1446 g.stash_and_close = function() {
1450 if (g.handle_update) {
1452 var r = g.network.request(
1453 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1454 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1455 [ ses(), g.copies, true ]
1457 if (typeof r.ilsevent != 'undefined') {
1458 g.error.standard_unexpected_error_alert('copy update',r);
1460 /* FIXME -- revisit the return value here */
1462 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1465 //g.data.temp_copies = js2JSON( g.copies );
1466 //g.data.stash('temp_copies');
1467 xulG.copies = g.copies;
1468 update_modal_xulG(xulG);
1469 JSAN.use('util.widgets');
1470 util.widgets.dispatch('close',window);
1472 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1476 /******************************************************************************************************/
1477 /* spawn copy notes interface */
1479 g.copy_notes = function() {
1480 JSAN.use('util.window'); var win = new util.window();
1482 urls.XUL_COPY_NOTES,
1483 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1484 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1485 { 'copy_id' : g.copies[0].id() }
1489 /******************************************************************************************************/
1490 /* hides or unhides stat cats based on library stat cat filter menu */
1491 g.toggle_stat_cat_display = function(el) {
1493 var visible = el.getAttribute('checked');
1494 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1495 for (var n = 0; n < nl.length; n++) {
1497 nl[n].setAttribute('hidden','false');
1499 nl[n].setAttribute('hidden','true');
1502 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1503 g.save_attributes();
1506 /******************************************************************************************************/
1507 /* This adds a stat cat definition to the stat cat pane for rendering */
1508 g.save_attributes = function() {
1509 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1510 var what_to_save = {};
1511 for (var i in g.copy_editor_prefs) {
1512 what_to_save[i] = [];
1513 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1515 util.widgets.save_attributes(file, what_to_save );
1518 /******************************************************************************************************/
1519 /* This adds a stat cat definition to the stat cat pane for rendering */
1520 g.add_stat_cat = function(sc) {
1522 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1526 if (typeof sc == 'object') {
1531 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1533 g.stat_cat_seen[ sc_id ] = 1;
1535 if (typeof sc != 'object') {
1537 sc = g.network.simple_request(
1538 'FM_ASC_BATCH_RETRIEVE',
1539 [ ses(), [ sc_id ] ]
1544 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1546 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1548 if (get_bool( sc.required() )) {
1549 g.required[ label_name ] = 1;
1555 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1556 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1557 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()
1558 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1559 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1566 g.panes_and_field_names.right_pane4.push( temp_array );
1568 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1572 /******************************************************************************************************/
1573 /* Add stat cats to the panes_and_field_names.right_pane4 */
1574 g.populate_stat_cats = function() {
1576 g.data.stash_retrieve();
1577 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1579 function get(lib_id,only_these) {
1580 g.data.stash_retrieve();
1581 var label = 'asc_list_for_lib_'+lib_id;
1582 if (typeof g.data[label] == 'undefined') {
1583 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1584 if (typeof robj.ilsevent != 'undefined') throw(robj);
1586 for (var j = 0; j < robj.length; j++) {
1587 var my_asc = robj[j];
1588 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1589 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1590 g.data.hash.asc[ my_asc.id() ] = my_asc;
1592 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1593 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1594 temp_list.push( my_asc );
1597 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1599 return g.data[label];
1602 /* The stat cats for the pertinent library -- this is based on workstation ou */
1603 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1604 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1605 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1606 g.add_stat_cat( g.data.list.my_asc[i] );
1609 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1610 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1612 function add_common_ancestors(sc_libs) {
1613 JSAN.use('util.fm_utils');
1614 var libs = []; for (var i in sc_libs) libs.push(i);
1615 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1616 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1618 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1619 var asc_list = get(ancestor, ancestors);
1620 for (var i = 0; i < asc_list.length; i++) {
1621 g.add_stat_cat( asc_list[i] );
1626 /* stat cats based on stat cat entries present on these copies */
1628 for (var i = 0; i < g.copies.length; i++) {
1629 var entries = g.copies[i].stat_cat_entries();
1630 if (!entries) entries = [];
1631 for (var j = 0; j < entries.length; j++) {
1632 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1633 sc_libs[ lib ] = true;
1636 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1638 /* stat cats based on Circ Lib */
1640 for (var i = 0; i < g.copies.length; i++) {
1641 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1642 sc_libs[ circ_lib ] = true;
1644 add_common_ancestors(sc_libs);
1646 /* stat cats based on Owning Lib */
1648 for (var i = 0; i < g.copies.length; i++) {
1649 var cn_id = g.copies[i].call_number();
1651 if (! g.map_acn[ cn_id ]) {
1652 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1653 if (typeof req.ilsevent == 'undefined') {
1654 g.map_acn[ cn_id ] = req;
1659 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1660 sc_libs[ owning_lib ] = true;
1663 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1665 g.panes_and_field_names.right_pane4.sort();
1669 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1673 g.check_for_unmet_required_fields = function() {
1675 for (var fn in g.required) {
1676 if (typeof g.populated[fn] == 'undefined') {
1680 if (xulG.unified_interface) {
1681 if (abort.length > 0) {
1682 if (typeof xulG.lock_save_button == 'function') {
1683 xulG.lock_save_button();
1686 if (typeof xulG.unlock_save_button == 'function') {
1687 xulG.unlock_save_button();
1691 if (abort.length > 0) {
1692 $('save').setAttribute('disabled','true');
1694 $('save').setAttribute('disabled','false');