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 /* Get preference (if it exists) for copy location label order */
58 g.cl_first = false; // Default to legacy OU first mode
59 var prefs = Components.classes['@mozilla.org/preferences-service;1']
60 .getService(Components.interfaces['nsIPrefBranch']);
62 g.cl_first = prefs.getBoolPref('oils.copy_editor.copy_location_name_first');
65 /******************************************************************************************************/
66 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
67 /* Quick fix, messagecatalog only usable during/after onload */
72 /******************************************************************************************************/
73 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
75 if (xul_param('edit') == '1') {
79 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
81 // Editor desired, but let's check permissions
84 var check = g.network.simple_request(
85 'PERM_MULTI_ORG_CHECK',
88 g.data.list.au[0].id(),
89 util.functional.map_list(
93 var cn_id = o.call_number();
95 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
97 if (! g.map_acn[ cn_id ]) {
98 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
99 if (typeof req.ilsevent == 'undefined') {
100 g.map_acn[ cn_id ] = req;
101 lib = g.map_acn[ cn_id ].owning_lib();
106 lib = g.map_acn[ cn_id ].owning_lib();
109 return typeof lib == 'object' ? lib.id() : lib;
112 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
115 g.edit = check.length == 0;
117 g.error.standard_unexpected_error_alert('batch permission check',E);
123 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
124 $('save').setAttribute('hidden','false');
126 $('top_nav').setAttribute('hidden','true');
129 g.retrieve_templates();
132 $('top_nav').setAttribute('hidden','true');
135 g.panes_and_field_names.left_pane =
138 $('catStrings').getString('staff.cat.copy_editor.status'),
140 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
141 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,
142 //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);',
145 ].concat(g.panes_and_field_names.left_pane);
148 /******************************************************************************************************/
149 /* Show the Record Details? */
151 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
153 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
154 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
155 brief_display.setAttribute( 'flex','1' );
158 /******************************************************************************************************/
159 /* Add stat cats to the panes_and_field_names.right_pane4 */
161 g.populate_stat_cats();
163 /******************************************************************************************************/
164 /* Backup copies :) */
166 g.original_copies = js2JSON( g.copies );
168 /******************************************************************************************************/
171 g.summarize( g.copies );
173 g.check_for_unmet_required_fields();
175 if (xulG.unified_interface) {
176 xulG.disable_copy_editor = function(c) {
177 addCSSClass(document.documentElement,'disabled_copy_editor');
180 xulG.enable_copy_editor = function(c) {
181 removeCSSClass(document.documentElement,'disabled_copy_editor');
183 xulG.refresh_copy_editor();
185 xulG.refresh_copy_editor = function() {
186 dump('refresh_copy_editor\n');
187 addCSSClass(document.documentElement,'enabling_copy_editor');
189 xulG.clear_update_copy_editor_timeout();
190 g.copies = xulG.copies;
191 g.edit = g.copies.length > 0;
193 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
195 g.original_copies = js2JSON( g.copies );
196 g.hide_copy_notes_button();
197 for (var i = 0; i < g.applied_templates.length; i++) {
198 g._apply_template( g.applied_templates[i], false);
200 if (g.copies.length > 0) {
201 // Stop tracking these templates once they're applied
203 g.applied_templates = [];
205 g.summarize( g.copies );
207 g.check_for_unmet_required_fields();
210 removeCSSClass(document.documentElement,'enabling_copy_editor');
214 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
217 xulG.unlock_copy_editor = function() {
220 xulG.notify_of_templatable_field_change = function(id,v) {
221 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
224 g.hide_copy_notes_button();
227 JSAN.use('util.hide');
228 util.hide.generate_css('ui.hide_copy_editor_fields');
231 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
232 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
237 /******************************************************************************************************/
238 /* Show copy notes button */
239 g.hide_copy_notes_button = function() {
240 if (g.copies.length > 0 && g.copies[0].id() < 0) {
241 document.getElementById('copy_notes').setAttribute('hidden','true');
242 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
243 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
245 if (g.copies.length != 1) {
246 document.getElementById('copy_notes').setAttribute('hidden','true');
250 /******************************************************************************************************/
251 /* Retrieve Templates */
253 g.retrieve_templates = function() {
255 JSAN.use('util.widgets'); JSAN.use('util.functional');
257 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
258 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
259 g.templates = robj['staff_client.copy_editor.templates'];
261 util.widgets.remove_children('template_placeholder');
262 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
264 g.template_menu = util.widgets.make_menulist( list );
265 g.template_menu.setAttribute('id','template_menu');
266 $('template_placeholder').appendChild(g.template_menu);
267 g.template_menu.addEventListener(
269 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
273 if (xulG.unified_interface) {
274 if (typeof xulG.update_unified_template_list == 'function') {
275 xulG.update_unified_template_list(list);
276 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
277 xulG.update_item_editor_template_selection = function(new_value) {
278 g.template_menu.setAttribute('value', new_value);
279 g.template_menu.value = new_value;
280 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
283 xulG.item_editor_apply_template = function() { g.apply_template(true); };
284 xulG.item_editor_delete_template = function() { g.delete_template(); };
285 xulG.item_editor_save_template = function() { g.save_template(); };
286 xulG.item_editor_import_templates = function() { g.import_templates(); };
287 xulG.item_editor_export_templates = function() { g.export_templates(); };
288 xulG.item_editor_reset = function() { g.reset(); };
293 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
297 /******************************************************************************************************/
300 g.applied_templates = [];
302 g.apply_template = function(apply_volume_editor_template_changes) {
304 var name = g.template_menu.value;
305 if (g.templates[ name ] != 'undefined') {
307 // We're only tracking these applied templates temporarily,
308 // specifically when they're used prior to copies being
309 // created in the unified interface.
310 g.applied_templates.push( name );
312 g._apply_template(name,apply_volume_editor_template_changes);
313 g.summarize( g.copies );
315 g.check_for_unmet_required_fields();
318 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
322 g._apply_template = function(name,apply_volume_editor_template_changes) {
324 if (g.templates[ name ] != 'undefined') {
325 var template = g.templates[ name ];
326 for (var i in template) {
327 if (g.is_field_hidden(i)) {
328 alert($('catStrings').getFormattedString(
329 'staff.cat.copy_editor.apply_unsafe_field',
334 if (template[i].field == 'status') {
335 if (!g.safe_to_edit_copy_status()) {
336 alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_unsafe_field',[i]));
340 g.changed[ i ] = template[ i ];
341 switch( template[i].type ) {
343 g.apply(template[i].field,template[i].value);
346 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
349 g.apply_owning_lib(template[i].value);
351 case 'volume_copy_creator' :
352 if (xulG.unified_interface && apply_volume_editor_template_changes) {
353 xulG.apply_template_to_batch(template[i].field,template[i].value);
360 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
364 /******************************************************************************************************/
365 /* Save as Template */
367 g.save_template = function() {
369 var name = window.prompt(
370 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
372 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
375 g.templates[name] = g.changed;
376 var robj = g.network.simple_request(
377 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
379 if (typeof robj.ilsevent != 'undefined') {
382 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
386 g.retrieve_templates();
388 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
394 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
398 /******************************************************************************************************/
399 /* Delete Template */
401 g.delete_template = function() {
403 var name = g.template_menu.value;
405 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
406 delete(g.templates[name]);
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.delete_template.confirm', [name]));
417 g.retrieve_templates();
419 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
425 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
429 /******************************************************************************************************/
430 /* Export Templates */
432 g.export_templates = function() {
434 JSAN.use('util.file'); var f = new util.file('');
435 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
437 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
441 /******************************************************************************************************/
442 /* Import Templates */
444 g.import_templates = function() {
446 JSAN.use('util.file'); var f = new util.file('');
447 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
449 for (var i in temp) {
451 if (g.templates[i]) {
453 var r = g.error.yns_alert(
454 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
455 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
456 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
457 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
459 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
462 if (r == 0 /* Yes */) g.templates[i] = temp[i];
466 g.templates[i] = temp[i];
472 var r = g.error.yns_alert(
473 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
474 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
475 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
476 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
478 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
481 if (r == 0 /* Yes */) {
482 var robj = g.network.simple_request(
483 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
485 if (typeof robj.ilsevent != 'undefined') {
488 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
492 g.retrieve_templates();
494 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
500 util.widgets.remove_children('template_placeholder');
501 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
502 g.template_menu = util.widgets.make_menulist( list );
503 $('template_placeholder').appendChild(g.template_menu);
504 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
509 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
514 /******************************************************************************************************/
515 /* Restore backup copies */
517 g.reset = function() {
518 g.applied_templates = [];
520 g.copies = JSON2js( g.original_copies );
521 g.summarize( g.copies );
523 g.check_for_unmet_required_fields();
525 if (xulG.unified_interface) {
526 xulG.reset_batch_menus();
530 /******************************************************************************************************/
531 /* Apply a value to a specific field on all the copies being edited */
533 g.apply = function(field,value) {
534 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
535 if (value == '<HACK:KLUDGE:NULL>') {
538 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
539 if (field == 'price' || field == 'deposit_amount') {
543 JSAN.use('util.money'); value = util.money.sanitize( value );
546 for (var i = 0; i < g.copies.length; i++) {
547 var copy = g.copies[i];
549 copy[field]( value ); copy.ischanged('1');
558 /******************************************************************************************************/
559 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
561 g.apply_stat_cat = function(sc_id,entry_id) {
562 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
563 for (var i = 0; i < g.copies.length; i++) {
564 var copy = g.copies[i];
567 var temp = copy.stat_cat_entries();
568 if (!temp) temp = [];
569 temp = util.functional.filter_list(
572 return (obj.stat_cat() != sc_id);
577 util.functional.find_id_object_in_list(
578 g.data.hash.asc[sc_id].entries(),
583 copy.stat_cat_entries( temp );
586 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
593 /******************************************************************************************************/
594 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
596 g.apply_owning_lib = function(ou_id) {
597 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
598 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
599 if (! g.safe_to_change_owning_lib() ) { return; }
600 for (var i = 0; i < g.copies.length; i++) {
601 var copy = g.copies[i];
603 if (!g.map_acn[copy.call_number()]) {
604 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
605 if (typeof volume.ilsevent != 'undefined') {
606 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
609 g.map_acn[copy.call_number()] = volume;
611 var old_volume = g.map_acn[copy.call_number()];
612 var acn_blob = g.network.simple_request(
613 'FM_ACN_FIND_OR_CREATE',
614 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
616 if (typeof acn_blob.ilsevent != 'undefined') {
617 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
620 copy.call_number(acn_blob.acn_id);
623 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
630 /******************************************************************************************************/
631 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
633 g.safe_to_change_owning_lib = function() {
635 if (xulG.unified_interface) { return false; }
637 for (var i = 0; i < g.copies.length; i++) {
638 var cn = g.copies[i].call_number();
639 if (typeof cn == 'object') { cn = cn.id(); }
640 if (cn == -1) { safe = false; }
644 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
649 /******************************************************************************************************/
650 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
652 g.safe_to_edit_copy_status = function() {
655 for (var i = 0; i < g.copies.length; i++) {
656 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
657 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
661 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
666 /******************************************************************************************************/
667 /* This returns true if the field has been hidden via util.hide */
669 g.is_field_hidden = function(field) {
671 g.data.stash_retrieve();
672 if (g.data.hash.aous['ui.hide_copy_editor_fields']
673 && g.data.hash.aous['ui.hide_copy_editor_fields'].indexOf(field) > -1) {
677 g.error.standard_unexpected_error_alert('is_field_hidden?',E);
683 /******************************************************************************************************/
684 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
686 g.populate_alert_message_input = function(tb) {
688 var seen = {}; var s = '';
689 for (var i = 0; i < g.copies.length; i++) {
690 var msg = g.copies[i].alert_message();
692 if (typeof seen[msg] == 'undefined') {
698 tb.setAttribute('value',s);
700 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
704 /***************************************************************************************************************/
705 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
707 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
708 g.data.stash_retrieve();
709 var label = 'acpl_list_for_lib_'+lib_id;
710 if (typeof g.data[label] == 'undefined') {
711 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
712 if (typeof robj.ilsevent != 'undefined') throw(robj);
714 for (var j = 0; j < robj.length; j++) {
715 var my_acpl = robj[j];
716 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
717 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
718 g.data.list.acpl.push( my_acpl );
720 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
721 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
722 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
723 temp_list.push( my_acpl );
726 g.data[label] = temp_list; g.data.stash(label,'hash','list');
728 return g.data[label];
731 /******************************************************************************************************/
732 /* This returns a list of acpl's appropriate for the copies being edited */
734 g.get_acpl_list = function() {
737 JSAN.use('util.functional');
741 /**************************************/
742 /* get owning libs from call numbers */
744 var owning_libs = {};
745 for (var i = 0; i < g.copies.length; i++) {
746 var callnumber = g.copies[i].call_number();
747 if (!callnumber) continue;
748 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
750 if (! g.map_acn[ cn_id ]) {
751 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
752 if (typeof req.ilsevent == 'undefined') {
753 g.map_acn[ cn_id ] = req;
758 var consider_lib = g.map_acn[ cn_id ].owning_lib();
759 if (!consider_lib) continue;
760 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
764 for (var i in g.callnumbers) {
765 var consider_lib = g.callnumbers[i].owning_lib;
766 if (!consider_lib) continue;
767 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
771 /***************************************************************************************************/
772 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
774 JSAN.use('util.fm_utils');
775 var libs = []; for (var i in owning_libs) libs.push(i);
776 if (libs.length > 0) {
777 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
778 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
781 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
782 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
783 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
784 if (acpl_list[i] != null) {
785 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
796 for (var i = 0; i < g.copies.length; i++) {
797 var consider_lib = g.copies[i].circ_lib();
798 if (!consider_lib) continue;
799 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
802 /***************************************************************************************************/
803 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
805 libs = []; for (var i in circ_libs) libs.push(i);
806 if (libs.length > 0) {
807 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
808 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
811 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
812 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
813 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
814 if (acpl_list[i] != null) {
815 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
821 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
822 return acpl_list.sort(
824 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
825 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
826 if (label_a < label_b) return -1;
827 if (label_a > label_b) return 1;
833 g.error.standard_unexpected_error_alert('get_acpl_list',E);
839 /******************************************************************************************************/
840 /* This keeps track of which fields have been edited for styling purposes */
844 /******************************************************************************************************/
845 /* This keeps track of which fields are required, and which fields have been populated */
850 /******************************************************************************************************/
851 /* These need data from the middle layer to render */
853 function init_panes0() {
854 g.special_exception = {};
855 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
856 JSAN.use('util.widgets');
857 if (value>0) { /* an existing call number */
858 g.network.simple_request(
859 'FM_ACN_RETRIEVE.authoritative',
862 var cn = '??? id = ' + value;
864 cn = req.getResultObject();
866 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
868 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
871 } else { /* a yet to be created call number */
873 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
877 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
878 if (!Number(value)) return;
879 g.network.simple_request(
880 'FM_AU_RETRIEVE_VIA_ID',
883 var p = '??? id = ' + value;
885 p = req.getResultObject();
889 g.error.sdump('D_ERROR','patron retrieve: ' + E);
891 JSAN.use('util.widgets');
892 util.widgets.set_text(label,p);
896 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
897 if (!Number(value)) return;
898 g.network.simple_request(
899 'FM_AU_RETRIEVE_VIA_ID',
902 var p = '??? id = ' + value;
904 p = req.getResultObject();
908 g.error.sdump('D_ERROR','patron retrieve: ' + E);
910 util.widgets.set_text(label,p);
916 /******************************************************************************************************/
917 g.readonly_stat_cat_names = [];
918 g.editable_stat_cat_names = [];
920 /******************************************************************************************************/
921 /* These get show in the left panel */
923 function init_panes() {
924 g.panes_and_field_names = {
929 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
931 render: 'fm.barcode();',
934 + 'g.apply("barcode", v);'
935 + 'if (typeof post_c === "function") post_c(v);'
937 + 'x = document.createElement("textbox");',
938 attr: { 'class': 'disabled' },
942 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
944 render: 'util.date.formatted_date( fm.create_date(), "%F");',
948 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
950 render: 'util.date.formatted_date( fm.active_date(), "%F");',
954 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
956 render: 'fm.creator();',
960 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
962 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
966 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
968 render: 'fm.editor();',
977 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
979 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
980 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);',
985 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
987 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
988 //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);',
989 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);',
993 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
995 render: 'fm.call_number();',
996 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,
1000 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
1002 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
1003 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);',
1013 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
1015 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") )',
1016 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);',
1020 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
1022 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") )',
1023 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);',
1027 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
1029 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() )',
1030 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);',
1035 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
1037 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") )',
1038 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);',
1042 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1044 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; }',
1045 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);',
1050 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1052 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; }',
1053 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);',
1058 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1060 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',
1061 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);',
1065 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1067 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()])',
1068 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);',
1075 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1077 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1078 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);',
1083 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1085 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") )',
1086 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);',
1090 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1092 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1093 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);',
1097 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1099 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1100 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);',
1105 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1107 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") )',
1108 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);',
1112 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1114 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") )',
1115 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);',
1119 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1121 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")',
1122 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);',
1134 /******************************************************************************************************/
1135 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1137 g.summarize = function( copies ) {
1138 /******************************************************************************************************/
1141 JSAN.use('util.date'); JSAN.use('util.money');
1144 for (var i in g.panes_and_field_names) {
1145 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1147 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1148 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1150 /******************************************************************************************************/
1151 /* Loop through the field names */
1153 for (var i = 0; i < g.field_names.length; i++) {
1155 var field_name = g.field_names[i][0];
1156 var render = g.field_names[i][1].render;
1157 var attr = g.field_names[i][1].attr;
1158 g.summary[ field_name ] = {};
1159 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1161 /******************************************************************************************************/
1162 /* Loop through the copies */
1164 for (var j = 0; j < copies.length; j++) {
1167 var cmd = render || ('fm.' + field_name + '();');
1168 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1170 /**********************************************************************************************/
1171 /* Try to retrieve the value for this field for this copy */
1174 value = eval( cmd );
1176 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1178 if (typeof value == 'object' && value != null) {
1179 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1181 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1182 delete g.populated[field_name];
1185 /**********************************************************************************************/
1186 /* Tally the count */
1188 if (g.summary[ field_name ][ value ]) {
1189 g.summary[ field_name ][ value ]++;
1191 g.summary[ field_name ][ value ] = 1;
1195 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1198 /******************************************************************************************************/
1199 /* Display the summarized data and inputs for editing */
1201 g.render = function() {
1203 /******************************************************************************************************/
1204 /* Library setup and clear any existing interface */
1206 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1208 for (var i in g.panes_and_field_names) {
1209 var p = document.getElementById(i);
1210 if (p) util.widgets.remove_children(p);
1213 /******************************************************************************************************/
1214 /* Populate the library filter menu for stat cats */
1217 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1218 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1221 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1223 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1224 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1225 for (var i = 0; i < sc_libs2.length; i++) {
1226 var menuitem = document.createElement('menuitem');
1227 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1228 menuitem.setAttribute('type','checkbox');
1229 menuitem.setAttribute('checked','true');
1230 menuitem.setAttribute('label',sc_libs2[i][0]);
1231 menuitem.setAttribute('value',sc_libs2[i][1]);
1232 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1233 x.appendChild(menuitem);
1236 /******************************************************************************************************/
1237 /* Prepare the panes */
1239 var groupbox; var caption; var vbox; var grid; var rows;
1241 /******************************************************************************************************/
1242 /* Loop through the field names */
1244 for (h in g.panes_and_field_names) {
1245 if (!document.getElementById(h)) continue;
1246 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1248 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1249 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1250 groupbox.setAttribute('hideable',fn);
1252 for (var a in attr) {
1253 groupbox.setAttribute(a,attr[a]);
1256 caption = document.createElement('caption'); groupbox.appendChild(caption);
1257 caption.setAttribute('label',fn);
1258 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1259 caption.setAttribute('hideable',fn);
1260 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1261 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1262 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1263 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1264 grid.setAttribute('flex','1');
1265 rows = grid.lastChild;
1268 /**************************************************************************************/
1269 /* Loop through each value for the field */
1271 for (var j in g.summary[fn]) {
1272 var value = j; var count = g.summary[fn][j];
1273 row = document.createElement('row'); rows.appendChild(row);
1274 var label1 = document.createElement('description'); row.appendChild(label1);
1275 if (g.special_exception[ fn ]) {
1276 g.special_exception[ fn ]( label1, value );
1278 label1.appendChild( document.createTextNode(value) );
1280 var label2 = document.createElement('description'); row.appendChild(label2);
1283 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1285 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1287 label2.appendChild( document.createTextNode(copy_count) );
1289 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1290 var hbox = document.createElement('hbox'); // main input controls go here
1291 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1292 groupbox.appendChild(hbox);
1293 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1294 groupbox.appendChild(hbox2);
1296 /**************************************************************************************/
1297 /* Render the input widget */
1299 if (f[1].input && g.edit) {
1300 g.render_input(hbox,f[1]);
1304 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1310 /******************************************************************************************************/
1311 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1312 JSAN.use('util.file');
1313 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1314 g.copy_editor_prefs = util.widgets.load_attributes(file);
1315 for (var i in g.copy_editor_prefs) {
1316 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1318 g.toggle_stat_cat_display( document.getElementById(i) );
1319 } catch(E) { alert(E); }
1322 if (g.template_menu) {
1323 g.template_menu.value = g.template_menu.getAttribute('value');
1324 if (xulG.unified_interface) {
1325 if (typeof xulG.update_unified_template_selection == 'function') {
1326 xulG.update_unified_template_selection(g.template_menu.value);
1331 util.hide.generate_css('ui.hide_copy_editor_fields');
1334 /******************************************************************************************************/
1335 /* This actually draws the change button and input widget for a given field */
1336 g.render_input = function(node,blob) {
1338 // node = hbox ; groupbox -> hbox, hbox
1340 var groupbox = node.parentNode;
1341 var caption = groupbox.firstChild;
1342 var vbox = node.previousSibling;
1344 var hbox2 = node.nextSibling;
1346 var input_cmd = blob.input;
1347 var render_cmd = blob.render;
1348 var attr = blob.attr;
1350 var block = false; var first = true;
1352 function on_mouseover(ev) {
1353 groupbox.setAttribute('style','background: white');
1356 function on_mouseout(ev) {
1357 groupbox.setAttribute('style','');
1360 groupbox.addEventListener('mouseover',on_mouseover,false);
1361 groupbox.addEventListener('mouseout',on_mouseout,false);
1363 function on_click(ev){
1365 if (block || g.disabled || !g.edit || ev.currentTarget.classList.contains('disabled')) {
1372 function post_c(v) {
1374 /* FIXME - kludgy */
1375 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1379 f = input_cmd.match(/apply\("(.+?)",/)[1];
1382 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1388 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1392 g.summarize( g.copies );
1394 g.check_for_unmet_required_fields();
1395 document.getElementById(caption.id).focus();
1399 g.error.standard_unexpected_error_alert('post_c',E);
1402 var x; var c; eval( input_cmd );
1404 util.widgets.remove_children(vbox);
1405 util.widgets.remove_children(hbox);
1406 util.widgets.remove_children(hbox2);
1407 hbox.appendChild(x);
1408 var apply = document.createElement('button');
1409 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1410 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1411 hbox2.appendChild(apply);
1412 apply.addEventListener('command',function() { c(x.value); },false);
1413 var cancel = document.createElement('button');
1414 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1415 cancel.addEventListener('command',function() {
1416 setTimeout( function() {
1417 g.summarize( g.copies );
1419 g.check_for_unmet_required_fields();
1420 document.getElementById(caption.id).focus();
1425 hbox2.appendChild(cancel);
1426 setTimeout( function() { x.focus(); }, 0 );
1429 g.error.standard_unexpected_error_alert('render_input',E);
1432 groupbox.addEventListener('click',on_click, false);
1433 groupbox.addEventListener('keypress',function(ev) {
1434 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1436 caption.setAttribute('style','-moz-user-focus: normal');
1437 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1438 caption.setAttribute('onblur','this.setAttribute("class","")');
1441 g.error.sdump('D_ERROR',E + '\n');
1445 /******************************************************************************************************/
1446 /* store the copies in the global xpcom stash */
1448 g.stash_and_close = function() {
1449 var r = {textcode: ''};
1453 if (g.handle_update) {
1455 r = g.network.request(
1456 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1457 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1458 [ ses(), g.copies, true ]
1460 if (r.textcode === 'ITEM_BARCODE_EXISTS') {
1461 alert('error with item update: ' + r.desc);
1462 var barcode = $($_('staff.cat.copy_editor.field.barcode.label'));
1463 barcode.parentNode.classList.remove('disabled');
1466 else if (typeof r.ilsevent !== 'undefined') {
1467 g.error.standard_unexpected_error_alert('copy update',r);
1469 /* FIXME -- revisit the return value here */
1471 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1474 //g.data.temp_copies = js2JSON( g.copies );
1475 //g.data.stash('temp_copies');
1476 xulG.copies = g.copies;
1477 if (r.textcode !== 'ITEM_BARCODE_EXISTS') {
1478 JSAN.use('util.widgets');
1479 util.widgets.dispatch('close',window);
1482 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1486 /******************************************************************************************************/
1487 /* spawn copy notes interface */
1489 g.copy_notes = function() {
1490 JSAN.use('util.window'); var win = new util.window();
1492 urls.XUL_COPY_NOTES,
1493 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1494 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1495 { 'copy_id' : g.copies[0].id() }
1499 /******************************************************************************************************/
1500 /* hides or unhides stat cats based on library stat cat filter menu */
1501 g.toggle_stat_cat_display = function(el) {
1503 var visible = el.getAttribute('checked');
1504 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1505 for (var n = 0; n < nl.length; n++) {
1507 nl[n].setAttribute('hidden','false');
1509 nl[n].setAttribute('hidden','true');
1512 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1513 g.save_attributes();
1516 /******************************************************************************************************/
1517 /* This adds a stat cat definition to the stat cat pane for rendering */
1518 g.save_attributes = function() {
1519 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1520 var what_to_save = {};
1521 for (var i in g.copy_editor_prefs) {
1522 what_to_save[i] = [];
1523 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1525 util.widgets.save_attributes(file, what_to_save );
1528 /******************************************************************************************************/
1529 /* This adds a stat cat definition to the stat cat pane for rendering */
1530 g.add_stat_cat = function(sc) {
1532 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1536 if (typeof sc == 'object') {
1541 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1543 g.stat_cat_seen[ sc_id ] = 1;
1545 if (typeof sc != 'object') {
1547 sc = g.network.simple_request(
1548 'FM_ASC_BATCH_RETRIEVE',
1549 [ ses(), [ sc_id ] ]
1554 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1556 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1558 if (get_bool( sc.required() )) {
1559 g.required[ label_name ] = 1;
1565 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1566 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1567 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()
1568 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1569 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1576 g.panes_and_field_names.right_pane4.push( temp_array );
1578 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1582 /******************************************************************************************************/
1583 /* Add stat cats to the panes_and_field_names.right_pane4 */
1584 g.populate_stat_cats = function() {
1586 g.data.stash_retrieve();
1587 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1589 function get(lib_id,only_these) {
1590 g.data.stash_retrieve();
1591 var label = 'asc_list_for_lib_'+lib_id;
1592 if (typeof g.data[label] == 'undefined') {
1593 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1594 if (typeof robj.ilsevent != 'undefined') throw(robj);
1596 for (var j = 0; j < robj.length; j++) {
1597 var my_asc = robj[j];
1598 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1599 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1600 g.data.hash.asc[ my_asc.id() ] = my_asc;
1602 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1603 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1604 temp_list.push( my_asc );
1607 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1609 return g.data[label];
1612 /* The stat cats for the pertinent library -- this is based on workstation ou */
1613 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1614 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1615 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1616 g.add_stat_cat( g.data.list.my_asc[i] );
1619 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1620 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1622 function add_common_ancestors(sc_libs) {
1623 JSAN.use('util.fm_utils');
1624 var libs = []; for (var i in sc_libs) libs.push(i);
1625 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1626 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1628 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1629 var asc_list = get(ancestor, ancestors);
1630 for (var i = 0; i < asc_list.length; i++) {
1631 g.add_stat_cat( asc_list[i] );
1636 /* stat cats based on stat cat entries present on these copies */
1638 for (var i = 0; i < g.copies.length; i++) {
1639 var entries = g.copies[i].stat_cat_entries();
1640 if (!entries) entries = [];
1641 for (var j = 0; j < entries.length; j++) {
1642 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1643 sc_libs[ lib ] = true;
1646 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1648 /* stat cats based on Circ Lib */
1650 for (var i = 0; i < g.copies.length; i++) {
1651 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1652 sc_libs[ circ_lib ] = true;
1654 add_common_ancestors(sc_libs);
1656 /* stat cats based on Owning Lib */
1658 for (var i = 0; i < g.copies.length; i++) {
1659 var cn_id = g.copies[i].call_number();
1661 if (! g.map_acn[ cn_id ]) {
1662 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1663 if (typeof req.ilsevent == 'undefined') {
1664 g.map_acn[ cn_id ] = req;
1669 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1670 sc_libs[ owning_lib ] = true;
1673 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1675 g.panes_and_field_names.right_pane4.sort();
1679 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1683 g.check_for_unmet_required_fields = function() {
1685 for (var fn in g.required) {
1686 if (typeof g.populated[fn] == 'undefined') {
1690 if (xulG.unified_interface) {
1691 if (abort.length > 0) {
1692 if (typeof xulG.lock_save_button == 'function') {
1693 xulG.lock_save_button();
1696 if (typeof xulG.unlock_save_button == 'function') {
1697 xulG.unlock_save_button();
1701 if (abort.length > 0) {
1702 $('save').setAttribute('disabled','true');
1704 $('save').setAttribute('disabled','false');