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 g.panes_and_field_names.left_pane =
129 $('catStrings').getString('staff.cat.copy_editor.status'),
131 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
132 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,
133 //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);',
136 ].concat(g.panes_and_field_names.left_pane);
139 /******************************************************************************************************/
140 /* Show the Record Details? */
142 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
144 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
145 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
146 brief_display.setAttribute( 'flex','1' );
149 /******************************************************************************************************/
150 /* Add stat cats to the panes_and_field_names.right_pane4 */
152 g.populate_stat_cats();
154 /******************************************************************************************************/
155 /* Backup copies :) */
157 g.original_copies = js2JSON( g.copies );
159 /******************************************************************************************************/
162 g.summarize( g.copies );
164 g.check_for_unmet_required_fields();
166 if (xulG.unified_interface) {
167 xulG.refresh_copy_editor = function() {
169 g.copies = xulG.copies;
170 g.original_copies = js2JSON( g.copies );
171 g.hide_copy_notes_button();
172 for (var i = 0; i < g.applied_templates.length; i++) {
173 g._apply_template( g.applied_templates[i], false);
175 g.summarize( g.copies );
177 g.check_for_unmet_required_fields();
179 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
182 xulG.unlock_copy_editor = function() {
185 xulG.notify_of_templatable_field_change = function(id,v) {
186 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
189 g.hide_copy_notes_button();
193 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
194 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
199 /******************************************************************************************************/
200 /* Show copy notes button */
201 g.hide_copy_notes_button = function() {
202 if (g.copies.length > 0 && g.copies[0].id() < 0) {
203 document.getElementById('copy_notes').setAttribute('hidden','true');
204 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
205 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
207 if (g.copies.length != 1) {
208 document.getElementById('copy_notes').setAttribute('hidden','true');
212 /******************************************************************************************************/
213 /* Retrieve Templates */
215 g.retrieve_templates = function() {
217 JSAN.use('util.widgets'); JSAN.use('util.functional');
219 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
220 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
221 g.templates = robj['staff_client.copy_editor.templates'];
223 util.widgets.remove_children('template_placeholder');
224 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
226 g.template_menu = util.widgets.make_menulist( list );
227 g.template_menu.setAttribute('id','template_menu');
228 $('template_placeholder').appendChild(g.template_menu);
229 g.template_menu.addEventListener(
231 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
235 if (xulG.unified_interface) {
236 if (typeof xulG.update_unified_template_list == 'function') {
237 xulG.update_unified_template_list(list);
238 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
239 xulG.update_item_editor_template_selection = function(new_value) {
240 g.template_menu.value = new_value;
241 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
244 xulG.item_editor_apply_template = function() { g.apply_template(true); };
245 xulG.item_editor_delete_template = function() { g.delete_template(); };
246 xulG.item_editor_save_template = function() { g.save_template(); };
247 xulG.item_editor_import_templates = function() { g.import_templates(); };
248 xulG.item_editor_export_templates = function() { g.export_templates(); };
249 xulG.item_editor_reset = function() { g.reset(); };
254 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
258 /******************************************************************************************************/
261 g.applied_templates = [];
263 g.apply_template = function(apply_volume_editor_template_changes) {
265 var name = g.template_menu.value;
266 if (g.templates[ name ] != 'undefined') {
267 g.applied_templates.push( name );
268 g._apply_template(name,apply_volume_editor_template_changes);
269 g.summarize( g.copies );
271 g.check_for_unmet_required_fields();
274 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
278 g._apply_template = function(name,apply_volume_editor_template_changes) {
280 if (g.templates[ name ] != 'undefined') {
281 var template = g.templates[ name ];
282 for (var i in template) {
283 g.changed[ i ] = template[ i ];
284 switch( template[i].type ) {
286 g.apply(template[i].field,template[i].value);
289 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
292 g.apply_owning_lib(template[i].value);
294 case 'volume_copy_creator' :
295 if (xulG.unified_interface && apply_volume_editor_template_changes) {
296 xulG.apply_template_to_batch(template[i].field,template[i].value);
303 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
307 /******************************************************************************************************/
308 /* Save as Template */
310 g.save_template = function() {
312 var name = window.prompt(
313 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
315 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
318 g.templates[name] = g.changed;
319 var robj = g.network.simple_request(
320 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
322 if (typeof robj.ilsevent != 'undefined') {
325 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
329 g.retrieve_templates();
331 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
337 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
341 /******************************************************************************************************/
342 /* Delete Template */
344 g.delete_template = function() {
346 var name = g.template_menu.value;
348 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
349 delete(g.templates[name]);
350 var robj = g.network.simple_request(
351 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
353 if (typeof robj.ilsevent != 'undefined') {
356 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
360 g.retrieve_templates();
362 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
368 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
372 /******************************************************************************************************/
373 /* Export Templates */
375 g.export_templates = function() {
377 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
378 JSAN.use('util.file'); var f = new util.file('');
379 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
381 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
385 /******************************************************************************************************/
386 /* Import Templates */
388 g.import_templates = function() {
390 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
391 JSAN.use('util.file'); var f = new util.file('');
392 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
394 for (var i in temp) {
396 if (g.templates[i]) {
398 var r = g.error.yns_alert(
399 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
400 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
401 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
402 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
404 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
407 if (r == 0 /* Yes */) g.templates[i] = temp[i];
411 g.templates[i] = temp[i];
417 var r = g.error.yns_alert(
418 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
419 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
420 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
421 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
423 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
426 if (r == 0 /* Yes */) {
427 var robj = g.network.simple_request(
428 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
430 if (typeof robj.ilsevent != 'undefined') {
433 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
437 g.retrieve_templates();
439 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
445 util.widgets.remove_children('template_placeholder');
446 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
447 g.template_menu = util.widgets.make_menulist( list );
448 $('template_placeholder').appendChild(g.template_menu);
449 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
454 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
459 /******************************************************************************************************/
460 /* Restore backup copies */
462 g.reset = function() {
463 g.applied_templates = [];
465 g.copies = JSON2js( g.original_copies );
466 g.summarize( g.copies );
468 g.check_for_unmet_required_fields();
470 if (xulG.unified_interface) {
471 xulG.reset_batch_menus();
475 /******************************************************************************************************/
476 /* Apply a value to a specific field on all the copies being edited */
478 g.apply = function(field,value) {
479 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
480 if (value == '<HACK:KLUDGE:NULL>') {
483 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
484 if (field == 'price' || field == 'deposit_amount') {
488 JSAN.use('util.money'); value = util.money.sanitize( value );
491 for (var i = 0; i < g.copies.length; i++) {
492 var copy = g.copies[i];
494 copy[field]( value ); copy.ischanged('1');
503 /******************************************************************************************************/
504 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
506 g.apply_stat_cat = function(sc_id,entry_id) {
507 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
508 for (var i = 0; i < g.copies.length; i++) {
509 var copy = g.copies[i];
512 var temp = copy.stat_cat_entries();
513 if (!temp) temp = [];
514 temp = util.functional.filter_list(
517 return (obj.stat_cat() != sc_id);
522 util.functional.find_id_object_in_list(
523 g.data.hash.asc[sc_id].entries(),
528 copy.stat_cat_entries( temp );
531 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
538 /******************************************************************************************************/
539 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
541 g.apply_owning_lib = function(ou_id) {
542 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
543 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
544 if (! g.safe_to_change_owning_lib() ) { return; }
545 for (var i = 0; i < g.copies.length; i++) {
546 var copy = g.copies[i];
548 if (!g.map_acn[copy.call_number()]) {
549 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
550 if (typeof volume.ilsevent != 'undefined') {
551 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
554 g.map_acn[copy.call_number()] = volume;
556 var old_volume = g.map_acn[copy.call_number()];
557 var acn_blob = g.network.simple_request(
558 'FM_ACN_FIND_OR_CREATE',
559 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
561 if (typeof acn_blob.ilsevent != 'undefined') {
562 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
565 copy.call_number(acn_blob.acn_id);
568 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
575 /******************************************************************************************************/
576 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
578 g.safe_to_change_owning_lib = function() {
580 if (xulG.unified_interface) { return false; }
582 for (var i = 0; i < g.copies.length; i++) {
583 var cn = g.copies[i].call_number();
584 if (typeof cn == 'object') { cn = cn.id(); }
585 if (cn == -1) { safe = false; }
589 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
594 /******************************************************************************************************/
595 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
597 g.safe_to_edit_copy_status = function() {
600 for (var i = 0; i < g.copies.length; i++) {
601 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
602 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
606 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
611 /******************************************************************************************************/
612 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
614 g.populate_alert_message_input = function(tb) {
616 var seen = {}; var s = '';
617 for (var i = 0; i < g.copies.length; i++) {
618 var msg = g.copies[i].alert_message();
620 if (typeof seen[msg] == 'undefined') {
626 tb.setAttribute('value',s);
628 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
632 /***************************************************************************************************************/
633 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
635 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
636 g.data.stash_retrieve();
637 var label = 'acpl_list_for_lib_'+lib_id;
638 if (typeof g.data[label] == 'undefined') {
639 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
640 if (typeof robj.ilsevent != 'undefined') throw(robj);
642 for (var j = 0; j < robj.length; j++) {
643 var my_acpl = robj[j];
644 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
645 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
646 g.data.list.acpl.push( my_acpl );
648 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
649 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
650 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
651 temp_list.push( my_acpl );
654 g.data[label] = temp_list; g.data.stash(label,'hash','list');
656 return g.data[label];
659 /******************************************************************************************************/
660 /* This returns a list of acpl's appropriate for the copies being edited */
662 g.get_acpl_list = function() {
665 JSAN.use('util.functional');
669 /**************************************/
670 /* get owning libs from call numbers */
672 var owning_libs = {};
673 for (var i = 0; i < g.copies.length; i++) {
674 var callnumber = g.copies[i].call_number();
675 if (!callnumber) continue;
676 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
678 if (! g.map_acn[ cn_id ]) {
679 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
680 if (typeof req.ilsevent == 'undefined') {
681 g.map_acn[ cn_id ] = req;
686 var consider_lib = g.map_acn[ cn_id ].owning_lib();
687 if (!consider_lib) continue;
688 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
692 for (var i in g.callnumbers) {
693 var consider_lib = g.callnumbers[i].owning_lib;
694 if (!consider_lib) continue;
695 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
699 /***************************************************************************************************/
700 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
702 JSAN.use('util.fm_utils');
703 var libs = []; for (var i in owning_libs) libs.push(i);
704 if (libs.length > 0) {
705 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
706 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
709 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
710 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
711 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
712 if (acpl_list[i] != null) {
713 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
724 for (var i = 0; i < g.copies.length; i++) {
725 var consider_lib = g.copies[i].circ_lib();
726 if (!consider_lib) continue;
727 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
730 /***************************************************************************************************/
731 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
733 libs = []; for (var i in circ_libs) libs.push(i);
734 if (libs.length > 0) {
735 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
736 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
739 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
740 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
741 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
742 if (acpl_list[i] != null) {
743 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
749 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
750 return acpl_list.sort(
752 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
753 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
754 if (label_a < label_b) return -1;
755 if (label_a > label_b) return 1;
761 g.error.standard_unexpected_error_alert('get_acpl_list',E);
767 /******************************************************************************************************/
768 /* This keeps track of which fields have been edited for styling purposes */
772 /******************************************************************************************************/
773 /* This keeps track of which fields are required, and which fields have been populated */
778 /******************************************************************************************************/
779 /* These need data from the middle layer to render */
781 function init_panes0() {
782 g.special_exception = {};
783 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
784 JSAN.use('util.widgets');
785 if (value>0) { /* an existing call number */
786 g.network.simple_request(
787 'FM_ACN_RETRIEVE.authoritative',
790 var cn = '??? id = ' + value;
792 cn = req.getResultObject();
794 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
796 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
799 } else { /* a yet to be created call number */
801 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
805 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
806 if (!Number(value)) return;
807 g.network.simple_request(
808 'FM_AU_RETRIEVE_VIA_ID',
811 var p = '??? id = ' + value;
813 p = req.getResultObject();
817 g.error.sdump('D_ERROR','patron retrieve: ' + E);
819 JSAN.use('util.widgets');
820 util.widgets.set_text(label,p);
824 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
825 if (!Number(value)) return;
826 g.network.simple_request(
827 'FM_AU_RETRIEVE_VIA_ID',
830 var p = '??? id = ' + value;
832 p = req.getResultObject();
836 g.error.sdump('D_ERROR','patron retrieve: ' + E);
838 util.widgets.set_text(label,p);
844 /******************************************************************************************************/
845 g.readonly_stat_cat_names = [];
846 g.editable_stat_cat_names = [];
848 /******************************************************************************************************/
849 /* These get show in the left panel */
851 function init_panes() {
852 g.panes_and_field_names = {
857 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
859 render: 'fm.barcode();',
863 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
865 render: 'util.date.formatted_date( fm.create_date(), "%F");',
869 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
871 render: 'fm.creator();',
875 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
877 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
881 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
883 render: 'fm.editor();',
892 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
894 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
895 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);',
900 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
902 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
903 //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);',
904 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);',
908 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
910 render: 'fm.call_number();',
911 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,
915 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
917 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
918 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);',
928 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
930 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") )',
931 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);',
935 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
937 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") )',
938 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);',
942 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
944 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() )',
945 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);',
950 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
952 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") )',
953 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);',
957 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
959 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; }',
960 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);',
965 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
967 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; }',
968 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);',
973 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
975 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',
976 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);',
980 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
982 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()])',
983 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);',
990 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
992 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
993 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);',
998 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1000 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") )',
1001 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);',
1005 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1007 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1008 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);',
1012 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1014 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1015 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);',
1020 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1022 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") )',
1023 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);',
1027 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1029 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") )',
1030 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);',
1034 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1036 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")',
1037 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);',
1049 /******************************************************************************************************/
1050 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1052 g.summarize = function( copies ) {
1053 /******************************************************************************************************/
1056 JSAN.use('util.date'); JSAN.use('util.money');
1059 for (var i in g.panes_and_field_names) {
1060 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1062 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1063 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1065 /******************************************************************************************************/
1066 /* Loop through the field names */
1068 for (var i = 0; i < g.field_names.length; i++) {
1070 var field_name = g.field_names[i][0];
1071 var render = g.field_names[i][1].render;
1072 var attr = g.field_names[i][1].attr;
1073 g.summary[ field_name ] = {};
1074 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1076 /******************************************************************************************************/
1077 /* Loop through the copies */
1079 for (var j = 0; j < copies.length; j++) {
1082 var cmd = render || ('fm.' + field_name + '();');
1083 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1085 /**********************************************************************************************/
1086 /* Try to retrieve the value for this field for this copy */
1089 value = eval( cmd );
1091 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1093 if (typeof value == 'object' && value != null) {
1094 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1096 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1097 delete g.populated[field_name];
1100 /**********************************************************************************************/
1101 /* Tally the count */
1103 if (g.summary[ field_name ][ value ]) {
1104 g.summary[ field_name ][ value ]++;
1106 g.summary[ field_name ][ value ] = 1;
1110 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1113 /******************************************************************************************************/
1114 /* Display the summarized data and inputs for editing */
1116 g.render = function() {
1118 /******************************************************************************************************/
1119 /* Library setup and clear any existing interface */
1121 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1123 for (var i in g.panes_and_field_names) {
1124 var p = document.getElementById(i);
1125 if (p) util.widgets.remove_children(p);
1128 /******************************************************************************************************/
1129 /* Populate the library filter menu for stat cats */
1132 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1133 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1136 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1138 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1139 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1140 for (var i = 0; i < sc_libs2.length; i++) {
1141 var menuitem = document.createElement('menuitem');
1142 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1143 menuitem.setAttribute('type','checkbox');
1144 menuitem.setAttribute('checked','true');
1145 menuitem.setAttribute('label',sc_libs2[i][0]);
1146 menuitem.setAttribute('value',sc_libs2[i][1]);
1147 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1148 x.appendChild(menuitem);
1151 /******************************************************************************************************/
1152 /* Prepare the panes */
1154 var groupbox; var caption; var vbox; var grid; var rows;
1156 /******************************************************************************************************/
1157 /* Loop through the field names */
1159 for (h in g.panes_and_field_names) {
1160 if (!document.getElementById(h)) continue;
1161 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1163 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1164 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1166 for (var a in attr) {
1167 groupbox.setAttribute(a,attr[a]);
1170 caption = document.createElement('caption'); groupbox.appendChild(caption);
1171 caption.setAttribute('label',fn);
1172 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1173 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1174 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1175 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1176 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1177 grid.setAttribute('flex','1');
1178 rows = grid.lastChild;
1181 /**************************************************************************************/
1182 /* Loop through each value for the field */
1184 for (var j in g.summary[fn]) {
1185 var value = j; var count = g.summary[fn][j];
1186 row = document.createElement('row'); rows.appendChild(row);
1187 var label1 = document.createElement('description'); row.appendChild(label1);
1188 if (g.special_exception[ fn ]) {
1189 g.special_exception[ fn ]( label1, value );
1191 label1.appendChild( document.createTextNode(value) );
1193 var label2 = document.createElement('description'); row.appendChild(label2);
1196 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1198 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1200 label2.appendChild( document.createTextNode(copy_count) );
1202 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1203 var hbox = document.createElement('hbox'); // main input controls go here
1204 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1205 groupbox.appendChild(hbox);
1206 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1207 groupbox.appendChild(hbox2);
1209 /**************************************************************************************/
1210 /* Render the input widget */
1212 if (f[1].input && g.edit) {
1213 g.render_input(hbox,f[1]);
1217 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1223 /******************************************************************************************************/
1224 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1225 JSAN.use('util.file');
1226 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1227 g.copy_editor_prefs = util.widgets.load_attributes(file);
1228 for (var i in g.copy_editor_prefs) {
1229 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1231 g.toggle_stat_cat_display( document.getElementById(i) );
1232 } catch(E) { alert(E); }
1235 if (g.template_menu) g.template_menu.value = g.template_menu.getAttribute('value');
1239 /******************************************************************************************************/
1240 /* This actually draws the change button and input widget for a given field */
1241 g.render_input = function(node,blob) {
1243 // node = hbox ; groupbox -> hbox, hbox
1245 var groupbox = node.parentNode;
1246 var caption = groupbox.firstChild;
1247 var vbox = node.previousSibling;
1249 var hbox2 = node.nextSibling;
1251 var input_cmd = blob.input;
1252 var render_cmd = blob.render;
1253 var attr = blob.attr;
1255 var block = false; var first = true;
1257 function on_mouseover(ev) {
1258 groupbox.setAttribute('style','background: white');
1261 function on_mouseout(ev) {
1262 groupbox.setAttribute('style','');
1265 vbox.addEventListener('mouseover',on_mouseover,false);
1266 vbox.addEventListener('mouseout',on_mouseout,false);
1267 groupbox.addEventListener('mouseover',on_mouseover,false);
1268 groupbox.addEventListener('mouseout',on_mouseout,false);
1269 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1270 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1272 function on_click(ev){
1274 if (block) return; block = true;
1278 function post_c(v) {
1280 /* FIXME - kludgy */
1281 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1285 f = input_cmd.match(/apply\("(.+?)",/)[1];
1288 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1294 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1298 g.summarize( g.copies );
1300 g.check_for_unmet_required_fields();
1301 document.getElementById(caption.id).focus();
1305 g.error.standard_unexpected_error_alert('post_c',E);
1308 var x; var c; eval( input_cmd );
1310 util.widgets.remove_children(vbox);
1311 util.widgets.remove_children(hbox);
1312 util.widgets.remove_children(hbox2);
1313 hbox.appendChild(x);
1314 var apply = document.createElement('button');
1315 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1316 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1317 hbox2.appendChild(apply);
1318 apply.addEventListener('command',function() { c(x.value); },false);
1319 var cancel = document.createElement('button');
1320 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1321 cancel.addEventListener('command',function() {
1322 setTimeout( function() {
1323 g.summarize( g.copies );
1325 g.check_for_unmet_required_fields();
1326 document.getElementById(caption.id).focus();
1331 hbox2.appendChild(cancel);
1332 setTimeout( function() { x.focus(); }, 0 );
1335 g.error.standard_unexpected_error_alert('render_input',E);
1338 vbox.addEventListener('click',on_click, false);
1339 hbox.addEventListener('click',on_click, false);
1340 caption.addEventListener('click',on_click, false);
1341 caption.addEventListener('keypress',function(ev) {
1342 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1344 caption.setAttribute('style','-moz-user-focus: normal');
1345 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1346 caption.setAttribute('onblur','this.setAttribute("class","")');
1349 g.error.sdump('D_ERROR',E + '\n');
1353 /******************************************************************************************************/
1354 /* store the copies in the global xpcom stash */
1356 g.stash_and_close = function() {
1360 if (g.handle_update) {
1362 var r = g.network.request(
1363 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1364 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1365 [ ses(), g.copies, true ]
1367 if (typeof r.ilsevent != 'undefined') {
1368 g.error.standard_unexpected_error_alert('copy update',r);
1370 /* FIXME -- revisit the return value here */
1372 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1375 //g.data.temp_copies = js2JSON( g.copies );
1376 //g.data.stash('temp_copies');
1377 xulG.copies = g.copies;
1378 update_modal_xulG(xulG);
1379 JSAN.use('util.widgets');
1380 util.widgets.dispatch('close',window);
1382 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1386 /******************************************************************************************************/
1387 /* spawn copy notes interface */
1389 g.copy_notes = function() {
1390 JSAN.use('util.window'); var win = new util.window();
1392 urls.XUL_COPY_NOTES,
1393 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1394 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1395 { 'copy_id' : g.copies[0].id() }
1399 /******************************************************************************************************/
1400 /* hides or unhides stat cats based on library stat cat filter menu */
1401 g.toggle_stat_cat_display = function(el) {
1403 var visible = el.getAttribute('checked');
1404 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1405 for (var n = 0; n < nl.length; n++) {
1407 nl[n].setAttribute('hidden','false');
1409 nl[n].setAttribute('hidden','true');
1412 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1413 g.save_attributes();
1416 /******************************************************************************************************/
1417 /* This adds a stat cat definition to the stat cat pane for rendering */
1418 g.save_attributes = function() {
1419 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1420 var what_to_save = {};
1421 for (var i in g.copy_editor_prefs) {
1422 what_to_save[i] = [];
1423 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1425 util.widgets.save_attributes(file, what_to_save );
1428 /******************************************************************************************************/
1429 /* This adds a stat cat definition to the stat cat pane for rendering */
1430 g.add_stat_cat = function(sc) {
1432 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1436 if (typeof sc == 'object') {
1441 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1443 g.stat_cat_seen[ sc_id ] = 1;
1445 if (typeof sc != 'object') {
1447 sc = g.network.simple_request(
1448 'FM_ASC_BATCH_RETRIEVE',
1449 [ ses(), [ sc_id ] ]
1454 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1456 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1458 if (get_bool( sc.required() )) {
1459 g.required[ label_name ] = 1;
1465 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1466 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1467 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()
1468 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1469 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1476 g.panes_and_field_names.right_pane4.push( temp_array );
1478 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1482 /******************************************************************************************************/
1483 /* Add stat cats to the panes_and_field_names.right_pane4 */
1484 g.populate_stat_cats = function() {
1486 g.data.stash_retrieve();
1487 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1489 function get(lib_id,only_these) {
1490 g.data.stash_retrieve();
1491 var label = 'asc_list_for_lib_'+lib_id;
1492 if (typeof g.data[label] == 'undefined') {
1493 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1494 if (typeof robj.ilsevent != 'undefined') throw(robj);
1496 for (var j = 0; j < robj.length; j++) {
1497 var my_asc = robj[j];
1498 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1499 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1500 g.data.hash.asc[ my_asc.id() ] = my_asc;
1502 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1503 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1504 temp_list.push( my_asc );
1507 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1509 return g.data[label];
1512 /* The stat cats for the pertinent library -- this is based on workstation ou */
1513 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1514 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1515 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1516 g.add_stat_cat( g.data.list.my_asc[i] );
1519 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1520 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1522 function add_common_ancestors(sc_libs) {
1523 JSAN.use('util.fm_utils');
1524 var libs = []; for (var i in sc_libs) libs.push(i);
1525 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1526 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1528 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1529 var asc_list = get(ancestor, ancestors);
1530 for (var i = 0; i < asc_list.length; i++) {
1531 g.add_stat_cat( asc_list[i] );
1536 /* stat cats based on stat cat entries present on these copies */
1538 for (var i = 0; i < g.copies.length; i++) {
1539 var entries = g.copies[i].stat_cat_entries();
1540 if (!entries) entries = [];
1541 for (var j = 0; j < entries.length; j++) {
1542 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1543 sc_libs[ lib ] = true;
1546 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1548 /* stat cats based on Circ Lib */
1550 for (var i = 0; i < g.copies.length; i++) {
1551 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1552 sc_libs[ circ_lib ] = true;
1554 add_common_ancestors(sc_libs);
1556 /* stat cats based on Owning Lib */
1558 for (var i = 0; i < g.copies.length; i++) {
1559 var cn_id = g.copies[i].call_number();
1561 if (! g.map_acn[ cn_id ]) {
1562 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1563 if (typeof req.ilsevent == 'undefined') {
1564 g.map_acn[ cn_id ] = req;
1569 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1570 sc_libs[ owning_lib ] = true;
1573 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1575 g.panes_and_field_names.right_pane4.sort();
1579 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1583 g.check_for_unmet_required_fields = function() {
1585 for (var fn in g.required) {
1586 if (typeof g.populated[fn] == 'undefined') {
1590 if (xulG.unified_interface) {
1591 if (abort.length > 0) {
1592 if (typeof xulG.lock_save_button == 'function') {
1593 xulG.lock_save_button();
1596 if (typeof xulG.unlock_save_button == 'function') {
1597 xulG.unlock_save_button();
1601 if (abort.length > 0) {
1602 $('save').setAttribute('disabled','true');
1604 $('save').setAttribute('disabled','false');