2 var g = { 'disabled' : false };
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});
55 /******************************************************************************************************/
56 /* Get preference (if it exists) for copy location label order */
58 g.cl_first = false; // Default to legacy OU first mode
59 var prefs = Components.classes['@mozilla.org/preferences-service;1']
60 .getService(Components.interfaces['nsIPrefBranch']);
62 g.cl_first = prefs.getBoolPref('oils.copy_editor.copy_location_name_first');
65 /******************************************************************************************************/
66 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
67 /* Quick fix, messagecatalog only usable during/after onload */
72 /******************************************************************************************************/
73 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
75 if (xul_param('edit',{'modal_xulG':true}) == '1') {
79 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
81 // Editor desired, but let's check permissions
84 var check = g.network.simple_request(
85 'PERM_MULTI_ORG_CHECK',
88 g.data.list.au[0].id(),
89 util.functional.map_list(
93 var cn_id = o.call_number();
95 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
97 if (! g.map_acn[ cn_id ]) {
98 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
99 if (typeof req.ilsevent == 'undefined') {
100 g.map_acn[ cn_id ] = req;
101 lib = g.map_acn[ cn_id ].owning_lib();
106 lib = g.map_acn[ cn_id ].owning_lib();
109 return typeof lib == 'object' ? lib.id() : lib;
112 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
115 g.edit = check.length == 0;
117 g.error.standard_unexpected_error_alert('batch permission check',E);
123 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
124 $('save').setAttribute('hidden','false');
126 $('top_nav').setAttribute('hidden','true');
129 g.retrieve_templates();
132 $('top_nav').setAttribute('hidden','true');
135 g.panes_and_field_names.left_pane =
138 $('catStrings').getString('staff.cat.copy_editor.status'),
140 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
141 input: g.safe_to_edit_copy_status() ? 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.ccs, function(obj) { return [ obj.name(), obj.id(), typeof my_constants.magical_statuses[obj.id()] != "undefined" ? true : false ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);' : undefined,
142 //input: 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( util.functional.filter_list( g.data.list.ccs, function(obj) { return typeof my_constants.magical_statuses[obj.id()] == "undefined"; } ), function(obj) { return [ obj.name(), obj.id() ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
145 ].concat(g.panes_and_field_names.left_pane);
148 /******************************************************************************************************/
149 /* Show the Record Details? */
151 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
153 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
154 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
155 brief_display.setAttribute( 'flex','1' );
158 /******************************************************************************************************/
159 /* Add stat cats to the panes_and_field_names.right_pane4 */
161 g.populate_stat_cats();
163 /******************************************************************************************************/
164 /* Backup copies :) */
166 g.original_copies = js2JSON( g.copies );
168 /******************************************************************************************************/
171 g.summarize( g.copies );
173 g.check_for_unmet_required_fields();
175 if (xulG.unified_interface) {
176 xulG.disable_copy_editor = function(c) {
177 addCSSClass(document.documentElement,'disabled_copy_editor');
180 xulG.enable_copy_editor = function(c) {
181 removeCSSClass(document.documentElement,'disabled_copy_editor');
183 xulG.refresh_copy_editor();
185 xulG.refresh_copy_editor = function() {
186 dump('refresh_copy_editor\n');
187 addCSSClass(document.documentElement,'enabling_copy_editor');
189 xulG.clear_update_copy_editor_timeout();
190 g.copies = xulG.copies;
191 g.edit = g.copies.length > 0;
193 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
195 g.original_copies = js2JSON( g.copies );
196 g.hide_copy_notes_button();
197 for (var i = 0; i < g.applied_templates.length; i++) {
198 g._apply_template( g.applied_templates[i], false);
200 if (g.copies.length > 0) {
201 // Stop tracking these templates once they're applied
203 g.applied_templates = [];
205 g.summarize( g.copies );
207 g.check_for_unmet_required_fields();
210 removeCSSClass(document.documentElement,'enabling_copy_editor');
214 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
217 xulG.unlock_copy_editor = function() {
220 xulG.notify_of_templatable_field_change = function(id,v) {
221 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
224 g.hide_copy_notes_button();
228 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
229 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
234 /******************************************************************************************************/
235 /* Show copy notes button */
236 g.hide_copy_notes_button = function() {
237 if (g.copies.length > 0 && g.copies[0].id() < 0) {
238 document.getElementById('copy_notes').setAttribute('hidden','true');
239 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
240 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
242 if (g.copies.length != 1) {
243 document.getElementById('copy_notes').setAttribute('hidden','true');
247 /******************************************************************************************************/
248 /* Retrieve Templates */
250 g.retrieve_templates = function() {
252 JSAN.use('util.widgets'); JSAN.use('util.functional');
254 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
255 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
256 g.templates = robj['staff_client.copy_editor.templates'];
258 util.widgets.remove_children('template_placeholder');
259 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
261 g.template_menu = util.widgets.make_menulist( list );
262 g.template_menu.setAttribute('id','template_menu');
263 $('template_placeholder').appendChild(g.template_menu);
264 g.template_menu.addEventListener(
266 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
270 if (xulG.unified_interface) {
271 if (typeof xulG.update_unified_template_list == 'function') {
272 xulG.update_unified_template_list(list);
273 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
274 xulG.update_item_editor_template_selection = function(new_value) {
275 g.template_menu.setAttribute('value', new_value);
276 g.template_menu.value = new_value;
277 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
280 xulG.item_editor_apply_template = function() { g.apply_template(true); };
281 xulG.item_editor_delete_template = function() { g.delete_template(); };
282 xulG.item_editor_save_template = function() { g.save_template(); };
283 xulG.item_editor_import_templates = function() { g.import_templates(); };
284 xulG.item_editor_export_templates = function() { g.export_templates(); };
285 xulG.item_editor_reset = function() { g.reset(); };
290 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
294 /******************************************************************************************************/
297 g.applied_templates = [];
299 g.apply_template = function(apply_volume_editor_template_changes) {
301 var name = g.template_menu.value;
302 if (g.templates[ name ] != 'undefined') {
304 // We're only tracking these applied templates temporarily,
305 // specifically when they're used prior to copies being
306 // created in the unified interface.
307 g.applied_templates.push( name );
309 g._apply_template(name,apply_volume_editor_template_changes);
310 g.summarize( g.copies );
312 g.check_for_unmet_required_fields();
315 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
319 g._apply_template = function(name,apply_volume_editor_template_changes) {
321 if (g.templates[ name ] != 'undefined') {
322 var template = g.templates[ name ];
323 for (var i in template) {
324 g.changed[ i ] = template[ i ];
325 switch( template[i].type ) {
327 g.apply(template[i].field,template[i].value);
330 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
333 g.apply_owning_lib(template[i].value);
335 case 'volume_copy_creator' :
336 if (xulG.unified_interface && apply_volume_editor_template_changes) {
337 xulG.apply_template_to_batch(template[i].field,template[i].value);
344 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
348 /******************************************************************************************************/
349 /* Save as Template */
351 g.save_template = function() {
353 var name = window.prompt(
354 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
356 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
359 g.templates[name] = g.changed;
360 var robj = g.network.simple_request(
361 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
363 if (typeof robj.ilsevent != 'undefined') {
366 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
370 g.retrieve_templates();
372 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
378 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
382 /******************************************************************************************************/
383 /* Delete Template */
385 g.delete_template = function() {
387 var name = g.template_menu.value;
389 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
390 delete(g.templates[name]);
391 var robj = g.network.simple_request(
392 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
394 if (typeof robj.ilsevent != 'undefined') {
397 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
401 g.retrieve_templates();
403 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
409 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
413 /******************************************************************************************************/
414 /* Export Templates */
416 g.export_templates = function() {
418 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
419 JSAN.use('util.file'); var f = new util.file('');
420 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
422 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
426 /******************************************************************************************************/
427 /* Import Templates */
429 g.import_templates = function() {
431 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
432 JSAN.use('util.file'); var f = new util.file('');
433 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
435 for (var i in temp) {
437 if (g.templates[i]) {
439 var r = g.error.yns_alert(
440 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
441 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
442 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
443 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
445 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
448 if (r == 0 /* Yes */) g.templates[i] = temp[i];
452 g.templates[i] = temp[i];
458 var r = g.error.yns_alert(
459 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
460 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
461 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
462 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
464 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
467 if (r == 0 /* Yes */) {
468 var robj = g.network.simple_request(
469 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
471 if (typeof robj.ilsevent != 'undefined') {
474 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
478 g.retrieve_templates();
480 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
486 util.widgets.remove_children('template_placeholder');
487 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
488 g.template_menu = util.widgets.make_menulist( list );
489 $('template_placeholder').appendChild(g.template_menu);
490 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
495 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
500 /******************************************************************************************************/
501 /* Restore backup copies */
503 g.reset = function() {
504 g.applied_templates = [];
506 g.copies = JSON2js( g.original_copies );
507 g.summarize( g.copies );
509 g.check_for_unmet_required_fields();
511 if (xulG.unified_interface) {
512 xulG.reset_batch_menus();
516 /******************************************************************************************************/
517 /* Apply a value to a specific field on all the copies being edited */
519 g.apply = function(field,value) {
520 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
521 if (value == '<HACK:KLUDGE:NULL>') {
524 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
525 if (field == 'price' || field == 'deposit_amount') {
529 JSAN.use('util.money'); value = util.money.sanitize( value );
532 for (var i = 0; i < g.copies.length; i++) {
533 var copy = g.copies[i];
535 copy[field]( value ); copy.ischanged('1');
544 /******************************************************************************************************/
545 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
547 g.apply_stat_cat = function(sc_id,entry_id) {
548 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
549 for (var i = 0; i < g.copies.length; i++) {
550 var copy = g.copies[i];
553 var temp = copy.stat_cat_entries();
554 if (!temp) temp = [];
555 temp = util.functional.filter_list(
558 return (obj.stat_cat() != sc_id);
563 util.functional.find_id_object_in_list(
564 g.data.hash.asc[sc_id].entries(),
569 copy.stat_cat_entries( temp );
572 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
579 /******************************************************************************************************/
580 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
582 g.apply_owning_lib = function(ou_id) {
583 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
584 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
585 if (! g.safe_to_change_owning_lib() ) { return; }
586 for (var i = 0; i < g.copies.length; i++) {
587 var copy = g.copies[i];
589 if (!g.map_acn[copy.call_number()]) {
590 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
591 if (typeof volume.ilsevent != 'undefined') {
592 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
595 g.map_acn[copy.call_number()] = volume;
597 var old_volume = g.map_acn[copy.call_number()];
598 var acn_blob = g.network.simple_request(
599 'FM_ACN_FIND_OR_CREATE',
600 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
602 if (typeof acn_blob.ilsevent != 'undefined') {
603 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
606 copy.call_number(acn_blob.acn_id);
609 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
616 /******************************************************************************************************/
617 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
619 g.safe_to_change_owning_lib = function() {
621 if (xulG.unified_interface) { return false; }
623 for (var i = 0; i < g.copies.length; i++) {
624 var cn = g.copies[i].call_number();
625 if (typeof cn == 'object') { cn = cn.id(); }
626 if (cn == -1) { safe = false; }
630 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
635 /******************************************************************************************************/
636 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
638 g.safe_to_edit_copy_status = function() {
641 for (var i = 0; i < g.copies.length; i++) {
642 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
643 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
647 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
652 /******************************************************************************************************/
653 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
655 g.populate_alert_message_input = function(tb) {
657 var seen = {}; var s = '';
658 for (var i = 0; i < g.copies.length; i++) {
659 var msg = g.copies[i].alert_message();
661 if (typeof seen[msg] == 'undefined') {
667 tb.setAttribute('value',s);
669 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
673 /***************************************************************************************************************/
674 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
676 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
677 g.data.stash_retrieve();
678 var label = 'acpl_list_for_lib_'+lib_id;
679 if (typeof g.data[label] == 'undefined') {
680 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
681 if (typeof robj.ilsevent != 'undefined') throw(robj);
683 for (var j = 0; j < robj.length; j++) {
684 var my_acpl = robj[j];
685 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
686 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
687 g.data.list.acpl.push( my_acpl );
689 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
690 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
691 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
692 temp_list.push( my_acpl );
695 g.data[label] = temp_list; g.data.stash(label,'hash','list');
697 return g.data[label];
700 /******************************************************************************************************/
701 /* This returns a list of acpl's appropriate for the copies being edited */
703 g.get_acpl_list = function() {
706 JSAN.use('util.functional');
710 /**************************************/
711 /* get owning libs from call numbers */
713 var owning_libs = {};
714 for (var i = 0; i < g.copies.length; i++) {
715 var callnumber = g.copies[i].call_number();
716 if (!callnumber) continue;
717 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
719 if (! g.map_acn[ cn_id ]) {
720 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
721 if (typeof req.ilsevent == 'undefined') {
722 g.map_acn[ cn_id ] = req;
727 var consider_lib = g.map_acn[ cn_id ].owning_lib();
728 if (!consider_lib) continue;
729 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
733 for (var i in g.callnumbers) {
734 var consider_lib = g.callnumbers[i].owning_lib;
735 if (!consider_lib) continue;
736 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
740 /***************************************************************************************************/
741 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
743 JSAN.use('util.fm_utils');
744 var libs = []; for (var i in owning_libs) libs.push(i);
745 if (libs.length > 0) {
746 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
747 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
750 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
751 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
752 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
753 if (acpl_list[i] != null) {
754 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
765 for (var i = 0; i < g.copies.length; i++) {
766 var consider_lib = g.copies[i].circ_lib();
767 if (!consider_lib) continue;
768 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
771 /***************************************************************************************************/
772 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
774 libs = []; for (var i in circ_libs) libs.push(i);
775 if (libs.length > 0) {
776 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
777 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
780 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
781 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
782 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
783 if (acpl_list[i] != null) {
784 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
790 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
791 return acpl_list.sort(
793 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
794 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
795 if (label_a < label_b) return -1;
796 if (label_a > label_b) return 1;
802 g.error.standard_unexpected_error_alert('get_acpl_list',E);
808 /******************************************************************************************************/
809 /* This keeps track of which fields have been edited for styling purposes */
813 /******************************************************************************************************/
814 /* This keeps track of which fields are required, and which fields have been populated */
819 /******************************************************************************************************/
820 /* These need data from the middle layer to render */
822 function init_panes0() {
823 g.special_exception = {};
824 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
825 JSAN.use('util.widgets');
826 if (value>0) { /* an existing call number */
827 g.network.simple_request(
828 'FM_ACN_RETRIEVE.authoritative',
831 var cn = '??? id = ' + value;
833 cn = req.getResultObject();
835 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
837 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
840 } else { /* a yet to be created call number */
842 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
846 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
847 if (!Number(value)) return;
848 g.network.simple_request(
849 'FM_AU_RETRIEVE_VIA_ID',
852 var p = '??? id = ' + value;
854 p = req.getResultObject();
858 g.error.sdump('D_ERROR','patron retrieve: ' + E);
860 JSAN.use('util.widgets');
861 util.widgets.set_text(label,p);
865 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
866 if (!Number(value)) return;
867 g.network.simple_request(
868 'FM_AU_RETRIEVE_VIA_ID',
871 var p = '??? id = ' + value;
873 p = req.getResultObject();
877 g.error.sdump('D_ERROR','patron retrieve: ' + E);
879 util.widgets.set_text(label,p);
885 /******************************************************************************************************/
886 g.readonly_stat_cat_names = [];
887 g.editable_stat_cat_names = [];
889 /******************************************************************************************************/
890 /* These get show in the left panel */
892 function init_panes() {
893 g.panes_and_field_names = {
898 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
900 render: 'fm.barcode();',
904 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
906 render: 'util.date.formatted_date( fm.create_date(), "%F");',
910 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
912 render: 'util.date.formatted_date( fm.active_date(), "%F");',
916 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
918 render: 'fm.creator();',
922 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
924 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
928 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
930 render: 'fm.editor();',
939 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
941 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
942 input: 'c = function(v){ g.apply("location",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.get_acpl_list(), function(obj) { return [ ' + (g.cl_first ? 'obj.name() + " : " + g.data.hash.aou[ obj.owning_lib() ].shortname()' : 'g.data.hash.aou[ obj.owning_lib() ].shortname() + " : " + obj.name()') + ', obj.id() ]; }).sort()); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
947 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
949 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
950 //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);',
951 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);',
955 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
957 render: 'fm.call_number();',
958 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,
962 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
964 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
965 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);',
975 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
977 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") )',
978 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);',
982 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
984 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") )',
985 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);',
989 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
991 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() )',
992 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);',
997 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
999 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") )',
1000 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);',
1004 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1006 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; }',
1007 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);',
1012 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1014 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; }',
1015 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);',
1020 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1022 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',
1023 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);',
1027 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1029 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()])',
1030 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);',
1037 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1039 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1040 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);',
1045 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1047 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") )',
1048 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);',
1052 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1054 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1055 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);',
1059 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1061 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1062 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);',
1067 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1069 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") )',
1070 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);',
1074 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1076 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") )',
1077 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);',
1081 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1083 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")',
1084 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);',
1096 /******************************************************************************************************/
1097 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1099 g.summarize = function( copies ) {
1100 /******************************************************************************************************/
1103 JSAN.use('util.date'); JSAN.use('util.money');
1106 for (var i in g.panes_and_field_names) {
1107 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1109 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1110 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1112 /******************************************************************************************************/
1113 /* Loop through the field names */
1115 for (var i = 0; i < g.field_names.length; i++) {
1117 var field_name = g.field_names[i][0];
1118 var render = g.field_names[i][1].render;
1119 var attr = g.field_names[i][1].attr;
1120 g.summary[ field_name ] = {};
1121 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1123 /******************************************************************************************************/
1124 /* Loop through the copies */
1126 for (var j = 0; j < copies.length; j++) {
1129 var cmd = render || ('fm.' + field_name + '();');
1130 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1132 /**********************************************************************************************/
1133 /* Try to retrieve the value for this field for this copy */
1136 value = eval( cmd );
1138 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1140 if (typeof value == 'object' && value != null) {
1141 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1143 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1144 delete g.populated[field_name];
1147 /**********************************************************************************************/
1148 /* Tally the count */
1150 if (g.summary[ field_name ][ value ]) {
1151 g.summary[ field_name ][ value ]++;
1153 g.summary[ field_name ][ value ] = 1;
1157 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1160 /******************************************************************************************************/
1161 /* Display the summarized data and inputs for editing */
1163 g.render = function() {
1165 /******************************************************************************************************/
1166 /* Library setup and clear any existing interface */
1168 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1170 for (var i in g.panes_and_field_names) {
1171 var p = document.getElementById(i);
1172 if (p) util.widgets.remove_children(p);
1175 /******************************************************************************************************/
1176 /* Populate the library filter menu for stat cats */
1179 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1180 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1183 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1185 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1186 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1187 for (var i = 0; i < sc_libs2.length; i++) {
1188 var menuitem = document.createElement('menuitem');
1189 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1190 menuitem.setAttribute('type','checkbox');
1191 menuitem.setAttribute('checked','true');
1192 menuitem.setAttribute('label',sc_libs2[i][0]);
1193 menuitem.setAttribute('value',sc_libs2[i][1]);
1194 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1195 x.appendChild(menuitem);
1198 /******************************************************************************************************/
1199 /* Prepare the panes */
1201 var groupbox; var caption; var vbox; var grid; var rows;
1203 /******************************************************************************************************/
1204 /* Loop through the field names */
1206 for (h in g.panes_and_field_names) {
1207 if (!document.getElementById(h)) continue;
1208 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1210 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1211 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1213 for (var a in attr) {
1214 groupbox.setAttribute(a,attr[a]);
1217 caption = document.createElement('caption'); groupbox.appendChild(caption);
1218 caption.setAttribute('label',fn);
1219 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1220 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1221 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1222 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1223 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1224 grid.setAttribute('flex','1');
1225 rows = grid.lastChild;
1228 /**************************************************************************************/
1229 /* Loop through each value for the field */
1231 for (var j in g.summary[fn]) {
1232 var value = j; var count = g.summary[fn][j];
1233 row = document.createElement('row'); rows.appendChild(row);
1234 var label1 = document.createElement('description'); row.appendChild(label1);
1235 if (g.special_exception[ fn ]) {
1236 g.special_exception[ fn ]( label1, value );
1238 label1.appendChild( document.createTextNode(value) );
1240 var label2 = document.createElement('description'); row.appendChild(label2);
1243 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1245 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1247 label2.appendChild( document.createTextNode(copy_count) );
1249 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1250 var hbox = document.createElement('hbox'); // main input controls go here
1251 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1252 groupbox.appendChild(hbox);
1253 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1254 groupbox.appendChild(hbox2);
1256 /**************************************************************************************/
1257 /* Render the input widget */
1259 if (f[1].input && g.edit) {
1260 g.render_input(hbox,f[1]);
1264 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1270 /******************************************************************************************************/
1271 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1272 JSAN.use('util.file');
1273 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1274 g.copy_editor_prefs = util.widgets.load_attributes(file);
1275 for (var i in g.copy_editor_prefs) {
1276 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1278 g.toggle_stat_cat_display( document.getElementById(i) );
1279 } catch(E) { alert(E); }
1282 if (g.template_menu) {
1283 g.template_menu.value = g.template_menu.getAttribute('value');
1284 if (xulG.unified_interface) {
1285 if (typeof xulG.update_unified_template_selection == 'function') {
1286 xulG.update_unified_template_selection(g.template_menu.value);
1293 /******************************************************************************************************/
1294 /* This actually draws the change button and input widget for a given field */
1295 g.render_input = function(node,blob) {
1297 // node = hbox ; groupbox -> hbox, hbox
1299 var groupbox = node.parentNode;
1300 var caption = groupbox.firstChild;
1301 var vbox = node.previousSibling;
1303 var hbox2 = node.nextSibling;
1305 var input_cmd = blob.input;
1306 var render_cmd = blob.render;
1307 var attr = blob.attr;
1309 var block = false; var first = true;
1311 function on_mouseover(ev) {
1312 groupbox.setAttribute('style','background: white');
1315 function on_mouseout(ev) {
1316 groupbox.setAttribute('style','');
1319 vbox.addEventListener('mouseover',on_mouseover,false);
1320 vbox.addEventListener('mouseout',on_mouseout,false);
1321 groupbox.addEventListener('mouseover',on_mouseover,false);
1322 groupbox.addEventListener('mouseout',on_mouseout,false);
1323 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1324 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1326 function on_click(ev){
1328 if (block || g.disabled || !g.edit) {
1335 function post_c(v) {
1337 /* FIXME - kludgy */
1338 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1342 f = input_cmd.match(/apply\("(.+?)",/)[1];
1345 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1351 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1355 g.summarize( g.copies );
1357 g.check_for_unmet_required_fields();
1358 document.getElementById(caption.id).focus();
1362 g.error.standard_unexpected_error_alert('post_c',E);
1365 var x; var c; eval( input_cmd );
1367 util.widgets.remove_children(vbox);
1368 util.widgets.remove_children(hbox);
1369 util.widgets.remove_children(hbox2);
1370 hbox.appendChild(x);
1371 var apply = document.createElement('button');
1372 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1373 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1374 hbox2.appendChild(apply);
1375 apply.addEventListener('command',function() { c(x.value); },false);
1376 var cancel = document.createElement('button');
1377 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1378 cancel.addEventListener('command',function() {
1379 setTimeout( function() {
1380 g.summarize( g.copies );
1382 g.check_for_unmet_required_fields();
1383 document.getElementById(caption.id).focus();
1388 hbox2.appendChild(cancel);
1389 setTimeout( function() { x.focus(); }, 0 );
1392 g.error.standard_unexpected_error_alert('render_input',E);
1395 vbox.addEventListener('click',on_click, false);
1396 hbox.addEventListener('click',on_click, false);
1397 caption.addEventListener('click',on_click, false);
1398 caption.addEventListener('keypress',function(ev) {
1399 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1401 caption.setAttribute('style','-moz-user-focus: normal');
1402 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1403 caption.setAttribute('onblur','this.setAttribute("class","")');
1406 g.error.sdump('D_ERROR',E + '\n');
1410 /******************************************************************************************************/
1411 /* store the copies in the global xpcom stash */
1413 g.stash_and_close = function() {
1417 if (g.handle_update) {
1419 var r = g.network.request(
1420 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1421 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1422 [ ses(), g.copies, true ]
1424 if (typeof r.ilsevent != 'undefined') {
1425 g.error.standard_unexpected_error_alert('copy update',r);
1427 /* FIXME -- revisit the return value here */
1429 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1432 //g.data.temp_copies = js2JSON( g.copies );
1433 //g.data.stash('temp_copies');
1434 xulG.copies = g.copies;
1435 update_modal_xulG(xulG);
1436 JSAN.use('util.widgets');
1437 util.widgets.dispatch('close',window);
1439 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1443 /******************************************************************************************************/
1444 /* spawn copy notes interface */
1446 g.copy_notes = function() {
1447 JSAN.use('util.window'); var win = new util.window();
1449 urls.XUL_COPY_NOTES,
1450 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1451 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1452 { 'copy_id' : g.copies[0].id() }
1456 /******************************************************************************************************/
1457 /* hides or unhides stat cats based on library stat cat filter menu */
1458 g.toggle_stat_cat_display = function(el) {
1460 var visible = el.getAttribute('checked');
1461 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1462 for (var n = 0; n < nl.length; n++) {
1464 nl[n].setAttribute('hidden','false');
1466 nl[n].setAttribute('hidden','true');
1469 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1470 g.save_attributes();
1473 /******************************************************************************************************/
1474 /* This adds a stat cat definition to the stat cat pane for rendering */
1475 g.save_attributes = function() {
1476 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1477 var what_to_save = {};
1478 for (var i in g.copy_editor_prefs) {
1479 what_to_save[i] = [];
1480 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1482 util.widgets.save_attributes(file, what_to_save );
1485 /******************************************************************************************************/
1486 /* This adds a stat cat definition to the stat cat pane for rendering */
1487 g.add_stat_cat = function(sc) {
1489 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1493 if (typeof sc == 'object') {
1498 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1500 g.stat_cat_seen[ sc_id ] = 1;
1502 if (typeof sc != 'object') {
1504 sc = g.network.simple_request(
1505 'FM_ASC_BATCH_RETRIEVE',
1506 [ ses(), [ sc_id ] ]
1511 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1513 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1515 if (get_bool( sc.required() )) {
1516 g.required[ label_name ] = 1;
1522 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1523 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1524 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()
1525 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1526 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1533 g.panes_and_field_names.right_pane4.push( temp_array );
1535 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1539 /******************************************************************************************************/
1540 /* Add stat cats to the panes_and_field_names.right_pane4 */
1541 g.populate_stat_cats = function() {
1543 g.data.stash_retrieve();
1544 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1546 function get(lib_id,only_these) {
1547 g.data.stash_retrieve();
1548 var label = 'asc_list_for_lib_'+lib_id;
1549 if (typeof g.data[label] == 'undefined') {
1550 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1551 if (typeof robj.ilsevent != 'undefined') throw(robj);
1553 for (var j = 0; j < robj.length; j++) {
1554 var my_asc = robj[j];
1555 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1556 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1557 g.data.hash.asc[ my_asc.id() ] = my_asc;
1559 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1560 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1561 temp_list.push( my_asc );
1564 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1566 return g.data[label];
1569 /* The stat cats for the pertinent library -- this is based on workstation ou */
1570 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1571 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1572 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1573 g.add_stat_cat( g.data.list.my_asc[i] );
1576 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1577 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1579 function add_common_ancestors(sc_libs) {
1580 JSAN.use('util.fm_utils');
1581 var libs = []; for (var i in sc_libs) libs.push(i);
1582 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1583 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1585 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1586 var asc_list = get(ancestor, ancestors);
1587 for (var i = 0; i < asc_list.length; i++) {
1588 g.add_stat_cat( asc_list[i] );
1593 /* stat cats based on stat cat entries present on these copies */
1595 for (var i = 0; i < g.copies.length; i++) {
1596 var entries = g.copies[i].stat_cat_entries();
1597 if (!entries) entries = [];
1598 for (var j = 0; j < entries.length; j++) {
1599 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1600 sc_libs[ lib ] = true;
1603 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1605 /* stat cats based on Circ Lib */
1607 for (var i = 0; i < g.copies.length; i++) {
1608 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1609 sc_libs[ circ_lib ] = true;
1611 add_common_ancestors(sc_libs);
1613 /* stat cats based on Owning Lib */
1615 for (var i = 0; i < g.copies.length; i++) {
1616 var cn_id = g.copies[i].call_number();
1618 if (! g.map_acn[ cn_id ]) {
1619 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1620 if (typeof req.ilsevent == 'undefined') {
1621 g.map_acn[ cn_id ] = req;
1626 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1627 sc_libs[ owning_lib ] = true;
1630 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1632 g.panes_and_field_names.right_pane4.sort();
1636 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1640 g.check_for_unmet_required_fields = function() {
1642 for (var fn in g.required) {
1643 if (typeof g.populated[fn] == 'undefined') {
1647 if (xulG.unified_interface) {
1648 if (abort.length > 0) {
1649 if (typeof xulG.lock_save_button == 'function') {
1650 xulG.lock_save_button();
1653 if (typeof xulG.unlock_save_button == 'function') {
1654 xulG.unlock_save_button();
1658 if (abort.length > 0) {
1659 $('save').setAttribute('disabled','true');
1661 $('save').setAttribute('disabled','false');