5 function $(id) { return document.getElementById(id); }
9 /******************************************************************************************************/
10 /* setup JSAN and some initial libraries */
12 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
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',{'modal_xulG':true});
30 g.handle_update = xul_param('handle_update',{'modal_xulG':true});
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,'modal_xulG':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,'modal_xulG':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,'modal_xulG':true});
56 /******************************************************************************************************/
57 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
58 /* Quick fix, messagecatalog only usable during/after onload */
63 /******************************************************************************************************/
64 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
66 if (xul_param('edit',{'modal_xulG':true}) == '1') {
70 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
72 // Editor desired, but let's check permissions
76 var check = g.network.simple_request(
77 'PERM_MULTI_ORG_CHECK',
80 g.data.list.au[0].id(),
81 util.functional.map_list(
85 var cn_id = o.call_number();
87 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
89 if (! g.map_acn[ cn_id ]) {
90 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
91 if (typeof req.ilsevent == 'undefined') {
92 g.map_acn[ cn_id ] = req;
93 lib = g.map_acn[ cn_id ].owning_lib();
98 lib = g.map_acn[ cn_id ].owning_lib();
101 return typeof lib == 'object' ? lib.id() : lib;
104 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
107 g.edit = check.length == 0;
109 g.error.standard_unexpected_error_alert('batch permission check',E);
115 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
116 $('save').setAttribute('hidden','false');
117 g.retrieve_templates();
119 $('top_nav').setAttribute('hidden','true');
123 $('top_nav').setAttribute('hidden','true');
126 if (g.copies.length > 0 && g.copies[0].id() < 0) {
127 document.getElementById('copy_notes').setAttribute('hidden','true');
128 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
129 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
131 g.panes_and_field_names.left_pane =
134 $('catStrings').getString('staff.cat.copy_editor.status'),
136 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
137 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,
138 //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);',
141 ].concat(g.panes_and_field_names.left_pane);
143 if (g.copies.length != 1) {
144 document.getElementById('copy_notes').setAttribute('hidden','true');
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.refresh_copy_editor = function() {
177 g.copies = xulG.copies;
178 g.original_copies = js2JSON( g.copies );
179 for (var i = 0; i < g.applied_templates.length; i++) {
180 g._apply_template( g.applied_templates[i] );
182 g.summarize( g.copies );
184 g.check_for_unmet_required_fields();
186 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
189 xulG.unlock_copy_editor = function() {
192 xulG.notify_of_templatable_field_change = function(id,v) {
193 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
198 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
199 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
204 /******************************************************************************************************/
205 /* Retrieve Templates */
207 g.retrieve_templates = function() {
209 JSAN.use('util.widgets'); JSAN.use('util.functional');
211 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
212 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
213 g.templates = robj['staff_client.copy_editor.templates'];
215 util.widgets.remove_children('template_placeholder');
216 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
218 g.template_menu = util.widgets.make_menulist( list );
219 g.template_menu.setAttribute('id','template_menu');
220 $('template_placeholder').appendChild(g.template_menu);
221 g.template_menu.addEventListener(
223 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
227 if (xulG.unified_interface) {
228 if (typeof xulG.update_unified_template_list == 'function') {
229 xulG.update_unified_template_list(list);
230 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
231 xulG.update_item_editor_template_selection = function(new_value) {
232 g.template_menu.value = new_value;
233 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
236 xulG.item_editor_apply_template = function() { g.apply_template(); };
237 xulG.item_editor_delete_template = function() { g.delete_template(); };
238 xulG.item_editor_save_template = function() { g.save_template(); };
239 xulG.item_editor_import_templates = function() { g.import_templates(); };
240 xulG.item_editor_export_templates = function() { g.export_templates(); };
241 xulG.item_editor_reset = function() { g.reset(); };
246 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
250 /******************************************************************************************************/
253 g.applied_templates = [];
255 g.apply_template = function() {
257 var name = g.template_menu.value;
258 if (g.templates[ name ] != 'undefined') {
259 g.applied_templates.push( name );
260 g._apply_template(name);
261 g.summarize( g.copies );
263 g.check_for_unmet_required_fields();
266 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
270 g._apply_template = function(name) {
272 if (g.templates[ name ] != 'undefined') {
273 var template = g.templates[ name ];
274 for (var i in template) {
275 g.changed[ i ] = template[ i ];
276 switch( template[i].type ) {
278 g.apply(template[i].field,template[i].value);
281 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
284 g.apply_owning_lib(template[i].value);
286 case 'volume_copy_creator' :
287 if (xulG.unified_interface) {
288 xulG.apply_template_to_batch(template[i].field,template[i].value);
295 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
299 /******************************************************************************************************/
300 /* Save as Template */
302 g.save_template = function() {
304 var name = window.prompt(
305 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
307 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
310 g.templates[name] = g.changed;
311 var robj = g.network.simple_request(
312 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
314 if (typeof robj.ilsevent != 'undefined') {
317 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
321 g.retrieve_templates();
323 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
329 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
333 /******************************************************************************************************/
334 /* Delete Template */
336 g.delete_template = function() {
338 var name = g.template_menu.value;
340 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
341 delete(g.templates[name]);
342 var robj = g.network.simple_request(
343 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
345 if (typeof robj.ilsevent != 'undefined') {
348 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
352 g.retrieve_templates();
354 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
360 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
364 /******************************************************************************************************/
365 /* Export Templates */
367 g.export_templates = function() {
369 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
370 JSAN.use('util.file'); var f = new util.file('');
371 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
373 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
377 /******************************************************************************************************/
378 /* Import Templates */
380 g.import_templates = function() {
382 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
383 JSAN.use('util.file'); var f = new util.file('');
384 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
386 for (var i in temp) {
388 if (g.templates[i]) {
390 var r = g.error.yns_alert(
391 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
392 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
393 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
394 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
396 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
399 if (r == 0 /* Yes */) g.templates[i] = temp[i];
403 g.templates[i] = temp[i];
409 var r = g.error.yns_alert(
410 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
411 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
412 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
413 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
415 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
418 if (r == 0 /* Yes */) {
419 var robj = g.network.simple_request(
420 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
422 if (typeof robj.ilsevent != 'undefined') {
425 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
429 g.retrieve_templates();
431 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
437 util.widgets.remove_children('template_placeholder');
438 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
439 g.template_menu = util.widgets.make_menulist( list );
440 $('template_placeholder').appendChild(g.template_menu);
441 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
446 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
451 /******************************************************************************************************/
452 /* Restore backup copies */
454 g.reset = function() {
455 g.applied_templates = [];
457 g.copies = JSON2js( g.original_copies );
458 g.summarize( g.copies );
460 g.check_for_unmet_required_fields();
462 if (xulG.unified_interface) {
463 xulG.reset_batch_menus();
467 /******************************************************************************************************/
468 /* Apply a value to a specific field on all the copies being edited */
470 g.apply = function(field,value) {
471 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
472 if (value == '<HACK:KLUDGE:NULL>') {
475 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
476 if (field == 'price' || field == 'deposit_amount') {
480 JSAN.use('util.money'); value = util.money.sanitize( value );
483 for (var i = 0; i < g.copies.length; i++) {
484 var copy = g.copies[i];
486 copy[field]( value ); copy.ischanged('1');
495 /******************************************************************************************************/
496 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
498 g.apply_stat_cat = function(sc_id,entry_id) {
499 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
500 for (var i = 0; i < g.copies.length; i++) {
501 var copy = g.copies[i];
504 var temp = copy.stat_cat_entries();
505 if (!temp) temp = [];
506 temp = util.functional.filter_list(
509 return (obj.stat_cat() != sc_id);
514 util.functional.find_id_object_in_list(
515 g.data.hash.asc[sc_id].entries(),
520 copy.stat_cat_entries( temp );
523 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
530 /******************************************************************************************************/
531 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
533 g.apply_owning_lib = function(ou_id) {
534 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
535 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
536 if (! g.safe_to_change_owning_lib() ) { return; }
537 for (var i = 0; i < g.copies.length; i++) {
538 var copy = g.copies[i];
540 if (!g.map_acn[copy.call_number()]) {
541 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
542 if (typeof volume.ilsevent != 'undefined') {
543 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
546 g.map_acn[copy.call_number()] = volume;
548 var old_volume = g.map_acn[copy.call_number()];
549 var acn_blob = g.network.simple_request(
550 'FM_ACN_FIND_OR_CREATE',
551 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix(),old_volume.suffix(),old_volume.label_class()]
553 if (typeof acn_blob.ilsevent != 'undefined') {
554 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
557 copy.call_number(acn_blob.acn_id);
560 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
567 /******************************************************************************************************/
568 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
570 g.safe_to_change_owning_lib = function() {
572 if (xulG.unified_interface) { return false; }
574 for (var i = 0; i < g.copies.length; i++) {
575 var cn = g.copies[i].call_number();
576 if (typeof cn == 'object') { cn = cn.id(); }
577 if (cn == -1) { safe = false; }
581 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
586 /******************************************************************************************************/
587 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
589 g.safe_to_edit_copy_status = function() {
592 for (var i = 0; i < g.copies.length; i++) {
593 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
594 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
598 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
603 /******************************************************************************************************/
604 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
606 g.populate_alert_message_input = function(tb) {
608 var seen = {}; var s = '';
609 for (var i = 0; i < g.copies.length; i++) {
610 var msg = g.copies[i].alert_message();
612 if (typeof seen[msg] == 'undefined') {
618 tb.setAttribute('value',s);
620 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
624 /***************************************************************************************************************/
625 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
627 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
628 g.data.stash_retrieve();
629 var label = 'acpl_list_for_lib_'+lib_id;
630 if (typeof g.data[label] == 'undefined') {
631 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
632 if (typeof robj.ilsevent != 'undefined') throw(robj);
634 for (var j = 0; j < robj.length; j++) {
635 var my_acpl = robj[j];
636 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
637 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
638 g.data.list.acpl.push( my_acpl );
640 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
641 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
642 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
643 temp_list.push( my_acpl );
646 g.data[label] = temp_list; g.data.stash(label,'hash','list');
648 return g.data[label];
651 /******************************************************************************************************/
652 /* This returns a list of acpl's appropriate for the copies being edited */
654 g.get_acpl_list = function() {
657 JSAN.use('util.functional');
661 /**************************************/
662 /* get owning libs from call numbers */
664 var owning_libs = {};
665 for (var i = 0; i < g.copies.length; i++) {
666 var callnumber = g.copies[i].call_number();
667 if (!callnumber) continue;
668 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
670 if (! g.map_acn[ cn_id ]) {
671 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
672 if (typeof req.ilsevent == 'undefined') {
673 g.map_acn[ cn_id ] = req;
678 var consider_lib = g.map_acn[ cn_id ].owning_lib();
679 if (!consider_lib) continue;
680 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
684 for (var i in g.callnumbers) {
685 var consider_lib = g.callnumbers[i].owning_lib;
686 if (!consider_lib) continue;
687 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
691 /***************************************************************************************************/
692 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
694 JSAN.use('util.fm_utils');
695 var libs = []; for (var i in owning_libs) libs.push(i);
696 if (libs.length > 0) {
697 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
698 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
701 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
702 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
703 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
704 if (acpl_list[i] != null) {
705 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
716 for (var i = 0; i < g.copies.length; i++) {
717 var consider_lib = g.copies[i].circ_lib();
718 if (!consider_lib) continue;
719 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
722 /***************************************************************************************************/
723 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
725 libs = []; for (var i in circ_libs) libs.push(i);
726 if (libs.length > 0) {
727 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
728 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
731 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
732 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
733 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
734 if (acpl_list[i] != null) {
735 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
741 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
742 return acpl_list.sort(
744 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
745 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
746 if (label_a < label_b) return -1;
747 if (label_a > label_b) return 1;
753 g.error.standard_unexpected_error_alert('get_acpl_list',E);
759 /******************************************************************************************************/
760 /* This keeps track of which fields have been edited for styling purposes */
764 /******************************************************************************************************/
765 /* This keeps track of which fields are required, and which fields have been populated */
770 /******************************************************************************************************/
771 /* These need data from the middle layer to render */
773 function init_panes0() {
774 g.special_exception = {};
775 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
776 JSAN.use('util.widgets');
777 if (value>0) { /* an existing call number */
778 g.network.simple_request(
779 'FM_ACN_RETRIEVE.authoritative',
782 var cn = '??? id = ' + value;
784 cn = req.getResultObject();
786 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
788 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
791 } else { /* a yet to be created call number */
793 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
797 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
798 if (!Number(value)) return;
799 g.network.simple_request(
800 'FM_AU_RETRIEVE_VIA_ID',
803 var p = '??? id = ' + value;
805 p = req.getResultObject();
809 g.error.sdump('D_ERROR','patron retrieve: ' + E);
811 JSAN.use('util.widgets');
812 util.widgets.set_text(label,p);
816 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
817 if (!Number(value)) return;
818 g.network.simple_request(
819 'FM_AU_RETRIEVE_VIA_ID',
822 var p = '??? id = ' + value;
824 p = req.getResultObject();
828 g.error.sdump('D_ERROR','patron retrieve: ' + E);
830 util.widgets.set_text(label,p);
836 /******************************************************************************************************/
837 g.readonly_stat_cat_names = [];
838 g.editable_stat_cat_names = [];
840 /******************************************************************************************************/
841 /* These get show in the left panel */
843 function init_panes() {
844 g.panes_and_field_names = {
849 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
851 render: 'fm.barcode();',
855 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
857 render: 'util.date.formatted_date( fm.create_date(), "%F");',
861 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
863 render: 'fm.creator();',
867 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
869 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
873 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
875 render: 'fm.editor();',
884 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
886 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
887 input: 'c = function(v){ g.apply("location",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.get_acpl_list(), function(obj) { return [ g.data.hash.aou[ obj.owning_lib() ].shortname() + " : " + obj.name(), obj.id() ]; }).sort()); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
892 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
894 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
895 //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);',
896 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);',
900 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
902 render: 'fm.call_number();',
903 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,
907 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
909 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
910 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);',
920 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
922 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") )',
923 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);',
927 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
929 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") )',
930 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);',
934 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
936 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() )',
937 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);',
942 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
944 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") )',
945 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);',
949 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
951 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; }',
952 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);',
957 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
959 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; }',
960 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);',
965 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
967 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',
968 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);',
972 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
974 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()])',
975 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);',
982 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
984 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
985 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);',
990 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
992 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") )',
993 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);',
997 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
999 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1000 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);',
1004 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1006 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1007 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);',
1012 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1014 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") )',
1015 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);',
1019 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1021 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") )',
1022 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);',
1026 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1028 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")',
1029 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);',
1041 /******************************************************************************************************/
1042 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1044 g.summarize = function( copies ) {
1045 /******************************************************************************************************/
1048 JSAN.use('util.date'); JSAN.use('util.money');
1051 for (var i in g.panes_and_field_names) {
1052 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1054 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1055 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1057 /******************************************************************************************************/
1058 /* Loop through the field names */
1060 for (var i = 0; i < g.field_names.length; i++) {
1062 var field_name = g.field_names[i][0];
1063 var render = g.field_names[i][1].render;
1064 var attr = g.field_names[i][1].attr;
1065 g.summary[ field_name ] = {};
1066 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1068 /******************************************************************************************************/
1069 /* Loop through the copies */
1071 for (var j = 0; j < copies.length; j++) {
1074 var cmd = render || ('fm.' + field_name + '();');
1075 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1077 /**********************************************************************************************/
1078 /* Try to retrieve the value for this field for this copy */
1081 value = eval( cmd );
1083 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1085 if (typeof value == 'object' && value != null) {
1086 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1088 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1089 delete g.populated[field_name];
1092 /**********************************************************************************************/
1093 /* Tally the count */
1095 if (g.summary[ field_name ][ value ]) {
1096 g.summary[ field_name ][ value ]++;
1098 g.summary[ field_name ][ value ] = 1;
1102 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1105 /******************************************************************************************************/
1106 /* Display the summarized data and inputs for editing */
1108 g.render = function() {
1110 /******************************************************************************************************/
1111 /* Library setup and clear any existing interface */
1113 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1115 for (var i in g.panes_and_field_names) {
1116 var p = document.getElementById(i);
1117 if (p) util.widgets.remove_children(p);
1120 /******************************************************************************************************/
1121 /* Populate the library filter menu for stat cats */
1124 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1125 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1128 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1130 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1131 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1132 for (var i = 0; i < sc_libs2.length; i++) {
1133 var menuitem = document.createElement('menuitem');
1134 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1135 menuitem.setAttribute('type','checkbox');
1136 menuitem.setAttribute('checked','true');
1137 menuitem.setAttribute('label',sc_libs2[i][0]);
1138 menuitem.setAttribute('value',sc_libs2[i][1]);
1139 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1140 x.appendChild(menuitem);
1143 /******************************************************************************************************/
1144 /* Prepare the panes */
1146 var groupbox; var caption; var vbox; var grid; var rows;
1148 /******************************************************************************************************/
1149 /* Loop through the field names */
1151 for (h in g.panes_and_field_names) {
1152 if (!document.getElementById(h)) continue;
1153 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1155 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1156 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1158 for (var a in attr) {
1159 groupbox.setAttribute(a,attr[a]);
1162 caption = document.createElement('caption'); groupbox.appendChild(caption);
1163 caption.setAttribute('label',fn);
1164 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1165 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1166 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1167 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1168 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1169 grid.setAttribute('flex','1');
1170 rows = grid.lastChild;
1173 /**************************************************************************************/
1174 /* Loop through each value for the field */
1176 for (var j in g.summary[fn]) {
1177 var value = j; var count = g.summary[fn][j];
1178 row = document.createElement('row'); rows.appendChild(row);
1179 var label1 = document.createElement('description'); row.appendChild(label1);
1180 if (g.special_exception[ fn ]) {
1181 g.special_exception[ fn ]( label1, value );
1183 label1.appendChild( document.createTextNode(value) );
1185 var label2 = document.createElement('description'); row.appendChild(label2);
1188 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1190 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1192 label2.appendChild( document.createTextNode(copy_count) );
1194 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1195 var hbox = document.createElement('hbox'); // main input controls go here
1196 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1197 groupbox.appendChild(hbox);
1198 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1199 groupbox.appendChild(hbox2);
1201 /**************************************************************************************/
1202 /* Render the input widget */
1204 if (f[1].input && g.edit) {
1205 g.render_input(hbox,f[1]);
1209 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1215 /******************************************************************************************************/
1216 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1217 JSAN.use('util.file');
1218 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1219 g.copy_editor_prefs = util.widgets.load_attributes(file);
1220 for (var i in g.copy_editor_prefs) {
1221 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1223 g.toggle_stat_cat_display( document.getElementById(i) );
1224 } catch(E) { alert(E); }
1227 if (g.template_menu) g.template_menu.value = g.template_menu.getAttribute('value');
1231 /******************************************************************************************************/
1232 /* This actually draws the change button and input widget for a given field */
1233 g.render_input = function(node,blob) {
1235 // node = hbox ; groupbox -> hbox, hbox
1237 var groupbox = node.parentNode;
1238 var caption = groupbox.firstChild;
1239 var vbox = node.previousSibling;
1241 var hbox2 = node.nextSibling;
1243 var input_cmd = blob.input;
1244 var render_cmd = blob.render;
1245 var attr = blob.attr;
1247 var block = false; var first = true;
1249 function on_mouseover(ev) {
1250 groupbox.setAttribute('style','background: white');
1253 function on_mouseout(ev) {
1254 groupbox.setAttribute('style','');
1257 vbox.addEventListener('mouseover',on_mouseover,false);
1258 vbox.addEventListener('mouseout',on_mouseout,false);
1259 groupbox.addEventListener('mouseover',on_mouseover,false);
1260 groupbox.addEventListener('mouseout',on_mouseout,false);
1261 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1262 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1264 function on_click(ev){
1266 if (block) return; block = true;
1270 function post_c(v) {
1272 /* FIXME - kludgy */
1273 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1277 f = input_cmd.match(/apply\("(.+?)",/)[1];
1280 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1286 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1290 g.summarize( g.copies );
1292 g.check_for_unmet_required_fields();
1293 document.getElementById(caption.id).focus();
1297 g.error.standard_unexpected_error_alert('post_c',E);
1300 var x; var c; eval( input_cmd );
1302 util.widgets.remove_children(vbox);
1303 util.widgets.remove_children(hbox);
1304 util.widgets.remove_children(hbox2);
1305 hbox.appendChild(x);
1306 var apply = document.createElement('button');
1307 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1308 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1309 hbox2.appendChild(apply);
1310 apply.addEventListener('command',function() { c(x.value); },false);
1311 var cancel = document.createElement('button');
1312 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1313 cancel.addEventListener('command',function() {
1314 setTimeout( function() {
1315 g.summarize( g.copies );
1317 g.check_for_unmet_required_fields();
1318 document.getElementById(caption.id).focus();
1323 hbox2.appendChild(cancel);
1324 setTimeout( function() { x.focus(); }, 0 );
1327 g.error.standard_unexpected_error_alert('render_input',E);
1330 vbox.addEventListener('click',on_click, false);
1331 hbox.addEventListener('click',on_click, false);
1332 caption.addEventListener('click',on_click, false);
1333 caption.addEventListener('keypress',function(ev) {
1334 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1336 caption.setAttribute('style','-moz-user-focus: normal');
1337 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1338 caption.setAttribute('onblur','this.setAttribute("class","")');
1341 g.error.sdump('D_ERROR',E + '\n');
1345 /******************************************************************************************************/
1346 /* store the copies in the global xpcom stash */
1348 g.stash_and_close = function() {
1352 if (g.handle_update) {
1354 var r = g.network.request(
1355 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1356 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1357 [ ses(), g.copies, true ]
1359 if (typeof r.ilsevent != 'undefined') {
1360 g.error.standard_unexpected_error_alert('copy update',r);
1362 /* FIXME -- revisit the return value here */
1364 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1367 //g.data.temp_copies = js2JSON( g.copies );
1368 //g.data.stash('temp_copies');
1369 xulG.copies = g.copies;
1370 update_modal_xulG(xulG);
1371 JSAN.use('util.widgets');
1372 util.widgets.dispatch('close',window);
1374 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1378 /******************************************************************************************************/
1379 /* spawn copy notes interface */
1381 g.copy_notes = function() {
1382 JSAN.use('util.window'); var win = new util.window();
1384 urls.XUL_COPY_NOTES,
1385 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1386 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1387 { 'copy_id' : g.copies[0].id() }
1391 /******************************************************************************************************/
1392 /* hides or unhides stat cats based on library stat cat filter menu */
1393 g.toggle_stat_cat_display = function(el) {
1395 var visible = el.getAttribute('checked');
1396 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1397 for (var n = 0; n < nl.length; n++) {
1399 nl[n].setAttribute('hidden','false');
1401 nl[n].setAttribute('hidden','true');
1404 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1405 g.save_attributes();
1408 /******************************************************************************************************/
1409 /* This adds a stat cat definition to the stat cat pane for rendering */
1410 g.save_attributes = function() {
1411 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1412 var what_to_save = {};
1413 for (var i in g.copy_editor_prefs) {
1414 what_to_save[i] = [];
1415 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1417 util.widgets.save_attributes(file, what_to_save );
1420 /******************************************************************************************************/
1421 /* This adds a stat cat definition to the stat cat pane for rendering */
1422 g.add_stat_cat = function(sc) {
1424 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1428 if (typeof sc == 'object') {
1433 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1435 g.stat_cat_seen[ sc_id ] = 1;
1437 if (typeof sc != 'object') {
1439 sc = g.network.simple_request(
1440 'FM_ASC_BATCH_RETRIEVE',
1441 [ ses(), [ sc_id ] ]
1446 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1448 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1450 if (get_bool( sc.required() )) {
1451 g.required[ label_name ] = 1;
1457 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1458 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1459 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()
1460 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1461 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1468 g.panes_and_field_names.right_pane4.push( temp_array );
1470 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1474 /******************************************************************************************************/
1475 /* Add stat cats to the panes_and_field_names.right_pane4 */
1476 g.populate_stat_cats = function() {
1478 g.data.stash_retrieve();
1479 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1481 function get(lib_id,only_these) {
1482 g.data.stash_retrieve();
1483 var label = 'asc_list_for_lib_'+lib_id;
1484 if (typeof g.data[label] == 'undefined') {
1485 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1486 if (typeof robj.ilsevent != 'undefined') throw(robj);
1488 for (var j = 0; j < robj.length; j++) {
1489 var my_asc = robj[j];
1490 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1491 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1492 g.data.hash.asc[ my_asc.id() ] = my_asc;
1494 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1495 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1496 temp_list.push( my_asc );
1499 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1501 return g.data[label];
1504 /* The stat cats for the pertinent library -- this is based on workstation ou */
1505 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1506 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1507 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1508 g.add_stat_cat( g.data.list.my_asc[i] );
1511 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1512 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1514 function add_common_ancestors(sc_libs) {
1515 JSAN.use('util.fm_utils');
1516 var libs = []; for (var i in sc_libs) libs.push(i);
1517 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1518 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1520 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1521 var asc_list = get(ancestor, ancestors);
1522 for (var i = 0; i < asc_list.length; i++) {
1523 g.add_stat_cat( asc_list[i] );
1528 /* stat cats based on stat cat entries present on these copies */
1530 for (var i = 0; i < g.copies.length; i++) {
1531 var entries = g.copies[i].stat_cat_entries();
1532 if (!entries) entries = [];
1533 for (var j = 0; j < entries.length; j++) {
1534 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1535 sc_libs[ lib ] = true;
1538 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1540 /* stat cats based on Circ Lib */
1542 for (var i = 0; i < g.copies.length; i++) {
1543 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1544 sc_libs[ circ_lib ] = true;
1546 add_common_ancestors(sc_libs);
1548 /* stat cats based on Owning Lib */
1550 for (var i = 0; i < g.copies.length; i++) {
1551 var cn_id = g.copies[i].call_number();
1553 if (! g.map_acn[ cn_id ]) {
1554 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1555 if (typeof req.ilsevent == 'undefined') {
1556 g.map_acn[ cn_id ] = req;
1561 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1562 sc_libs[ owning_lib ] = true;
1565 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1567 g.panes_and_field_names.right_pane4.sort();
1571 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1575 g.check_for_unmet_required_fields = function() {
1577 for (var fn in g.required) {
1578 if (typeof g.populated[fn] == 'undefined') {
1582 if (abort.length > 0) {
1583 $('save').setAttribute('disabled','true');
1585 $('save').setAttribute('disabled','false');