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});
56 /******************************************************************************************************/
57 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
58 /* Quick fix, messagecatalog only usable during/after onload */
63 /******************************************************************************************************/
64 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
66 if (xul_param('edit',{'modal_xulG':true}) == '1') {
70 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
72 // Editor desired, but let's check permissions
75 var check = g.network.simple_request(
76 'PERM_MULTI_ORG_CHECK',
79 g.data.list.au[0].id(),
80 util.functional.map_list(
84 var cn_id = o.call_number();
86 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
88 if (! g.map_acn[ cn_id ]) {
89 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
90 if (typeof req.ilsevent == 'undefined') {
91 g.map_acn[ cn_id ] = req;
92 lib = g.map_acn[ cn_id ].owning_lib();
97 lib = g.map_acn[ cn_id ].owning_lib();
100 return typeof lib == 'object' ? lib.id() : lib;
103 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
106 g.edit = check.length == 0;
108 g.error.standard_unexpected_error_alert('batch permission check',E);
114 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
115 $('save').setAttribute('hidden','false');
117 $('top_nav').setAttribute('hidden','true');
120 g.retrieve_templates();
123 $('top_nav').setAttribute('hidden','true');
126 g.panes_and_field_names.left_pane =
129 $('catStrings').getString('staff.cat.copy_editor.status'),
131 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
132 input: g.safe_to_edit_copy_status() ? 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.ccs, function(obj) { return [ obj.name(), obj.id(), typeof my_constants.magical_statuses[obj.id()] != "undefined" ? true : false ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);' : undefined,
133 //input: 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( util.functional.filter_list( g.data.list.ccs, function(obj) { return typeof my_constants.magical_statuses[obj.id()] == "undefined"; } ), function(obj) { return [ obj.name(), obj.id() ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
136 ].concat(g.panes_and_field_names.left_pane);
139 /******************************************************************************************************/
140 /* Show the Record Details? */
142 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
144 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
145 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
146 brief_display.setAttribute( 'flex','1' );
149 /******************************************************************************************************/
150 /* Add stat cats to the panes_and_field_names.right_pane4 */
152 g.populate_stat_cats();
154 /******************************************************************************************************/
155 /* Backup copies :) */
157 g.original_copies = js2JSON( g.copies );
159 /******************************************************************************************************/
162 g.summarize( g.copies );
164 g.check_for_unmet_required_fields();
166 if (xulG.unified_interface) {
167 xulG.disable_copy_editor = function(c) {
168 addCSSClass(document.documentElement,'red_bg');
171 xulG.enable_copy_editor = function(c) {
172 removeCSSClass(document.documentElement,'red_bg');
174 xulG.refresh_copy_editor();
176 xulG.refresh_copy_editor = function() {
177 dump('refresh_copy_editor\n');
178 addCSSClass(document.documentElement,'blue_bg');
180 xulG.clear_update_copy_editor_timeout();
181 g.copies = xulG.copies;
182 g.edit = g.copies.length > 0;
184 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
186 g.original_copies = js2JSON( g.copies );
187 g.hide_copy_notes_button();
188 for (var i = 0; i < g.applied_templates.length; i++) {
189 g._apply_template( g.applied_templates[i], false);
191 g.summarize( g.copies );
193 g.check_for_unmet_required_fields();
196 removeCSSClass(document.documentElement,'blue_bg');
200 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
203 xulG.unlock_copy_editor = function() {
206 xulG.notify_of_templatable_field_change = function(id,v) {
207 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
210 g.hide_copy_notes_button();
214 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
215 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
220 /******************************************************************************************************/
221 /* Show copy notes button */
222 g.hide_copy_notes_button = function() {
223 if (g.copies.length > 0 && g.copies[0].id() < 0) {
224 document.getElementById('copy_notes').setAttribute('hidden','true');
225 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
226 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
228 if (g.copies.length != 1) {
229 document.getElementById('copy_notes').setAttribute('hidden','true');
233 /******************************************************************************************************/
234 /* Retrieve Templates */
236 g.retrieve_templates = function() {
238 JSAN.use('util.widgets'); JSAN.use('util.functional');
240 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
241 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
242 g.templates = robj['staff_client.copy_editor.templates'];
244 util.widgets.remove_children('template_placeholder');
245 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
247 g.template_menu = util.widgets.make_menulist( list );
248 g.template_menu.setAttribute('id','template_menu');
249 $('template_placeholder').appendChild(g.template_menu);
250 g.template_menu.addEventListener(
252 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
256 if (xulG.unified_interface) {
257 if (typeof xulG.update_unified_template_list == 'function') {
258 xulG.update_unified_template_list(list);
259 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
260 xulG.update_item_editor_template_selection = function(new_value) {
261 g.template_menu.value = new_value;
262 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
265 xulG.item_editor_apply_template = function() { g.apply_template(true); };
266 xulG.item_editor_delete_template = function() { g.delete_template(); };
267 xulG.item_editor_save_template = function() { g.save_template(); };
268 xulG.item_editor_import_templates = function() { g.import_templates(); };
269 xulG.item_editor_export_templates = function() { g.export_templates(); };
270 xulG.item_editor_reset = function() { g.reset(); };
275 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
279 /******************************************************************************************************/
282 g.applied_templates = [];
284 g.apply_template = function(apply_volume_editor_template_changes) {
286 var name = g.template_menu.value;
287 if (g.templates[ name ] != 'undefined') {
288 g.applied_templates.push( name );
289 g._apply_template(name,apply_volume_editor_template_changes);
290 g.summarize( g.copies );
292 g.check_for_unmet_required_fields();
295 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
299 g._apply_template = function(name,apply_volume_editor_template_changes) {
301 if (g.templates[ name ] != 'undefined') {
302 var template = g.templates[ name ];
303 for (var i in template) {
304 g.changed[ i ] = template[ i ];
305 switch( template[i].type ) {
307 g.apply(template[i].field,template[i].value);
310 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
313 g.apply_owning_lib(template[i].value);
315 case 'volume_copy_creator' :
316 if (xulG.unified_interface && apply_volume_editor_template_changes) {
317 xulG.apply_template_to_batch(template[i].field,template[i].value);
324 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
328 /******************************************************************************************************/
329 /* Save as Template */
331 g.save_template = function() {
333 var name = window.prompt(
334 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
336 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
339 g.templates[name] = g.changed;
340 var robj = g.network.simple_request(
341 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
343 if (typeof robj.ilsevent != 'undefined') {
346 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
350 g.retrieve_templates();
352 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
358 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
362 /******************************************************************************************************/
363 /* Delete Template */
365 g.delete_template = function() {
367 var name = g.template_menu.value;
369 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
370 delete(g.templates[name]);
371 var robj = g.network.simple_request(
372 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
374 if (typeof robj.ilsevent != 'undefined') {
377 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
381 g.retrieve_templates();
383 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
389 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
393 /******************************************************************************************************/
394 /* Export Templates */
396 g.export_templates = function() {
398 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
399 JSAN.use('util.file'); var f = new util.file('');
400 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
402 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
406 /******************************************************************************************************/
407 /* Import Templates */
409 g.import_templates = function() {
411 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
412 JSAN.use('util.file'); var f = new util.file('');
413 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
415 for (var i in temp) {
417 if (g.templates[i]) {
419 var r = g.error.yns_alert(
420 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
421 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
422 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
423 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
425 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
428 if (r == 0 /* Yes */) g.templates[i] = temp[i];
432 g.templates[i] = temp[i];
438 var r = g.error.yns_alert(
439 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
440 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
441 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
442 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
444 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
447 if (r == 0 /* Yes */) {
448 var robj = g.network.simple_request(
449 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
451 if (typeof robj.ilsevent != 'undefined') {
454 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
458 g.retrieve_templates();
460 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
466 util.widgets.remove_children('template_placeholder');
467 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
468 g.template_menu = util.widgets.make_menulist( list );
469 $('template_placeholder').appendChild(g.template_menu);
470 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
475 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
480 /******************************************************************************************************/
481 /* Restore backup copies */
483 g.reset = function() {
484 g.applied_templates = [];
486 g.copies = JSON2js( g.original_copies );
487 g.summarize( g.copies );
489 g.check_for_unmet_required_fields();
491 if (xulG.unified_interface) {
492 xulG.reset_batch_menus();
496 /******************************************************************************************************/
497 /* Apply a value to a specific field on all the copies being edited */
499 g.apply = function(field,value) {
500 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
501 if (value == '<HACK:KLUDGE:NULL>') {
504 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
505 if (field == 'price' || field == 'deposit_amount') {
509 JSAN.use('util.money'); value = util.money.sanitize( value );
512 for (var i = 0; i < g.copies.length; i++) {
513 var copy = g.copies[i];
515 copy[field]( value ); copy.ischanged('1');
524 /******************************************************************************************************/
525 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
527 g.apply_stat_cat = function(sc_id,entry_id) {
528 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
529 for (var i = 0; i < g.copies.length; i++) {
530 var copy = g.copies[i];
533 var temp = copy.stat_cat_entries();
534 if (!temp) temp = [];
535 temp = util.functional.filter_list(
538 return (obj.stat_cat() != sc_id);
543 util.functional.find_id_object_in_list(
544 g.data.hash.asc[sc_id].entries(),
549 copy.stat_cat_entries( temp );
552 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
559 /******************************************************************************************************/
560 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
562 g.apply_owning_lib = function(ou_id) {
563 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
564 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
565 if (! g.safe_to_change_owning_lib() ) { return; }
566 for (var i = 0; i < g.copies.length; i++) {
567 var copy = g.copies[i];
569 if (!g.map_acn[copy.call_number()]) {
570 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
571 if (typeof volume.ilsevent != 'undefined') {
572 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
575 g.map_acn[copy.call_number()] = volume;
577 var old_volume = g.map_acn[copy.call_number()];
578 var acn_blob = g.network.simple_request(
579 'FM_ACN_FIND_OR_CREATE',
580 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
582 if (typeof acn_blob.ilsevent != 'undefined') {
583 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
586 copy.call_number(acn_blob.acn_id);
589 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
596 /******************************************************************************************************/
597 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
599 g.safe_to_change_owning_lib = function() {
601 if (xulG.unified_interface) { return false; }
603 for (var i = 0; i < g.copies.length; i++) {
604 var cn = g.copies[i].call_number();
605 if (typeof cn == 'object') { cn = cn.id(); }
606 if (cn == -1) { safe = false; }
610 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
615 /******************************************************************************************************/
616 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
618 g.safe_to_edit_copy_status = function() {
621 for (var i = 0; i < g.copies.length; i++) {
622 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
623 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
627 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
632 /******************************************************************************************************/
633 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
635 g.populate_alert_message_input = function(tb) {
637 var seen = {}; var s = '';
638 for (var i = 0; i < g.copies.length; i++) {
639 var msg = g.copies[i].alert_message();
641 if (typeof seen[msg] == 'undefined') {
647 tb.setAttribute('value',s);
649 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
653 /***************************************************************************************************************/
654 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
656 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
657 g.data.stash_retrieve();
658 var label = 'acpl_list_for_lib_'+lib_id;
659 if (typeof g.data[label] == 'undefined') {
660 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
661 if (typeof robj.ilsevent != 'undefined') throw(robj);
663 for (var j = 0; j < robj.length; j++) {
664 var my_acpl = robj[j];
665 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
666 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
667 g.data.list.acpl.push( my_acpl );
669 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
670 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
671 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
672 temp_list.push( my_acpl );
675 g.data[label] = temp_list; g.data.stash(label,'hash','list');
677 return g.data[label];
680 /******************************************************************************************************/
681 /* This returns a list of acpl's appropriate for the copies being edited */
683 g.get_acpl_list = function() {
686 JSAN.use('util.functional');
690 /**************************************/
691 /* get owning libs from call numbers */
693 var owning_libs = {};
694 for (var i = 0; i < g.copies.length; i++) {
695 var callnumber = g.copies[i].call_number();
696 if (!callnumber) continue;
697 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
699 if (! g.map_acn[ cn_id ]) {
700 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
701 if (typeof req.ilsevent == 'undefined') {
702 g.map_acn[ cn_id ] = req;
707 var consider_lib = g.map_acn[ cn_id ].owning_lib();
708 if (!consider_lib) continue;
709 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
713 for (var i in g.callnumbers) {
714 var consider_lib = g.callnumbers[i].owning_lib;
715 if (!consider_lib) continue;
716 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
720 /***************************************************************************************************/
721 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
723 JSAN.use('util.fm_utils');
724 var libs = []; for (var i in owning_libs) libs.push(i);
725 if (libs.length > 0) {
726 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
727 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
730 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
731 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
732 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
733 if (acpl_list[i] != null) {
734 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
745 for (var i = 0; i < g.copies.length; i++) {
746 var consider_lib = g.copies[i].circ_lib();
747 if (!consider_lib) continue;
748 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
751 /***************************************************************************************************/
752 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
754 libs = []; for (var i in circ_libs) libs.push(i);
755 if (libs.length > 0) {
756 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
757 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
760 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
761 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
762 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
763 if (acpl_list[i] != null) {
764 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
770 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
771 return acpl_list.sort(
773 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
774 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
775 if (label_a < label_b) return -1;
776 if (label_a > label_b) return 1;
782 g.error.standard_unexpected_error_alert('get_acpl_list',E);
788 /******************************************************************************************************/
789 /* This keeps track of which fields have been edited for styling purposes */
793 /******************************************************************************************************/
794 /* This keeps track of which fields are required, and which fields have been populated */
799 /******************************************************************************************************/
800 /* These need data from the middle layer to render */
802 function init_panes0() {
803 g.special_exception = {};
804 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
805 JSAN.use('util.widgets');
806 if (value>0) { /* an existing call number */
807 g.network.simple_request(
808 'FM_ACN_RETRIEVE.authoritative',
811 var cn = '??? id = ' + value;
813 cn = req.getResultObject();
815 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
817 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
820 } else { /* a yet to be created call number */
822 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
826 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
827 if (!Number(value)) return;
828 g.network.simple_request(
829 'FM_AU_RETRIEVE_VIA_ID',
832 var p = '??? id = ' + value;
834 p = req.getResultObject();
838 g.error.sdump('D_ERROR','patron retrieve: ' + E);
840 JSAN.use('util.widgets');
841 util.widgets.set_text(label,p);
845 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.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 util.widgets.set_text(label,p);
865 /******************************************************************************************************/
866 g.readonly_stat_cat_names = [];
867 g.editable_stat_cat_names = [];
869 /******************************************************************************************************/
870 /* These get show in the left panel */
872 function init_panes() {
873 g.panes_and_field_names = {
878 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
880 render: 'fm.barcode();',
884 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
886 render: 'util.date.formatted_date( fm.create_date(), "%F");',
890 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
892 render: 'util.date.formatted_date( fm.active_date(), "%F");',
896 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
898 render: 'fm.creator();',
902 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
904 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
908 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
910 render: 'fm.editor();',
919 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
921 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
922 input: 'c = function(v){ g.apply("location",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.get_acpl_list(), function(obj) { return [ g.data.hash.aou[ obj.owning_lib() ].shortname() + " : " + obj.name(), obj.id() ]; }).sort()); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
927 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
929 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
930 //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);',
931 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);',
935 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
937 render: 'fm.call_number();',
938 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,
942 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
944 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
945 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);',
955 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
957 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") )',
958 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);',
962 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
964 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") )',
965 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);',
969 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
971 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() )',
972 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);',
977 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
979 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") )',
980 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);',
984 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
986 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; }',
987 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);',
992 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
994 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; }',
995 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);',
1000 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1002 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',
1003 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);',
1007 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1009 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()])',
1010 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);',
1017 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1019 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1020 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);',
1025 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1027 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") )',
1028 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);',
1032 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1034 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1035 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);',
1039 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1041 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1042 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);',
1047 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1049 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") )',
1050 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);',
1054 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1056 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") )',
1057 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);',
1061 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1063 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")',
1064 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);',
1076 /******************************************************************************************************/
1077 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1079 g.summarize = function( copies ) {
1080 /******************************************************************************************************/
1083 JSAN.use('util.date'); JSAN.use('util.money');
1086 for (var i in g.panes_and_field_names) {
1087 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1089 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1090 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1092 /******************************************************************************************************/
1093 /* Loop through the field names */
1095 for (var i = 0; i < g.field_names.length; i++) {
1097 var field_name = g.field_names[i][0];
1098 var render = g.field_names[i][1].render;
1099 var attr = g.field_names[i][1].attr;
1100 g.summary[ field_name ] = {};
1101 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1103 /******************************************************************************************************/
1104 /* Loop through the copies */
1106 for (var j = 0; j < copies.length; j++) {
1109 var cmd = render || ('fm.' + field_name + '();');
1110 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1112 /**********************************************************************************************/
1113 /* Try to retrieve the value for this field for this copy */
1116 value = eval( cmd );
1118 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1120 if (typeof value == 'object' && value != null) {
1121 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1123 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1124 delete g.populated[field_name];
1127 /**********************************************************************************************/
1128 /* Tally the count */
1130 if (g.summary[ field_name ][ value ]) {
1131 g.summary[ field_name ][ value ]++;
1133 g.summary[ field_name ][ value ] = 1;
1137 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1140 /******************************************************************************************************/
1141 /* Display the summarized data and inputs for editing */
1143 g.render = function() {
1145 /******************************************************************************************************/
1146 /* Library setup and clear any existing interface */
1148 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1150 for (var i in g.panes_and_field_names) {
1151 var p = document.getElementById(i);
1152 if (p) util.widgets.remove_children(p);
1155 /******************************************************************************************************/
1156 /* Populate the library filter menu for stat cats */
1159 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1160 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1163 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1165 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1166 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1167 for (var i = 0; i < sc_libs2.length; i++) {
1168 var menuitem = document.createElement('menuitem');
1169 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1170 menuitem.setAttribute('type','checkbox');
1171 menuitem.setAttribute('checked','true');
1172 menuitem.setAttribute('label',sc_libs2[i][0]);
1173 menuitem.setAttribute('value',sc_libs2[i][1]);
1174 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1175 x.appendChild(menuitem);
1178 /******************************************************************************************************/
1179 /* Prepare the panes */
1181 var groupbox; var caption; var vbox; var grid; var rows;
1183 /******************************************************************************************************/
1184 /* Loop through the field names */
1186 for (h in g.panes_and_field_names) {
1187 if (!document.getElementById(h)) continue;
1188 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1190 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1191 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1193 for (var a in attr) {
1194 groupbox.setAttribute(a,attr[a]);
1197 caption = document.createElement('caption'); groupbox.appendChild(caption);
1198 caption.setAttribute('label',fn);
1199 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1200 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1201 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1202 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1203 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1204 grid.setAttribute('flex','1');
1205 rows = grid.lastChild;
1208 /**************************************************************************************/
1209 /* Loop through each value for the field */
1211 for (var j in g.summary[fn]) {
1212 var value = j; var count = g.summary[fn][j];
1213 row = document.createElement('row'); rows.appendChild(row);
1214 var label1 = document.createElement('description'); row.appendChild(label1);
1215 if (g.special_exception[ fn ]) {
1216 g.special_exception[ fn ]( label1, value );
1218 label1.appendChild( document.createTextNode(value) );
1220 var label2 = document.createElement('description'); row.appendChild(label2);
1223 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1225 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1227 label2.appendChild( document.createTextNode(copy_count) );
1229 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1230 var hbox = document.createElement('hbox'); // main input controls go here
1231 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1232 groupbox.appendChild(hbox);
1233 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1234 groupbox.appendChild(hbox2);
1236 /**************************************************************************************/
1237 /* Render the input widget */
1239 if (f[1].input && g.edit) {
1240 g.render_input(hbox,f[1]);
1244 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1250 /******************************************************************************************************/
1251 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1252 JSAN.use('util.file');
1253 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1254 g.copy_editor_prefs = util.widgets.load_attributes(file);
1255 for (var i in g.copy_editor_prefs) {
1256 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1258 g.toggle_stat_cat_display( document.getElementById(i) );
1259 } catch(E) { alert(E); }
1262 if (g.template_menu) g.template_menu.value = g.template_menu.getAttribute('value');
1266 /******************************************************************************************************/
1267 /* This actually draws the change button and input widget for a given field */
1268 g.render_input = function(node,blob) {
1270 // node = hbox ; groupbox -> hbox, hbox
1272 var groupbox = node.parentNode;
1273 var caption = groupbox.firstChild;
1274 var vbox = node.previousSibling;
1276 var hbox2 = node.nextSibling;
1278 var input_cmd = blob.input;
1279 var render_cmd = blob.render;
1280 var attr = blob.attr;
1282 var block = false; var first = true;
1284 function on_mouseover(ev) {
1285 groupbox.setAttribute('style','background: white');
1288 function on_mouseout(ev) {
1289 groupbox.setAttribute('style','');
1292 vbox.addEventListener('mouseover',on_mouseover,false);
1293 vbox.addEventListener('mouseout',on_mouseout,false);
1294 groupbox.addEventListener('mouseover',on_mouseover,false);
1295 groupbox.addEventListener('mouseout',on_mouseout,false);
1296 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1297 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1299 function on_click(ev){
1301 if (block || g.disabled || !g.edit) {
1308 function post_c(v) {
1310 /* FIXME - kludgy */
1311 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1315 f = input_cmd.match(/apply\("(.+?)",/)[1];
1318 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1324 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1328 g.summarize( g.copies );
1330 g.check_for_unmet_required_fields();
1331 document.getElementById(caption.id).focus();
1335 g.error.standard_unexpected_error_alert('post_c',E);
1338 var x; var c; eval( input_cmd );
1340 util.widgets.remove_children(vbox);
1341 util.widgets.remove_children(hbox);
1342 util.widgets.remove_children(hbox2);
1343 hbox.appendChild(x);
1344 var apply = document.createElement('button');
1345 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1346 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1347 hbox2.appendChild(apply);
1348 apply.addEventListener('command',function() { c(x.value); },false);
1349 var cancel = document.createElement('button');
1350 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1351 cancel.addEventListener('command',function() {
1352 setTimeout( function() {
1353 g.summarize( g.copies );
1355 g.check_for_unmet_required_fields();
1356 document.getElementById(caption.id).focus();
1361 hbox2.appendChild(cancel);
1362 setTimeout( function() { x.focus(); }, 0 );
1365 g.error.standard_unexpected_error_alert('render_input',E);
1368 vbox.addEventListener('click',on_click, false);
1369 hbox.addEventListener('click',on_click, false);
1370 caption.addEventListener('click',on_click, false);
1371 caption.addEventListener('keypress',function(ev) {
1372 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1374 caption.setAttribute('style','-moz-user-focus: normal');
1375 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1376 caption.setAttribute('onblur','this.setAttribute("class","")');
1379 g.error.sdump('D_ERROR',E + '\n');
1383 /******************************************************************************************************/
1384 /* store the copies in the global xpcom stash */
1386 g.stash_and_close = function() {
1390 if (g.handle_update) {
1392 var r = g.network.request(
1393 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1394 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1395 [ ses(), g.copies, true ]
1397 if (typeof r.ilsevent != 'undefined') {
1398 g.error.standard_unexpected_error_alert('copy update',r);
1400 /* FIXME -- revisit the return value here */
1402 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1405 //g.data.temp_copies = js2JSON( g.copies );
1406 //g.data.stash('temp_copies');
1407 xulG.copies = g.copies;
1408 update_modal_xulG(xulG);
1409 JSAN.use('util.widgets');
1410 util.widgets.dispatch('close',window);
1412 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1416 /******************************************************************************************************/
1417 /* spawn copy notes interface */
1419 g.copy_notes = function() {
1420 JSAN.use('util.window'); var win = new util.window();
1422 urls.XUL_COPY_NOTES,
1423 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1424 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1425 { 'copy_id' : g.copies[0].id() }
1429 /******************************************************************************************************/
1430 /* hides or unhides stat cats based on library stat cat filter menu */
1431 g.toggle_stat_cat_display = function(el) {
1433 var visible = el.getAttribute('checked');
1434 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1435 for (var n = 0; n < nl.length; n++) {
1437 nl[n].setAttribute('hidden','false');
1439 nl[n].setAttribute('hidden','true');
1442 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1443 g.save_attributes();
1446 /******************************************************************************************************/
1447 /* This adds a stat cat definition to the stat cat pane for rendering */
1448 g.save_attributes = function() {
1449 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1450 var what_to_save = {};
1451 for (var i in g.copy_editor_prefs) {
1452 what_to_save[i] = [];
1453 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1455 util.widgets.save_attributes(file, what_to_save );
1458 /******************************************************************************************************/
1459 /* This adds a stat cat definition to the stat cat pane for rendering */
1460 g.add_stat_cat = function(sc) {
1462 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1466 if (typeof sc == 'object') {
1471 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1473 g.stat_cat_seen[ sc_id ] = 1;
1475 if (typeof sc != 'object') {
1477 sc = g.network.simple_request(
1478 'FM_ASC_BATCH_RETRIEVE',
1479 [ ses(), [ sc_id ] ]
1484 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1486 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1488 if (get_bool( sc.required() )) {
1489 g.required[ label_name ] = 1;
1495 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1496 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1497 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()
1498 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1499 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1506 g.panes_and_field_names.right_pane4.push( temp_array );
1508 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1512 /******************************************************************************************************/
1513 /* Add stat cats to the panes_and_field_names.right_pane4 */
1514 g.populate_stat_cats = function() {
1516 g.data.stash_retrieve();
1517 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1519 function get(lib_id,only_these) {
1520 g.data.stash_retrieve();
1521 var label = 'asc_list_for_lib_'+lib_id;
1522 if (typeof g.data[label] == 'undefined') {
1523 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1524 if (typeof robj.ilsevent != 'undefined') throw(robj);
1526 for (var j = 0; j < robj.length; j++) {
1527 var my_asc = robj[j];
1528 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1529 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1530 g.data.hash.asc[ my_asc.id() ] = my_asc;
1532 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1533 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1534 temp_list.push( my_asc );
1537 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1539 return g.data[label];
1542 /* The stat cats for the pertinent library -- this is based on workstation ou */
1543 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1544 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1545 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1546 g.add_stat_cat( g.data.list.my_asc[i] );
1549 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1550 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1552 function add_common_ancestors(sc_libs) {
1553 JSAN.use('util.fm_utils');
1554 var libs = []; for (var i in sc_libs) libs.push(i);
1555 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1556 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1558 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1559 var asc_list = get(ancestor, ancestors);
1560 for (var i = 0; i < asc_list.length; i++) {
1561 g.add_stat_cat( asc_list[i] );
1566 /* stat cats based on stat cat entries present on these copies */
1568 for (var i = 0; i < g.copies.length; i++) {
1569 var entries = g.copies[i].stat_cat_entries();
1570 if (!entries) entries = [];
1571 for (var j = 0; j < entries.length; j++) {
1572 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1573 sc_libs[ lib ] = true;
1576 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1578 /* stat cats based on Circ Lib */
1580 for (var i = 0; i < g.copies.length; i++) {
1581 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1582 sc_libs[ circ_lib ] = true;
1584 add_common_ancestors(sc_libs);
1586 /* stat cats based on Owning Lib */
1588 for (var i = 0; i < g.copies.length; i++) {
1589 var cn_id = g.copies[i].call_number();
1591 if (! g.map_acn[ cn_id ]) {
1592 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1593 if (typeof req.ilsevent == 'undefined') {
1594 g.map_acn[ cn_id ] = req;
1599 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1600 sc_libs[ owning_lib ] = true;
1603 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1605 g.panes_and_field_names.right_pane4.sort();
1609 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1613 g.check_for_unmet_required_fields = function() {
1615 for (var fn in g.required) {
1616 if (typeof g.populated[fn] == 'undefined') {
1620 if (xulG.unified_interface) {
1621 if (abort.length > 0) {
1622 if (typeof xulG.lock_save_button == 'function') {
1623 xulG.lock_save_button();
1626 if (typeof xulG.unlock_save_button == 'function') {
1627 xulG.unlock_save_button();
1631 if (abort.length > 0) {
1632 $('save').setAttribute('disabled','true');
1634 $('save').setAttribute('disabled','false');