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();
227 JSAN.use('util.hide');
228 util.hide.generate_css('ui.hide_copy_editor_fields');
231 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
232 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
237 /******************************************************************************************************/
238 /* Show copy notes button */
239 g.hide_copy_notes_button = function() {
240 if (g.copies.length > 0 && g.copies[0].id() < 0) {
241 document.getElementById('copy_notes').setAttribute('hidden','true');
242 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
243 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
245 if (g.copies.length != 1) {
246 document.getElementById('copy_notes').setAttribute('hidden','true');
250 /******************************************************************************************************/
251 /* Retrieve Templates */
253 g.retrieve_templates = function() {
255 JSAN.use('util.widgets'); JSAN.use('util.functional');
257 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
258 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
259 g.templates = robj['staff_client.copy_editor.templates'];
261 util.widgets.remove_children('template_placeholder');
262 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
264 g.template_menu = util.widgets.make_menulist( list );
265 g.template_menu.setAttribute('id','template_menu');
266 $('template_placeholder').appendChild(g.template_menu);
267 g.template_menu.addEventListener(
269 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
273 if (xulG.unified_interface) {
274 if (typeof xulG.update_unified_template_list == 'function') {
275 xulG.update_unified_template_list(list);
276 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
277 xulG.update_item_editor_template_selection = function(new_value) {
278 g.template_menu.setAttribute('value', new_value);
279 g.template_menu.value = new_value;
280 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
283 xulG.item_editor_apply_template = function() { g.apply_template(true); };
284 xulG.item_editor_delete_template = function() { g.delete_template(); };
285 xulG.item_editor_save_template = function() { g.save_template(); };
286 xulG.item_editor_import_templates = function() { g.import_templates(); };
287 xulG.item_editor_export_templates = function() { g.export_templates(); };
288 xulG.item_editor_reset = function() { g.reset(); };
293 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
297 /******************************************************************************************************/
300 g.applied_templates = [];
302 g.apply_template = function(apply_volume_editor_template_changes) {
304 var name = g.template_menu.value;
305 if (g.templates[ name ] != 'undefined') {
307 // We're only tracking these applied templates temporarily,
308 // specifically when they're used prior to copies being
309 // created in the unified interface.
310 g.applied_templates.push( name );
312 g._apply_template(name,apply_volume_editor_template_changes);
313 g.summarize( g.copies );
315 g.check_for_unmet_required_fields();
318 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
322 g._apply_template = function(name,apply_volume_editor_template_changes) {
324 if (g.templates[ name ] != 'undefined') {
325 var template = g.templates[ name ];
326 for (var i in template) {
327 g.changed[ i ] = template[ i ];
328 switch( template[i].type ) {
330 g.apply(template[i].field,template[i].value);
333 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
336 g.apply_owning_lib(template[i].value);
338 case 'volume_copy_creator' :
339 if (xulG.unified_interface && apply_volume_editor_template_changes) {
340 xulG.apply_template_to_batch(template[i].field,template[i].value);
347 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
351 /******************************************************************************************************/
352 /* Save as Template */
354 g.save_template = function() {
356 var name = window.prompt(
357 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
359 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
362 g.templates[name] = g.changed;
363 var robj = g.network.simple_request(
364 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
366 if (typeof robj.ilsevent != 'undefined') {
369 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
373 g.retrieve_templates();
375 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
381 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
385 /******************************************************************************************************/
386 /* Delete Template */
388 g.delete_template = function() {
390 var name = g.template_menu.value;
392 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
393 delete(g.templates[name]);
394 var robj = g.network.simple_request(
395 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
397 if (typeof robj.ilsevent != 'undefined') {
400 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
404 g.retrieve_templates();
406 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
412 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
416 /******************************************************************************************************/
417 /* Export Templates */
419 g.export_templates = function() {
421 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
422 JSAN.use('util.file'); var f = new util.file('');
423 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
425 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
429 /******************************************************************************************************/
430 /* Import Templates */
432 g.import_templates = function() {
434 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
435 JSAN.use('util.file'); var f = new util.file('');
436 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
438 for (var i in temp) {
440 if (g.templates[i]) {
442 var r = g.error.yns_alert(
443 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
444 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
445 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
446 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
448 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
451 if (r == 0 /* Yes */) g.templates[i] = temp[i];
455 g.templates[i] = temp[i];
461 var r = g.error.yns_alert(
462 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
463 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
464 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
465 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
467 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
470 if (r == 0 /* Yes */) {
471 var robj = g.network.simple_request(
472 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
474 if (typeof robj.ilsevent != 'undefined') {
477 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
481 g.retrieve_templates();
483 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
489 util.widgets.remove_children('template_placeholder');
490 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
491 g.template_menu = util.widgets.make_menulist( list );
492 $('template_placeholder').appendChild(g.template_menu);
493 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
498 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
503 /******************************************************************************************************/
504 /* Restore backup copies */
506 g.reset = function() {
507 g.applied_templates = [];
509 g.copies = JSON2js( g.original_copies );
510 g.summarize( g.copies );
512 g.check_for_unmet_required_fields();
514 if (xulG.unified_interface) {
515 xulG.reset_batch_menus();
519 /******************************************************************************************************/
520 /* Apply a value to a specific field on all the copies being edited */
522 g.apply = function(field,value) {
523 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
524 if (value == '<HACK:KLUDGE:NULL>') {
527 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
528 if (field == 'price' || field == 'deposit_amount') {
532 JSAN.use('util.money'); value = util.money.sanitize( value );
535 for (var i = 0; i < g.copies.length; i++) {
536 var copy = g.copies[i];
538 copy[field]( value ); copy.ischanged('1');
547 /******************************************************************************************************/
548 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
550 g.apply_stat_cat = function(sc_id,entry_id) {
551 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
552 for (var i = 0; i < g.copies.length; i++) {
553 var copy = g.copies[i];
556 var temp = copy.stat_cat_entries();
557 if (!temp) temp = [];
558 temp = util.functional.filter_list(
561 return (obj.stat_cat() != sc_id);
566 util.functional.find_id_object_in_list(
567 g.data.hash.asc[sc_id].entries(),
572 copy.stat_cat_entries( temp );
575 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
582 /******************************************************************************************************/
583 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
585 g.apply_owning_lib = function(ou_id) {
586 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
587 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
588 if (! g.safe_to_change_owning_lib() ) { return; }
589 for (var i = 0; i < g.copies.length; i++) {
590 var copy = g.copies[i];
592 if (!g.map_acn[copy.call_number()]) {
593 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
594 if (typeof volume.ilsevent != 'undefined') {
595 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
598 g.map_acn[copy.call_number()] = volume;
600 var old_volume = g.map_acn[copy.call_number()];
601 var acn_blob = g.network.simple_request(
602 'FM_ACN_FIND_OR_CREATE',
603 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
605 if (typeof acn_blob.ilsevent != 'undefined') {
606 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
609 copy.call_number(acn_blob.acn_id);
612 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
619 /******************************************************************************************************/
620 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
622 g.safe_to_change_owning_lib = function() {
624 if (xulG.unified_interface) { return false; }
626 for (var i = 0; i < g.copies.length; i++) {
627 var cn = g.copies[i].call_number();
628 if (typeof cn == 'object') { cn = cn.id(); }
629 if (cn == -1) { safe = false; }
633 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
638 /******************************************************************************************************/
639 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
641 g.safe_to_edit_copy_status = function() {
644 for (var i = 0; i < g.copies.length; i++) {
645 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
646 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
650 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
655 /******************************************************************************************************/
656 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
658 g.populate_alert_message_input = function(tb) {
660 var seen = {}; var s = '';
661 for (var i = 0; i < g.copies.length; i++) {
662 var msg = g.copies[i].alert_message();
664 if (typeof seen[msg] == 'undefined') {
670 tb.setAttribute('value',s);
672 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
676 /***************************************************************************************************************/
677 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
679 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
680 g.data.stash_retrieve();
681 var label = 'acpl_list_for_lib_'+lib_id;
682 if (typeof g.data[label] == 'undefined') {
683 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
684 if (typeof robj.ilsevent != 'undefined') throw(robj);
686 for (var j = 0; j < robj.length; j++) {
687 var my_acpl = robj[j];
688 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
689 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
690 g.data.list.acpl.push( my_acpl );
692 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
693 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
694 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
695 temp_list.push( my_acpl );
698 g.data[label] = temp_list; g.data.stash(label,'hash','list');
700 return g.data[label];
703 /******************************************************************************************************/
704 /* This returns a list of acpl's appropriate for the copies being edited */
706 g.get_acpl_list = function() {
709 JSAN.use('util.functional');
713 /**************************************/
714 /* get owning libs from call numbers */
716 var owning_libs = {};
717 for (var i = 0; i < g.copies.length; i++) {
718 var callnumber = g.copies[i].call_number();
719 if (!callnumber) continue;
720 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
722 if (! g.map_acn[ cn_id ]) {
723 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
724 if (typeof req.ilsevent == 'undefined') {
725 g.map_acn[ cn_id ] = req;
730 var consider_lib = g.map_acn[ cn_id ].owning_lib();
731 if (!consider_lib) continue;
732 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
736 for (var i in g.callnumbers) {
737 var consider_lib = g.callnumbers[i].owning_lib;
738 if (!consider_lib) continue;
739 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
743 /***************************************************************************************************/
744 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
746 JSAN.use('util.fm_utils');
747 var libs = []; for (var i in owning_libs) libs.push(i);
748 if (libs.length > 0) {
749 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
750 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
753 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
754 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
755 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
756 if (acpl_list[i] != null) {
757 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
768 for (var i = 0; i < g.copies.length; i++) {
769 var consider_lib = g.copies[i].circ_lib();
770 if (!consider_lib) continue;
771 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
774 /***************************************************************************************************/
775 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
777 libs = []; for (var i in circ_libs) libs.push(i);
778 if (libs.length > 0) {
779 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
780 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
783 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
784 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
785 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
786 if (acpl_list[i] != null) {
787 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
793 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
794 return acpl_list.sort(
796 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
797 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
798 if (label_a < label_b) return -1;
799 if (label_a > label_b) return 1;
805 g.error.standard_unexpected_error_alert('get_acpl_list',E);
811 /******************************************************************************************************/
812 /* This keeps track of which fields have been edited for styling purposes */
816 /******************************************************************************************************/
817 /* This keeps track of which fields are required, and which fields have been populated */
822 /******************************************************************************************************/
823 /* These need data from the middle layer to render */
825 function init_panes0() {
826 g.special_exception = {};
827 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
828 JSAN.use('util.widgets');
829 if (value>0) { /* an existing call number */
830 g.network.simple_request(
831 'FM_ACN_RETRIEVE.authoritative',
834 var cn = '??? id = ' + value;
836 cn = req.getResultObject();
838 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
840 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
843 } else { /* a yet to be created call number */
845 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
849 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
850 if (!Number(value)) return;
851 g.network.simple_request(
852 'FM_AU_RETRIEVE_VIA_ID',
855 var p = '??? id = ' + value;
857 p = req.getResultObject();
861 g.error.sdump('D_ERROR','patron retrieve: ' + E);
863 JSAN.use('util.widgets');
864 util.widgets.set_text(label,p);
868 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
869 if (!Number(value)) return;
870 g.network.simple_request(
871 'FM_AU_RETRIEVE_VIA_ID',
874 var p = '??? id = ' + value;
876 p = req.getResultObject();
880 g.error.sdump('D_ERROR','patron retrieve: ' + E);
882 util.widgets.set_text(label,p);
888 /******************************************************************************************************/
889 g.readonly_stat_cat_names = [];
890 g.editable_stat_cat_names = [];
892 /******************************************************************************************************/
893 /* These get show in the left panel */
895 function init_panes() {
896 g.panes_and_field_names = {
901 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
903 render: 'fm.barcode();',
907 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
909 render: 'util.date.formatted_date( fm.create_date(), "%F");',
913 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
915 render: 'util.date.formatted_date( fm.active_date(), "%F");',
919 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
921 render: 'fm.creator();',
925 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
927 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
931 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
933 render: 'fm.editor();',
942 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
944 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
945 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);',
950 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
952 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
953 //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);',
954 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);',
958 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
960 render: 'fm.call_number();',
961 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,
965 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
967 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
968 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);',
978 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
980 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") )',
981 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);',
985 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
987 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") )',
988 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);',
992 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
994 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() )',
995 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);',
1000 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
1002 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") )',
1003 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);',
1007 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1009 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; }',
1010 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);',
1015 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1017 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; }',
1018 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);',
1023 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1025 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',
1026 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);',
1030 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1032 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()])',
1033 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);',
1040 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1042 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1043 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);',
1048 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1050 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") )',
1051 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);',
1055 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1057 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1058 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);',
1062 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1064 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1065 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);',
1070 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1072 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") )',
1073 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);',
1077 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1079 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") )',
1080 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);',
1084 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1086 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")',
1087 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);',
1099 /******************************************************************************************************/
1100 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1102 g.summarize = function( copies ) {
1103 /******************************************************************************************************/
1106 JSAN.use('util.date'); JSAN.use('util.money');
1109 for (var i in g.panes_and_field_names) {
1110 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1112 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1113 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1115 /******************************************************************************************************/
1116 /* Loop through the field names */
1118 for (var i = 0; i < g.field_names.length; i++) {
1120 var field_name = g.field_names[i][0];
1121 var render = g.field_names[i][1].render;
1122 var attr = g.field_names[i][1].attr;
1123 g.summary[ field_name ] = {};
1124 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1126 /******************************************************************************************************/
1127 /* Loop through the copies */
1129 for (var j = 0; j < copies.length; j++) {
1132 var cmd = render || ('fm.' + field_name + '();');
1133 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1135 /**********************************************************************************************/
1136 /* Try to retrieve the value for this field for this copy */
1139 value = eval( cmd );
1141 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1143 if (typeof value == 'object' && value != null) {
1144 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1146 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1147 delete g.populated[field_name];
1150 /**********************************************************************************************/
1151 /* Tally the count */
1153 if (g.summary[ field_name ][ value ]) {
1154 g.summary[ field_name ][ value ]++;
1156 g.summary[ field_name ][ value ] = 1;
1160 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1163 /******************************************************************************************************/
1164 /* Display the summarized data and inputs for editing */
1166 g.render = function() {
1168 /******************************************************************************************************/
1169 /* Library setup and clear any existing interface */
1171 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1173 for (var i in g.panes_and_field_names) {
1174 var p = document.getElementById(i);
1175 if (p) util.widgets.remove_children(p);
1178 /******************************************************************************************************/
1179 /* Populate the library filter menu for stat cats */
1182 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1183 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1186 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1188 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1189 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1190 for (var i = 0; i < sc_libs2.length; i++) {
1191 var menuitem = document.createElement('menuitem');
1192 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1193 menuitem.setAttribute('type','checkbox');
1194 menuitem.setAttribute('checked','true');
1195 menuitem.setAttribute('label',sc_libs2[i][0]);
1196 menuitem.setAttribute('value',sc_libs2[i][1]);
1197 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1198 x.appendChild(menuitem);
1201 /******************************************************************************************************/
1202 /* Prepare the panes */
1204 var groupbox; var caption; var vbox; var grid; var rows;
1206 /******************************************************************************************************/
1207 /* Loop through the field names */
1209 for (h in g.panes_and_field_names) {
1210 if (!document.getElementById(h)) continue;
1211 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1213 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1214 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1215 groupbox.setAttribute('hideable',fn);
1217 for (var a in attr) {
1218 groupbox.setAttribute(a,attr[a]);
1221 caption = document.createElement('caption'); groupbox.appendChild(caption);
1222 caption.setAttribute('label',fn);
1223 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1224 caption.setAttribute('hideable',fn);
1225 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1226 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1227 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1228 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1229 grid.setAttribute('flex','1');
1230 rows = grid.lastChild;
1233 /**************************************************************************************/
1234 /* Loop through each value for the field */
1236 for (var j in g.summary[fn]) {
1237 var value = j; var count = g.summary[fn][j];
1238 row = document.createElement('row'); rows.appendChild(row);
1239 var label1 = document.createElement('description'); row.appendChild(label1);
1240 if (g.special_exception[ fn ]) {
1241 g.special_exception[ fn ]( label1, value );
1243 label1.appendChild( document.createTextNode(value) );
1245 var label2 = document.createElement('description'); row.appendChild(label2);
1248 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1250 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1252 label2.appendChild( document.createTextNode(copy_count) );
1254 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1255 var hbox = document.createElement('hbox'); // main input controls go here
1256 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1257 groupbox.appendChild(hbox);
1258 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1259 groupbox.appendChild(hbox2);
1261 /**************************************************************************************/
1262 /* Render the input widget */
1264 if (f[1].input && g.edit) {
1265 g.render_input(hbox,f[1]);
1269 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1275 /******************************************************************************************************/
1276 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1277 JSAN.use('util.file');
1278 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1279 g.copy_editor_prefs = util.widgets.load_attributes(file);
1280 for (var i in g.copy_editor_prefs) {
1281 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1283 g.toggle_stat_cat_display( document.getElementById(i) );
1284 } catch(E) { alert(E); }
1287 if (g.template_menu) {
1288 g.template_menu.value = g.template_menu.getAttribute('value');
1289 if (xulG.unified_interface) {
1290 if (typeof xulG.update_unified_template_selection == 'function') {
1291 xulG.update_unified_template_selection(g.template_menu.value);
1298 /******************************************************************************************************/
1299 /* This actually draws the change button and input widget for a given field */
1300 g.render_input = function(node,blob) {
1302 // node = hbox ; groupbox -> hbox, hbox
1304 var groupbox = node.parentNode;
1305 var caption = groupbox.firstChild;
1306 var vbox = node.previousSibling;
1308 var hbox2 = node.nextSibling;
1310 var input_cmd = blob.input;
1311 var render_cmd = blob.render;
1312 var attr = blob.attr;
1314 var block = false; var first = true;
1316 function on_mouseover(ev) {
1317 groupbox.setAttribute('style','background: white');
1320 function on_mouseout(ev) {
1321 groupbox.setAttribute('style','');
1324 vbox.addEventListener('mouseover',on_mouseover,false);
1325 vbox.addEventListener('mouseout',on_mouseout,false);
1326 groupbox.addEventListener('mouseover',on_mouseover,false);
1327 groupbox.addEventListener('mouseout',on_mouseout,false);
1328 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1329 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1331 function on_click(ev){
1333 if (block || g.disabled || !g.edit) {
1340 function post_c(v) {
1342 /* FIXME - kludgy */
1343 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1347 f = input_cmd.match(/apply\("(.+?)",/)[1];
1350 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1356 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1360 g.summarize( g.copies );
1362 g.check_for_unmet_required_fields();
1363 document.getElementById(caption.id).focus();
1367 g.error.standard_unexpected_error_alert('post_c',E);
1370 var x; var c; eval( input_cmd );
1372 util.widgets.remove_children(vbox);
1373 util.widgets.remove_children(hbox);
1374 util.widgets.remove_children(hbox2);
1375 hbox.appendChild(x);
1376 var apply = document.createElement('button');
1377 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1378 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1379 hbox2.appendChild(apply);
1380 apply.addEventListener('command',function() { c(x.value); },false);
1381 var cancel = document.createElement('button');
1382 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1383 cancel.addEventListener('command',function() {
1384 setTimeout( function() {
1385 g.summarize( g.copies );
1387 g.check_for_unmet_required_fields();
1388 document.getElementById(caption.id).focus();
1393 hbox2.appendChild(cancel);
1394 setTimeout( function() { x.focus(); }, 0 );
1397 g.error.standard_unexpected_error_alert('render_input',E);
1400 vbox.addEventListener('click',on_click, false);
1401 hbox.addEventListener('click',on_click, false);
1402 caption.addEventListener('click',on_click, false);
1403 caption.addEventListener('keypress',function(ev) {
1404 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1406 caption.setAttribute('style','-moz-user-focus: normal');
1407 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1408 caption.setAttribute('onblur','this.setAttribute("class","")');
1411 g.error.sdump('D_ERROR',E + '\n');
1415 /******************************************************************************************************/
1416 /* store the copies in the global xpcom stash */
1418 g.stash_and_close = function() {
1422 if (g.handle_update) {
1424 var r = g.network.request(
1425 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1426 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1427 [ ses(), g.copies, true ]
1429 if (typeof r.ilsevent != 'undefined') {
1430 g.error.standard_unexpected_error_alert('copy update',r);
1432 /* FIXME -- revisit the return value here */
1434 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1437 //g.data.temp_copies = js2JSON( g.copies );
1438 //g.data.stash('temp_copies');
1439 xulG.copies = g.copies;
1440 update_modal_xulG(xulG);
1441 JSAN.use('util.widgets');
1442 util.widgets.dispatch('close',window);
1444 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1448 /******************************************************************************************************/
1449 /* spawn copy notes interface */
1451 g.copy_notes = function() {
1452 JSAN.use('util.window'); var win = new util.window();
1454 urls.XUL_COPY_NOTES,
1455 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1456 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1457 { 'copy_id' : g.copies[0].id() }
1461 /******************************************************************************************************/
1462 /* hides or unhides stat cats based on library stat cat filter menu */
1463 g.toggle_stat_cat_display = function(el) {
1465 var visible = el.getAttribute('checked');
1466 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1467 for (var n = 0; n < nl.length; n++) {
1469 nl[n].setAttribute('hidden','false');
1471 nl[n].setAttribute('hidden','true');
1474 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1475 g.save_attributes();
1478 /******************************************************************************************************/
1479 /* This adds a stat cat definition to the stat cat pane for rendering */
1480 g.save_attributes = function() {
1481 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1482 var what_to_save = {};
1483 for (var i in g.copy_editor_prefs) {
1484 what_to_save[i] = [];
1485 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1487 util.widgets.save_attributes(file, what_to_save );
1490 /******************************************************************************************************/
1491 /* This adds a stat cat definition to the stat cat pane for rendering */
1492 g.add_stat_cat = function(sc) {
1494 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1498 if (typeof sc == 'object') {
1503 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1505 g.stat_cat_seen[ sc_id ] = 1;
1507 if (typeof sc != 'object') {
1509 sc = g.network.simple_request(
1510 'FM_ASC_BATCH_RETRIEVE',
1511 [ ses(), [ sc_id ] ]
1516 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1518 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1520 if (get_bool( sc.required() )) {
1521 g.required[ label_name ] = 1;
1527 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1528 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1529 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()
1530 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1531 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1538 g.panes_and_field_names.right_pane4.push( temp_array );
1540 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1544 /******************************************************************************************************/
1545 /* Add stat cats to the panes_and_field_names.right_pane4 */
1546 g.populate_stat_cats = function() {
1548 g.data.stash_retrieve();
1549 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1551 function get(lib_id,only_these) {
1552 g.data.stash_retrieve();
1553 var label = 'asc_list_for_lib_'+lib_id;
1554 if (typeof g.data[label] == 'undefined') {
1555 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1556 if (typeof robj.ilsevent != 'undefined') throw(robj);
1558 for (var j = 0; j < robj.length; j++) {
1559 var my_asc = robj[j];
1560 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1561 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1562 g.data.hash.asc[ my_asc.id() ] = my_asc;
1564 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1565 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1566 temp_list.push( my_asc );
1569 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1571 return g.data[label];
1574 /* The stat cats for the pertinent library -- this is based on workstation ou */
1575 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1576 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1577 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1578 g.add_stat_cat( g.data.list.my_asc[i] );
1581 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1582 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1584 function add_common_ancestors(sc_libs) {
1585 JSAN.use('util.fm_utils');
1586 var libs = []; for (var i in sc_libs) libs.push(i);
1587 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1588 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1590 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1591 var asc_list = get(ancestor, ancestors);
1592 for (var i = 0; i < asc_list.length; i++) {
1593 g.add_stat_cat( asc_list[i] );
1598 /* stat cats based on stat cat entries present on these copies */
1600 for (var i = 0; i < g.copies.length; i++) {
1601 var entries = g.copies[i].stat_cat_entries();
1602 if (!entries) entries = [];
1603 for (var j = 0; j < entries.length; j++) {
1604 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1605 sc_libs[ lib ] = true;
1608 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1610 /* stat cats based on Circ Lib */
1612 for (var i = 0; i < g.copies.length; i++) {
1613 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1614 sc_libs[ circ_lib ] = true;
1616 add_common_ancestors(sc_libs);
1618 /* stat cats based on Owning Lib */
1620 for (var i = 0; i < g.copies.length; i++) {
1621 var cn_id = g.copies[i].call_number();
1623 if (! g.map_acn[ cn_id ]) {
1624 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1625 if (typeof req.ilsevent == 'undefined') {
1626 g.map_acn[ cn_id ] = req;
1631 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1632 sc_libs[ owning_lib ] = true;
1635 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1637 g.panes_and_field_names.right_pane4.sort();
1641 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1645 g.check_for_unmet_required_fields = function() {
1647 for (var fn in g.required) {
1648 if (typeof g.populated[fn] == 'undefined') {
1652 if (xulG.unified_interface) {
1653 if (abort.length > 0) {
1654 if (typeof xulG.lock_save_button == 'function') {
1655 xulG.lock_save_button();
1658 if (typeof xulG.unlock_save_button == 'function') {
1659 xulG.unlock_save_button();
1663 if (abort.length > 0) {
1664 $('save').setAttribute('disabled','true');
1666 $('save').setAttribute('disabled','false');