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.active_date.label'),
871 render: 'util.date.formatted_date( fm.active_date(), "%F");',
875 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
877 render: 'fm.creator();',
881 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
883 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
887 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
889 render: 'fm.editor();',
898 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
900 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
901 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);',
906 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
908 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
909 //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);',
910 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);',
914 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
916 render: 'fm.call_number();',
917 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,
921 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
923 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
924 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);',
934 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
936 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") )',
937 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);',
941 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
943 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") )',
944 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);',
948 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
950 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() )',
951 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);',
956 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
958 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") )',
959 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);',
963 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
965 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; }',
966 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);',
971 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
973 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; }',
974 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);',
979 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
981 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',
982 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);',
986 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
988 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()])',
989 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);',
996 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
998 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
999 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);',
1004 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1006 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") )',
1007 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);',
1011 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1013 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1014 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);',
1018 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1020 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1021 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);',
1026 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1028 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") )',
1029 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);',
1033 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1035 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") )',
1036 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);',
1040 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1042 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")',
1043 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);',
1055 /******************************************************************************************************/
1056 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1058 g.summarize = function( copies ) {
1059 /******************************************************************************************************/
1062 JSAN.use('util.date'); JSAN.use('util.money');
1065 for (var i in g.panes_and_field_names) {
1066 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1068 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1069 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1071 /******************************************************************************************************/
1072 /* Loop through the field names */
1074 for (var i = 0; i < g.field_names.length; i++) {
1076 var field_name = g.field_names[i][0];
1077 var render = g.field_names[i][1].render;
1078 var attr = g.field_names[i][1].attr;
1079 g.summary[ field_name ] = {};
1080 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1082 /******************************************************************************************************/
1083 /* Loop through the copies */
1085 for (var j = 0; j < copies.length; j++) {
1088 var cmd = render || ('fm.' + field_name + '();');
1089 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1091 /**********************************************************************************************/
1092 /* Try to retrieve the value for this field for this copy */
1095 value = eval( cmd );
1097 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1099 if (typeof value == 'object' && value != null) {
1100 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1102 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1103 delete g.populated[field_name];
1106 /**********************************************************************************************/
1107 /* Tally the count */
1109 if (g.summary[ field_name ][ value ]) {
1110 g.summary[ field_name ][ value ]++;
1112 g.summary[ field_name ][ value ] = 1;
1116 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1119 /******************************************************************************************************/
1120 /* Display the summarized data and inputs for editing */
1122 g.render = function() {
1124 /******************************************************************************************************/
1125 /* Library setup and clear any existing interface */
1127 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1129 for (var i in g.panes_and_field_names) {
1130 var p = document.getElementById(i);
1131 if (p) util.widgets.remove_children(p);
1134 /******************************************************************************************************/
1135 /* Populate the library filter menu for stat cats */
1138 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1139 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1142 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1144 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1145 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1146 for (var i = 0; i < sc_libs2.length; i++) {
1147 var menuitem = document.createElement('menuitem');
1148 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1149 menuitem.setAttribute('type','checkbox');
1150 menuitem.setAttribute('checked','true');
1151 menuitem.setAttribute('label',sc_libs2[i][0]);
1152 menuitem.setAttribute('value',sc_libs2[i][1]);
1153 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1154 x.appendChild(menuitem);
1157 /******************************************************************************************************/
1158 /* Prepare the panes */
1160 var groupbox; var caption; var vbox; var grid; var rows;
1162 /******************************************************************************************************/
1163 /* Loop through the field names */
1165 for (h in g.panes_and_field_names) {
1166 if (!document.getElementById(h)) continue;
1167 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1169 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1170 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1172 for (var a in attr) {
1173 groupbox.setAttribute(a,attr[a]);
1176 caption = document.createElement('caption'); groupbox.appendChild(caption);
1177 caption.setAttribute('label',fn);
1178 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1179 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1180 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1181 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1182 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1183 grid.setAttribute('flex','1');
1184 rows = grid.lastChild;
1187 /**************************************************************************************/
1188 /* Loop through each value for the field */
1190 for (var j in g.summary[fn]) {
1191 var value = j; var count = g.summary[fn][j];
1192 row = document.createElement('row'); rows.appendChild(row);
1193 var label1 = document.createElement('description'); row.appendChild(label1);
1194 if (g.special_exception[ fn ]) {
1195 g.special_exception[ fn ]( label1, value );
1197 label1.appendChild( document.createTextNode(value) );
1199 var label2 = document.createElement('description'); row.appendChild(label2);
1202 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1204 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1206 label2.appendChild( document.createTextNode(copy_count) );
1208 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1209 var hbox = document.createElement('hbox'); // main input controls go here
1210 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1211 groupbox.appendChild(hbox);
1212 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1213 groupbox.appendChild(hbox2);
1215 /**************************************************************************************/
1216 /* Render the input widget */
1218 if (f[1].input && g.edit) {
1219 g.render_input(hbox,f[1]);
1223 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1229 /******************************************************************************************************/
1230 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1231 JSAN.use('util.file');
1232 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1233 g.copy_editor_prefs = util.widgets.load_attributes(file);
1234 for (var i in g.copy_editor_prefs) {
1235 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1237 g.toggle_stat_cat_display( document.getElementById(i) );
1238 } catch(E) { alert(E); }
1241 if (g.template_menu) g.template_menu.value = g.template_menu.getAttribute('value');
1245 /******************************************************************************************************/
1246 /* This actually draws the change button and input widget for a given field */
1247 g.render_input = function(node,blob) {
1249 // node = hbox ; groupbox -> hbox, hbox
1251 var groupbox = node.parentNode;
1252 var caption = groupbox.firstChild;
1253 var vbox = node.previousSibling;
1255 var hbox2 = node.nextSibling;
1257 var input_cmd = blob.input;
1258 var render_cmd = blob.render;
1259 var attr = blob.attr;
1261 var block = false; var first = true;
1263 function on_mouseover(ev) {
1264 groupbox.setAttribute('style','background: white');
1267 function on_mouseout(ev) {
1268 groupbox.setAttribute('style','');
1271 vbox.addEventListener('mouseover',on_mouseover,false);
1272 vbox.addEventListener('mouseout',on_mouseout,false);
1273 groupbox.addEventListener('mouseover',on_mouseover,false);
1274 groupbox.addEventListener('mouseout',on_mouseout,false);
1275 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1276 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1278 function on_click(ev){
1280 if (block) return; block = true;
1284 function post_c(v) {
1286 /* FIXME - kludgy */
1287 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1291 f = input_cmd.match(/apply\("(.+?)",/)[1];
1294 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1300 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1304 g.summarize( g.copies );
1306 g.check_for_unmet_required_fields();
1307 document.getElementById(caption.id).focus();
1311 g.error.standard_unexpected_error_alert('post_c',E);
1314 var x; var c; eval( input_cmd );
1316 util.widgets.remove_children(vbox);
1317 util.widgets.remove_children(hbox);
1318 util.widgets.remove_children(hbox2);
1319 hbox.appendChild(x);
1320 var apply = document.createElement('button');
1321 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1322 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1323 hbox2.appendChild(apply);
1324 apply.addEventListener('command',function() { c(x.value); },false);
1325 var cancel = document.createElement('button');
1326 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1327 cancel.addEventListener('command',function() {
1328 setTimeout( function() {
1329 g.summarize( g.copies );
1331 g.check_for_unmet_required_fields();
1332 document.getElementById(caption.id).focus();
1337 hbox2.appendChild(cancel);
1338 setTimeout( function() { x.focus(); }, 0 );
1341 g.error.standard_unexpected_error_alert('render_input',E);
1344 vbox.addEventListener('click',on_click, false);
1345 hbox.addEventListener('click',on_click, false);
1346 caption.addEventListener('click',on_click, false);
1347 caption.addEventListener('keypress',function(ev) {
1348 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1350 caption.setAttribute('style','-moz-user-focus: normal');
1351 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1352 caption.setAttribute('onblur','this.setAttribute("class","")');
1355 g.error.sdump('D_ERROR',E + '\n');
1359 /******************************************************************************************************/
1360 /* store the copies in the global xpcom stash */
1362 g.stash_and_close = function() {
1366 if (g.handle_update) {
1368 var r = g.network.request(
1369 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1370 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1371 [ ses(), g.copies, true ]
1373 if (typeof r.ilsevent != 'undefined') {
1374 g.error.standard_unexpected_error_alert('copy update',r);
1376 /* FIXME -- revisit the return value here */
1378 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1381 //g.data.temp_copies = js2JSON( g.copies );
1382 //g.data.stash('temp_copies');
1383 xulG.copies = g.copies;
1384 update_modal_xulG(xulG);
1385 JSAN.use('util.widgets');
1386 util.widgets.dispatch('close',window);
1388 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1392 /******************************************************************************************************/
1393 /* spawn copy notes interface */
1395 g.copy_notes = function() {
1396 JSAN.use('util.window'); var win = new util.window();
1398 urls.XUL_COPY_NOTES,
1399 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1400 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1401 { 'copy_id' : g.copies[0].id() }
1405 /******************************************************************************************************/
1406 /* hides or unhides stat cats based on library stat cat filter menu */
1407 g.toggle_stat_cat_display = function(el) {
1409 var visible = el.getAttribute('checked');
1410 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1411 for (var n = 0; n < nl.length; n++) {
1413 nl[n].setAttribute('hidden','false');
1415 nl[n].setAttribute('hidden','true');
1418 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1419 g.save_attributes();
1422 /******************************************************************************************************/
1423 /* This adds a stat cat definition to the stat cat pane for rendering */
1424 g.save_attributes = function() {
1425 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1426 var what_to_save = {};
1427 for (var i in g.copy_editor_prefs) {
1428 what_to_save[i] = [];
1429 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1431 util.widgets.save_attributes(file, what_to_save );
1434 /******************************************************************************************************/
1435 /* This adds a stat cat definition to the stat cat pane for rendering */
1436 g.add_stat_cat = function(sc) {
1438 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1442 if (typeof sc == 'object') {
1447 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1449 g.stat_cat_seen[ sc_id ] = 1;
1451 if (typeof sc != 'object') {
1453 sc = g.network.simple_request(
1454 'FM_ASC_BATCH_RETRIEVE',
1455 [ ses(), [ sc_id ] ]
1460 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1462 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1464 if (get_bool( sc.required() )) {
1465 g.required[ label_name ] = 1;
1471 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1472 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1473 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()
1474 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1475 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1482 g.panes_and_field_names.right_pane4.push( temp_array );
1484 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1488 /******************************************************************************************************/
1489 /* Add stat cats to the panes_and_field_names.right_pane4 */
1490 g.populate_stat_cats = function() {
1492 g.data.stash_retrieve();
1493 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1495 function get(lib_id,only_these) {
1496 g.data.stash_retrieve();
1497 var label = 'asc_list_for_lib_'+lib_id;
1498 if (typeof g.data[label] == 'undefined') {
1499 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1500 if (typeof robj.ilsevent != 'undefined') throw(robj);
1502 for (var j = 0; j < robj.length; j++) {
1503 var my_asc = robj[j];
1504 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1505 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1506 g.data.hash.asc[ my_asc.id() ] = my_asc;
1508 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1509 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1510 temp_list.push( my_asc );
1513 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1515 return g.data[label];
1518 /* The stat cats for the pertinent library -- this is based on workstation ou */
1519 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1520 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1521 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1522 g.add_stat_cat( g.data.list.my_asc[i] );
1525 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1526 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1528 function add_common_ancestors(sc_libs) {
1529 JSAN.use('util.fm_utils');
1530 var libs = []; for (var i in sc_libs) libs.push(i);
1531 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1532 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1534 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1535 var asc_list = get(ancestor, ancestors);
1536 for (var i = 0; i < asc_list.length; i++) {
1537 g.add_stat_cat( asc_list[i] );
1542 /* stat cats based on stat cat entries present on these copies */
1544 for (var i = 0; i < g.copies.length; i++) {
1545 var entries = g.copies[i].stat_cat_entries();
1546 if (!entries) entries = [];
1547 for (var j = 0; j < entries.length; j++) {
1548 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1549 sc_libs[ lib ] = true;
1552 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1554 /* stat cats based on Circ Lib */
1556 for (var i = 0; i < g.copies.length; i++) {
1557 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1558 sc_libs[ circ_lib ] = true;
1560 add_common_ancestors(sc_libs);
1562 /* stat cats based on Owning Lib */
1564 for (var i = 0; i < g.copies.length; i++) {
1565 var cn_id = g.copies[i].call_number();
1567 if (! g.map_acn[ cn_id ]) {
1568 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1569 if (typeof req.ilsevent == 'undefined') {
1570 g.map_acn[ cn_id ] = req;
1575 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1576 sc_libs[ owning_lib ] = true;
1579 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1581 g.panes_and_field_names.right_pane4.sort();
1585 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1589 g.check_for_unmet_required_fields = function() {
1591 for (var fn in g.required) {
1592 if (typeof g.populated[fn] == 'undefined') {
1596 if (xulG.unified_interface) {
1597 if (abort.length > 0) {
1598 if (typeof xulG.lock_save_button == 'function') {
1599 xulG.lock_save_button();
1602 if (typeof xulG.unlock_save_button == 'function') {
1603 xulG.unlock_save_button();
1607 if (abort.length > 0) {
1608 $('save').setAttribute('disabled','true');
1610 $('save').setAttribute('disabled','false');