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.value = new_value;
276 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
279 xulG.item_editor_apply_template = function() { g.apply_template(true); };
280 xulG.item_editor_delete_template = function() { g.delete_template(); };
281 xulG.item_editor_save_template = function() { g.save_template(); };
282 xulG.item_editor_import_templates = function() { g.import_templates(); };
283 xulG.item_editor_export_templates = function() { g.export_templates(); };
284 xulG.item_editor_reset = function() { g.reset(); };
289 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
293 /******************************************************************************************************/
296 g.applied_templates = [];
298 g.apply_template = function(apply_volume_editor_template_changes) {
300 var name = g.template_menu.value;
301 if (g.templates[ name ] != 'undefined') {
303 // We're only tracking these applied templates temporarily,
304 // specifically when they're used prior to copies being
305 // created in the unified interface.
306 g.applied_templates.push( name );
308 g._apply_template(name,apply_volume_editor_template_changes);
309 g.summarize( g.copies );
311 g.check_for_unmet_required_fields();
314 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
318 g._apply_template = function(name,apply_volume_editor_template_changes) {
320 if (g.templates[ name ] != 'undefined') {
321 var template = g.templates[ name ];
322 for (var i in template) {
323 g.changed[ i ] = template[ i ];
324 switch( template[i].type ) {
326 g.apply(template[i].field,template[i].value);
329 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
332 g.apply_owning_lib(template[i].value);
334 case 'volume_copy_creator' :
335 if (xulG.unified_interface && apply_volume_editor_template_changes) {
336 xulG.apply_template_to_batch(template[i].field,template[i].value);
343 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
347 /******************************************************************************************************/
348 /* Save as Template */
350 g.save_template = function() {
352 var name = window.prompt(
353 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
355 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
358 g.templates[name] = g.changed;
359 var robj = g.network.simple_request(
360 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
362 if (typeof robj.ilsevent != 'undefined') {
365 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
369 g.retrieve_templates();
371 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
377 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
381 /******************************************************************************************************/
382 /* Delete Template */
384 g.delete_template = function() {
386 var name = g.template_menu.value;
388 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
389 delete(g.templates[name]);
390 var robj = g.network.simple_request(
391 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
393 if (typeof robj.ilsevent != 'undefined') {
396 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
400 g.retrieve_templates();
402 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
408 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
412 /******************************************************************************************************/
413 /* Export Templates */
415 g.export_templates = function() {
417 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
418 JSAN.use('util.file'); var f = new util.file('');
419 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
421 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
425 /******************************************************************************************************/
426 /* Import Templates */
428 g.import_templates = function() {
430 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
431 JSAN.use('util.file'); var f = new util.file('');
432 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
434 for (var i in temp) {
436 if (g.templates[i]) {
438 var r = g.error.yns_alert(
439 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
440 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
441 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
442 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
444 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
447 if (r == 0 /* Yes */) g.templates[i] = temp[i];
451 g.templates[i] = temp[i];
457 var r = g.error.yns_alert(
458 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
459 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
460 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
461 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
463 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
466 if (r == 0 /* Yes */) {
467 var robj = g.network.simple_request(
468 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
470 if (typeof robj.ilsevent != 'undefined') {
473 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
477 g.retrieve_templates();
479 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
485 util.widgets.remove_children('template_placeholder');
486 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
487 g.template_menu = util.widgets.make_menulist( list );
488 $('template_placeholder').appendChild(g.template_menu);
489 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
494 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
499 /******************************************************************************************************/
500 /* Restore backup copies */
502 g.reset = function() {
503 g.applied_templates = [];
505 g.copies = JSON2js( g.original_copies );
506 g.summarize( g.copies );
508 g.check_for_unmet_required_fields();
510 if (xulG.unified_interface) {
511 xulG.reset_batch_menus();
515 /******************************************************************************************************/
516 /* Apply a value to a specific field on all the copies being edited */
518 g.apply = function(field,value) {
519 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
520 if (value == '<HACK:KLUDGE:NULL>') {
523 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
524 if (field == 'price' || field == 'deposit_amount') {
528 JSAN.use('util.money'); value = util.money.sanitize( value );
531 for (var i = 0; i < g.copies.length; i++) {
532 var copy = g.copies[i];
534 copy[field]( value ); copy.ischanged('1');
543 /******************************************************************************************************/
544 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
546 g.apply_stat_cat = function(sc_id,entry_id) {
547 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
548 for (var i = 0; i < g.copies.length; i++) {
549 var copy = g.copies[i];
552 var temp = copy.stat_cat_entries();
553 if (!temp) temp = [];
554 temp = util.functional.filter_list(
557 return (obj.stat_cat() != sc_id);
562 util.functional.find_id_object_in_list(
563 g.data.hash.asc[sc_id].entries(),
568 copy.stat_cat_entries( temp );
571 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
578 /******************************************************************************************************/
579 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
581 g.apply_owning_lib = function(ou_id) {
582 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
583 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
584 if (! g.safe_to_change_owning_lib() ) { return; }
585 for (var i = 0; i < g.copies.length; i++) {
586 var copy = g.copies[i];
588 if (!g.map_acn[copy.call_number()]) {
589 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
590 if (typeof volume.ilsevent != 'undefined') {
591 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
594 g.map_acn[copy.call_number()] = volume;
596 var old_volume = g.map_acn[copy.call_number()];
597 var acn_blob = g.network.simple_request(
598 'FM_ACN_FIND_OR_CREATE',
599 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
601 if (typeof acn_blob.ilsevent != 'undefined') {
602 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
605 copy.call_number(acn_blob.acn_id);
608 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
615 /******************************************************************************************************/
616 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
618 g.safe_to_change_owning_lib = function() {
620 if (xulG.unified_interface) { return false; }
622 for (var i = 0; i < g.copies.length; i++) {
623 var cn = g.copies[i].call_number();
624 if (typeof cn == 'object') { cn = cn.id(); }
625 if (cn == -1) { safe = false; }
629 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
634 /******************************************************************************************************/
635 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
637 g.safe_to_edit_copy_status = function() {
640 for (var i = 0; i < g.copies.length; i++) {
641 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
642 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
646 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
651 /******************************************************************************************************/
652 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
654 g.populate_alert_message_input = function(tb) {
656 var seen = {}; var s = '';
657 for (var i = 0; i < g.copies.length; i++) {
658 var msg = g.copies[i].alert_message();
660 if (typeof seen[msg] == 'undefined') {
666 tb.setAttribute('value',s);
668 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
672 /***************************************************************************************************************/
673 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
675 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
676 g.data.stash_retrieve();
677 var label = 'acpl_list_for_lib_'+lib_id;
678 if (typeof g.data[label] == 'undefined') {
679 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
680 if (typeof robj.ilsevent != 'undefined') throw(robj);
682 for (var j = 0; j < robj.length; j++) {
683 var my_acpl = robj[j];
684 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
685 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
686 g.data.list.acpl.push( my_acpl );
688 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
689 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
690 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
691 temp_list.push( my_acpl );
694 g.data[label] = temp_list; g.data.stash(label,'hash','list');
696 return g.data[label];
699 /******************************************************************************************************/
700 /* This returns a list of acpl's appropriate for the copies being edited */
702 g.get_acpl_list = function() {
705 JSAN.use('util.functional');
709 /**************************************/
710 /* get owning libs from call numbers */
712 var owning_libs = {};
713 for (var i = 0; i < g.copies.length; i++) {
714 var callnumber = g.copies[i].call_number();
715 if (!callnumber) continue;
716 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
718 if (! g.map_acn[ cn_id ]) {
719 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
720 if (typeof req.ilsevent == 'undefined') {
721 g.map_acn[ cn_id ] = req;
726 var consider_lib = g.map_acn[ cn_id ].owning_lib();
727 if (!consider_lib) continue;
728 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
732 for (var i in g.callnumbers) {
733 var consider_lib = g.callnumbers[i].owning_lib;
734 if (!consider_lib) continue;
735 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
739 /***************************************************************************************************/
740 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
742 JSAN.use('util.fm_utils');
743 var libs = []; for (var i in owning_libs) libs.push(i);
744 if (libs.length > 0) {
745 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
746 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
749 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
750 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
751 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
752 if (acpl_list[i] != null) {
753 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
764 for (var i = 0; i < g.copies.length; i++) {
765 var consider_lib = g.copies[i].circ_lib();
766 if (!consider_lib) continue;
767 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
770 /***************************************************************************************************/
771 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
773 libs = []; for (var i in circ_libs) libs.push(i);
774 if (libs.length > 0) {
775 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
776 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
779 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
780 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
781 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
782 if (acpl_list[i] != null) {
783 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
789 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
790 return acpl_list.sort(
792 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
793 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
794 if (label_a < label_b) return -1;
795 if (label_a > label_b) return 1;
801 g.error.standard_unexpected_error_alert('get_acpl_list',E);
807 /******************************************************************************************************/
808 /* This keeps track of which fields have been edited for styling purposes */
812 /******************************************************************************************************/
813 /* This keeps track of which fields are required, and which fields have been populated */
818 /******************************************************************************************************/
819 /* These need data from the middle layer to render */
821 function init_panes0() {
822 g.special_exception = {};
823 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
824 JSAN.use('util.widgets');
825 if (value>0) { /* an existing call number */
826 g.network.simple_request(
827 'FM_ACN_RETRIEVE.authoritative',
830 var cn = '??? id = ' + value;
832 cn = req.getResultObject();
834 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
836 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
839 } else { /* a yet to be created call number */
841 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
845 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
846 if (!Number(value)) return;
847 g.network.simple_request(
848 'FM_AU_RETRIEVE_VIA_ID',
851 var p = '??? id = ' + value;
853 p = req.getResultObject();
857 g.error.sdump('D_ERROR','patron retrieve: ' + E);
859 JSAN.use('util.widgets');
860 util.widgets.set_text(label,p);
864 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
865 if (!Number(value)) return;
866 g.network.simple_request(
867 'FM_AU_RETRIEVE_VIA_ID',
870 var p = '??? id = ' + value;
872 p = req.getResultObject();
876 g.error.sdump('D_ERROR','patron retrieve: ' + E);
878 util.widgets.set_text(label,p);
884 /******************************************************************************************************/
885 g.readonly_stat_cat_names = [];
886 g.editable_stat_cat_names = [];
888 /******************************************************************************************************/
889 /* These get show in the left panel */
891 function init_panes() {
892 g.panes_and_field_names = {
897 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
899 render: 'fm.barcode();',
903 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
905 render: 'util.date.formatted_date( fm.create_date(), "%F");',
909 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
911 render: 'util.date.formatted_date( fm.active_date(), "%F");',
915 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
917 render: 'fm.creator();',
921 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
923 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
927 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
929 render: 'fm.editor();',
938 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
940 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
941 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);',
946 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
948 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
949 //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);',
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( 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);',
954 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
956 render: 'fm.call_number();',
957 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,
961 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
963 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
964 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);',
974 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
976 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") )',
977 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);',
981 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
983 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") )',
984 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);',
988 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
990 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() )',
991 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);',
996 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
998 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") )',
999 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);',
1003 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1005 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; }',
1006 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);',
1011 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1013 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; }',
1014 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);',
1019 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1021 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',
1022 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);',
1026 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1028 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()])',
1029 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);',
1036 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1038 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1039 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);',
1044 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1046 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") )',
1047 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);',
1051 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1053 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1054 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);',
1058 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1060 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1061 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);',
1066 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1068 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") )',
1069 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);',
1073 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1075 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") )',
1076 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);',
1080 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1082 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")',
1083 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);',
1095 /******************************************************************************************************/
1096 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1098 g.summarize = function( copies ) {
1099 /******************************************************************************************************/
1102 JSAN.use('util.date'); JSAN.use('util.money');
1105 for (var i in g.panes_and_field_names) {
1106 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1108 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1109 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1111 /******************************************************************************************************/
1112 /* Loop through the field names */
1114 for (var i = 0; i < g.field_names.length; i++) {
1116 var field_name = g.field_names[i][0];
1117 var render = g.field_names[i][1].render;
1118 var attr = g.field_names[i][1].attr;
1119 g.summary[ field_name ] = {};
1120 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1122 /******************************************************************************************************/
1123 /* Loop through the copies */
1125 for (var j = 0; j < copies.length; j++) {
1128 var cmd = render || ('fm.' + field_name + '();');
1129 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1131 /**********************************************************************************************/
1132 /* Try to retrieve the value for this field for this copy */
1135 value = eval( cmd );
1137 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1139 if (typeof value == 'object' && value != null) {
1140 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1142 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1143 delete g.populated[field_name];
1146 /**********************************************************************************************/
1147 /* Tally the count */
1149 if (g.summary[ field_name ][ value ]) {
1150 g.summary[ field_name ][ value ]++;
1152 g.summary[ field_name ][ value ] = 1;
1156 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1159 /******************************************************************************************************/
1160 /* Display the summarized data and inputs for editing */
1162 g.render = function() {
1164 /******************************************************************************************************/
1165 /* Library setup and clear any existing interface */
1167 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1169 for (var i in g.panes_and_field_names) {
1170 var p = document.getElementById(i);
1171 if (p) util.widgets.remove_children(p);
1174 /******************************************************************************************************/
1175 /* Populate the library filter menu for stat cats */
1178 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1179 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1182 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1184 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1185 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1186 for (var i = 0; i < sc_libs2.length; i++) {
1187 var menuitem = document.createElement('menuitem');
1188 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1189 menuitem.setAttribute('type','checkbox');
1190 menuitem.setAttribute('checked','true');
1191 menuitem.setAttribute('label',sc_libs2[i][0]);
1192 menuitem.setAttribute('value',sc_libs2[i][1]);
1193 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1194 x.appendChild(menuitem);
1197 /******************************************************************************************************/
1198 /* Prepare the panes */
1200 var groupbox; var caption; var vbox; var grid; var rows;
1202 /******************************************************************************************************/
1203 /* Loop through the field names */
1205 for (h in g.panes_and_field_names) {
1206 if (!document.getElementById(h)) continue;
1207 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1209 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1210 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1212 for (var a in attr) {
1213 groupbox.setAttribute(a,attr[a]);
1216 caption = document.createElement('caption'); groupbox.appendChild(caption);
1217 caption.setAttribute('label',fn);
1218 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1219 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1220 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1221 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1222 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1223 grid.setAttribute('flex','1');
1224 rows = grid.lastChild;
1227 /**************************************************************************************/
1228 /* Loop through each value for the field */
1230 for (var j in g.summary[fn]) {
1231 var value = j; var count = g.summary[fn][j];
1232 row = document.createElement('row'); rows.appendChild(row);
1233 var label1 = document.createElement('description'); row.appendChild(label1);
1234 if (g.special_exception[ fn ]) {
1235 g.special_exception[ fn ]( label1, value );
1237 label1.appendChild( document.createTextNode(value) );
1239 var label2 = document.createElement('description'); row.appendChild(label2);
1242 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1244 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1246 label2.appendChild( document.createTextNode(copy_count) );
1248 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1249 var hbox = document.createElement('hbox'); // main input controls go here
1250 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1251 groupbox.appendChild(hbox);
1252 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1253 groupbox.appendChild(hbox2);
1255 /**************************************************************************************/
1256 /* Render the input widget */
1258 if (f[1].input && g.edit) {
1259 g.render_input(hbox,f[1]);
1263 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1269 /******************************************************************************************************/
1270 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1271 JSAN.use('util.file');
1272 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1273 g.copy_editor_prefs = util.widgets.load_attributes(file);
1274 for (var i in g.copy_editor_prefs) {
1275 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1277 g.toggle_stat_cat_display( document.getElementById(i) );
1278 } catch(E) { alert(E); }
1281 if (g.template_menu) g.template_menu.value = g.template_menu.getAttribute('value');
1285 /******************************************************************************************************/
1286 /* This actually draws the change button and input widget for a given field */
1287 g.render_input = function(node,blob) {
1289 // node = hbox ; groupbox -> hbox, hbox
1291 var groupbox = node.parentNode;
1292 var caption = groupbox.firstChild;
1293 var vbox = node.previousSibling;
1295 var hbox2 = node.nextSibling;
1297 var input_cmd = blob.input;
1298 var render_cmd = blob.render;
1299 var attr = blob.attr;
1301 var block = false; var first = true;
1303 function on_mouseover(ev) {
1304 groupbox.setAttribute('style','background: white');
1307 function on_mouseout(ev) {
1308 groupbox.setAttribute('style','');
1311 vbox.addEventListener('mouseover',on_mouseover,false);
1312 vbox.addEventListener('mouseout',on_mouseout,false);
1313 groupbox.addEventListener('mouseover',on_mouseover,false);
1314 groupbox.addEventListener('mouseout',on_mouseout,false);
1315 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1316 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1318 function on_click(ev){
1320 if (block || g.disabled || !g.edit) {
1327 function post_c(v) {
1329 /* FIXME - kludgy */
1330 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1334 f = input_cmd.match(/apply\("(.+?)",/)[1];
1337 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1343 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1347 g.summarize( g.copies );
1349 g.check_for_unmet_required_fields();
1350 document.getElementById(caption.id).focus();
1354 g.error.standard_unexpected_error_alert('post_c',E);
1357 var x; var c; eval( input_cmd );
1359 util.widgets.remove_children(vbox);
1360 util.widgets.remove_children(hbox);
1361 util.widgets.remove_children(hbox2);
1362 hbox.appendChild(x);
1363 var apply = document.createElement('button');
1364 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1365 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1366 hbox2.appendChild(apply);
1367 apply.addEventListener('command',function() { c(x.value); },false);
1368 var cancel = document.createElement('button');
1369 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1370 cancel.addEventListener('command',function() {
1371 setTimeout( function() {
1372 g.summarize( g.copies );
1374 g.check_for_unmet_required_fields();
1375 document.getElementById(caption.id).focus();
1380 hbox2.appendChild(cancel);
1381 setTimeout( function() { x.focus(); }, 0 );
1384 g.error.standard_unexpected_error_alert('render_input',E);
1387 vbox.addEventListener('click',on_click, false);
1388 hbox.addEventListener('click',on_click, false);
1389 caption.addEventListener('click',on_click, false);
1390 caption.addEventListener('keypress',function(ev) {
1391 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1393 caption.setAttribute('style','-moz-user-focus: normal');
1394 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1395 caption.setAttribute('onblur','this.setAttribute("class","")');
1398 g.error.sdump('D_ERROR',E + '\n');
1402 /******************************************************************************************************/
1403 /* store the copies in the global xpcom stash */
1405 g.stash_and_close = function() {
1409 if (g.handle_update) {
1411 var r = g.network.request(
1412 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1413 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1414 [ ses(), g.copies, true ]
1416 if (typeof r.ilsevent != 'undefined') {
1417 g.error.standard_unexpected_error_alert('copy update',r);
1419 /* FIXME -- revisit the return value here */
1421 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1424 //g.data.temp_copies = js2JSON( g.copies );
1425 //g.data.stash('temp_copies');
1426 xulG.copies = g.copies;
1427 update_modal_xulG(xulG);
1428 JSAN.use('util.widgets');
1429 util.widgets.dispatch('close',window);
1431 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1435 /******************************************************************************************************/
1436 /* spawn copy notes interface */
1438 g.copy_notes = function() {
1439 JSAN.use('util.window'); var win = new util.window();
1441 urls.XUL_COPY_NOTES,
1442 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1443 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1444 { 'copy_id' : g.copies[0].id() }
1448 /******************************************************************************************************/
1449 /* hides or unhides stat cats based on library stat cat filter menu */
1450 g.toggle_stat_cat_display = function(el) {
1452 var visible = el.getAttribute('checked');
1453 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1454 for (var n = 0; n < nl.length; n++) {
1456 nl[n].setAttribute('hidden','false');
1458 nl[n].setAttribute('hidden','true');
1461 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1462 g.save_attributes();
1465 /******************************************************************************************************/
1466 /* This adds a stat cat definition to the stat cat pane for rendering */
1467 g.save_attributes = function() {
1468 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1469 var what_to_save = {};
1470 for (var i in g.copy_editor_prefs) {
1471 what_to_save[i] = [];
1472 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1474 util.widgets.save_attributes(file, what_to_save );
1477 /******************************************************************************************************/
1478 /* This adds a stat cat definition to the stat cat pane for rendering */
1479 g.add_stat_cat = function(sc) {
1481 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1485 if (typeof sc == 'object') {
1490 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1492 g.stat_cat_seen[ sc_id ] = 1;
1494 if (typeof sc != 'object') {
1496 sc = g.network.simple_request(
1497 'FM_ASC_BATCH_RETRIEVE',
1498 [ ses(), [ sc_id ] ]
1503 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1505 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1507 if (get_bool( sc.required() )) {
1508 g.required[ label_name ] = 1;
1514 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1515 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1516 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()
1517 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1518 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1525 g.panes_and_field_names.right_pane4.push( temp_array );
1527 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1531 /******************************************************************************************************/
1532 /* Add stat cats to the panes_and_field_names.right_pane4 */
1533 g.populate_stat_cats = function() {
1535 g.data.stash_retrieve();
1536 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1538 function get(lib_id,only_these) {
1539 g.data.stash_retrieve();
1540 var label = 'asc_list_for_lib_'+lib_id;
1541 if (typeof g.data[label] == 'undefined') {
1542 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1543 if (typeof robj.ilsevent != 'undefined') throw(robj);
1545 for (var j = 0; j < robj.length; j++) {
1546 var my_asc = robj[j];
1547 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1548 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1549 g.data.hash.asc[ my_asc.id() ] = my_asc;
1551 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1552 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1553 temp_list.push( my_asc );
1556 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1558 return g.data[label];
1561 /* The stat cats for the pertinent library -- this is based on workstation ou */
1562 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1563 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1564 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1565 g.add_stat_cat( g.data.list.my_asc[i] );
1568 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1569 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1571 function add_common_ancestors(sc_libs) {
1572 JSAN.use('util.fm_utils');
1573 var libs = []; for (var i in sc_libs) libs.push(i);
1574 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1575 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1577 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1578 var asc_list = get(ancestor, ancestors);
1579 for (var i = 0; i < asc_list.length; i++) {
1580 g.add_stat_cat( asc_list[i] );
1585 /* stat cats based on stat cat entries present on these copies */
1587 for (var i = 0; i < g.copies.length; i++) {
1588 var entries = g.copies[i].stat_cat_entries();
1589 if (!entries) entries = [];
1590 for (var j = 0; j < entries.length; j++) {
1591 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1592 sc_libs[ lib ] = true;
1595 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1597 /* stat cats based on Circ Lib */
1599 for (var i = 0; i < g.copies.length; i++) {
1600 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1601 sc_libs[ circ_lib ] = true;
1603 add_common_ancestors(sc_libs);
1605 /* stat cats based on Owning Lib */
1607 for (var i = 0; i < g.copies.length; i++) {
1608 var cn_id = g.copies[i].call_number();
1610 if (! g.map_acn[ cn_id ]) {
1611 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1612 if (typeof req.ilsevent == 'undefined') {
1613 g.map_acn[ cn_id ] = req;
1618 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1619 sc_libs[ owning_lib ] = true;
1622 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1624 g.panes_and_field_names.right_pane4.sort();
1628 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1632 g.check_for_unmet_required_fields = function() {
1634 for (var fn in g.required) {
1635 if (typeof g.populated[fn] == 'undefined') {
1639 if (xulG.unified_interface) {
1640 if (abort.length > 0) {
1641 if (typeof xulG.lock_save_button == 'function') {
1642 xulG.lock_save_button();
1645 if (typeof xulG.unlock_save_button == 'function') {
1646 xulG.unlock_save_button();
1650 if (abort.length > 0) {
1651 $('save').setAttribute('disabled','true');
1653 $('save').setAttribute('disabled','false');