2 var g = { 'disabled' : false };
5 function $(id) { return document.getElementById(id); }
9 /******************************************************************************************************/
10 /* setup JSAN and some initial libraries */
12 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
13 if (typeof JSAN == 'undefined') {
14 throw( $('commonStrings').getString('common.jsan.missing') );
16 JSAN.errorLevel = "die"; // none, warn, or die
17 JSAN.addRepository('/xul/server/');
18 JSAN.use('util.error'); g.error = new util.error();
19 g.error.sdump('D_TRACE','my_init() for cat/copy_editor.xul');
21 JSAN.use('util.functional');
22 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
23 JSAN.use('util.network'); g.network = new util.network();
25 if (xulG.unified_interface) {
26 $('non_unified_buttons').hidden = true;
29 g.docid = xul_param('docid',{'modal_xulG':true});
30 g.handle_update = xul_param('handle_update',{'modal_xulG':true});
32 /******************************************************************************************************/
33 /* Get the copy ids from various sources and flesh them */
35 var copy_ids = xul_param('copy_ids',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xulG':true,'JSON2js_if_xpcom':true,'stash_name':'temp_copy_ids','clear_xpcom':true,'modal_xulG':true});
36 if (!copy_ids) copy_ids = [];
38 if (copy_ids.length > 0) g.copies = g.network.simple_request(
39 'FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative',
43 /******************************************************************************************************/
44 /* And other fleshed copies if any */
46 if (!g.copies) g.copies = [];
47 var c = xul_param('copies',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_copies','clear_xpcom':true,'modal_xulG':true})
48 if (c) g.copies = g.copies.concat(c);
50 /******************************************************************************************************/
51 /* We try to retrieve callnumbers for existing copies, but for new copies, we rely on this */
53 g.callnumbers = xul_param('callnumbers',{'concat':true,'JSON2js_if_cgi':true,'JSON2js_if_xpcom':true,'stash_name':'temp_callnumbers','clear_xpcom':true,'modal_xulG':true});
55 /******************************************************************************************************/
56 /* Get preference (if it exists) for copy location label order */
58 g.cl_first = false; // Default to legacy OU first mode
59 var prefs = Components.classes['@mozilla.org/preferences-service;1']
60 .getService(Components.interfaces['nsIPrefBranch']);
62 g.cl_first = prefs.getBoolPref('oils.copy_editor.copy_location_name_first');
65 /******************************************************************************************************/
66 /* Quick fix, this was defined inline in the global scope but now needs g.error and g.copies from my_init */
67 /* Quick fix, messagecatalog only usable during/after onload */
72 /******************************************************************************************************/
73 /* Is the interface an editor or a viewer, single or multi copy, existing copies or new copies? */
75 if (xul_param('edit',{'modal_xulG':true}) == '1') {
79 if (g.copies.length > 0) { // When loaded in the unified interface, there may be no copies yet (from the volum/item creator)
81 // Editor desired, but let's check permissions
84 var check = g.network.simple_request(
85 'PERM_MULTI_ORG_CHECK',
88 g.data.list.au[0].id(),
89 util.functional.map_list(
93 var cn_id = o.call_number();
95 lib = o.circ_lib(); // base perms on circ_lib instead of owning_lib if pre-cat
97 if (! g.map_acn[ cn_id ]) {
98 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
99 if (typeof req.ilsevent == 'undefined') {
100 g.map_acn[ cn_id ] = req;
101 lib = g.map_acn[ cn_id ].owning_lib();
106 lib = g.map_acn[ cn_id ].owning_lib();
109 return typeof lib == 'object' ? lib.id() : lib;
112 g.copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
115 g.edit = check.length == 0;
117 g.error.standard_unexpected_error_alert('batch permission check',E);
123 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
124 $('save').setAttribute('hidden','false');
126 $('top_nav').setAttribute('hidden','true');
129 g.retrieve_templates();
132 $('top_nav').setAttribute('hidden','true');
135 g.panes_and_field_names.left_pane =
138 $('catStrings').getString('staff.cat.copy_editor.status'),
140 render: 'typeof fm.status() == "object" ? fm.status().name() : g.data.hash.ccs[ fm.status() ].name()',
141 input: g.safe_to_edit_copy_status() ? 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( g.data.list.ccs, function(obj) { return [ obj.name(), obj.id(), typeof my_constants.magical_statuses[obj.id()] != "undefined" ? true : false ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);' : undefined,
142 //input: 'c = function(v){ g.apply("status",v); if (typeof post_c == "function") post_c(v); }; x = util.widgets.make_menulist( util.functional.map_list( util.functional.filter_list( g.data.list.ccs, function(obj) { return typeof my_constants.magical_statuses[obj.id()] == "undefined"; } ), function(obj) { return [ obj.name(), obj.id() ]; } ).sort() ); x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c), false);',
145 ].concat(g.panes_and_field_names.left_pane);
148 /******************************************************************************************************/
149 /* Show the Record Details? */
151 var bdb = document.getElementById('brief_display_box'); while(bdb.firstChild) bdb.removeChild(bdb.lastChild);
153 var brief_display = document.createElement('iframe'); bdb.appendChild(brief_display);
154 brief_display.setAttribute( 'src', urls.XUL_BIB_BRIEF + '?docid=' + g.docid); // this is a modal window, so can't push in xulG
155 brief_display.setAttribute( 'flex','1' );
158 /******************************************************************************************************/
159 /* Add stat cats to the panes_and_field_names.right_pane4 */
161 g.populate_stat_cats();
163 /******************************************************************************************************/
164 /* Backup copies :) */
166 g.original_copies = js2JSON( g.copies );
168 /******************************************************************************************************/
171 g.summarize( g.copies );
173 g.check_for_unmet_required_fields();
175 if (xulG.unified_interface) {
176 xulG.disable_copy_editor = function(c) {
177 addCSSClass(document.documentElement,'disabled_copy_editor');
180 xulG.enable_copy_editor = function(c) {
181 removeCSSClass(document.documentElement,'disabled_copy_editor');
183 xulG.refresh_copy_editor();
185 xulG.refresh_copy_editor = function() {
186 dump('refresh_copy_editor\n');
187 addCSSClass(document.documentElement,'enabling_copy_editor');
189 xulG.clear_update_copy_editor_timeout();
190 g.copies = xulG.copies;
191 g.edit = g.copies.length > 0;
193 $('caption').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.caption'));
195 g.original_copies = js2JSON( g.copies );
196 g.hide_copy_notes_button();
197 for (var i = 0; i < g.applied_templates.length; i++) {
198 g._apply_template( g.applied_templates[i], false);
200 if (g.copies.length > 0) {
201 // Stop tracking these templates once they're applied
203 g.applied_templates = [];
205 g.summarize( g.copies );
207 g.check_for_unmet_required_fields();
210 removeCSSClass(document.documentElement,'enabling_copy_editor');
214 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
217 xulG.unlock_copy_editor = function() {
220 xulG.notify_of_templatable_field_change = function(id,v) {
221 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
224 g.hide_copy_notes_button();
227 JSAN.use('util.hide');
228 util.hide.generate_css('ui.hide_copy_editor_fields');
231 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
232 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
237 /******************************************************************************************************/
238 /* Show copy notes button */
239 g.hide_copy_notes_button = function() {
240 if (g.copies.length > 0 && g.copies[0].id() < 0) {
241 document.getElementById('copy_notes').setAttribute('hidden','true');
242 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
243 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
245 if (g.copies.length != 1) {
246 document.getElementById('copy_notes').setAttribute('hidden','true');
250 /******************************************************************************************************/
251 /* Retrieve Templates */
253 g.retrieve_templates = function() {
255 JSAN.use('util.widgets'); JSAN.use('util.functional');
257 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
258 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
259 g.templates = robj['staff_client.copy_editor.templates'];
261 util.widgets.remove_children('template_placeholder');
262 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
264 g.template_menu = util.widgets.make_menulist( list );
265 g.template_menu.setAttribute('id','template_menu');
266 $('template_placeholder').appendChild(g.template_menu);
267 g.template_menu.addEventListener(
269 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
273 if (xulG.unified_interface) {
274 if (typeof xulG.update_unified_template_list == 'function') {
275 xulG.update_unified_template_list(list);
276 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
277 xulG.update_item_editor_template_selection = function(new_value) {
278 g.template_menu.setAttribute('value', new_value);
279 g.template_menu.value = new_value;
280 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
283 xulG.item_editor_apply_template = function() { g.apply_template(true); };
284 xulG.item_editor_delete_template = function() { g.delete_template(); };
285 xulG.item_editor_save_template = function() { g.save_template(); };
286 xulG.item_editor_import_templates = function() { g.import_templates(); };
287 xulG.item_editor_export_templates = function() { g.export_templates(); };
288 xulG.item_editor_reset = function() { g.reset(); };
293 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
297 /******************************************************************************************************/
300 g.applied_templates = [];
302 g.apply_template = function(apply_volume_editor_template_changes) {
304 var name = g.template_menu.value;
305 if (g.templates[ name ] != 'undefined') {
307 // We're only tracking these applied templates temporarily,
308 // specifically when they're used prior to copies being
309 // created in the unified interface.
310 g.applied_templates.push( name );
312 g._apply_template(name,apply_volume_editor_template_changes);
313 g.summarize( g.copies );
315 g.check_for_unmet_required_fields();
318 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
322 g._apply_template = function(name,apply_volume_editor_template_changes) {
324 if (g.templates[ name ] != 'undefined') {
325 var template = g.templates[ name ];
326 for (var i in template) {
327 if (g.is_field_hidden(i)) {
328 alert($('catStrings').getFormattedString(
329 'staff.cat.copy_editor.apply_unsafe_field',
334 if (template[i].field == 'status') {
335 if (!g.safe_to_edit_copy_status()) {
336 alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_unsafe_field',[i]));
340 g.changed[ i ] = template[ i ];
341 switch( template[i].type ) {
343 g.apply(template[i].field,template[i].value);
346 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
349 g.apply_owning_lib(template[i].value);
351 case 'volume_copy_creator' :
352 if (xulG.unified_interface && apply_volume_editor_template_changes) {
353 xulG.apply_template_to_batch(template[i].field,template[i].value);
360 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
364 /******************************************************************************************************/
365 /* Save as Template */
367 g.save_template = function() {
369 var name = window.prompt(
370 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
372 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
375 g.templates[name] = g.changed;
376 var robj = g.network.simple_request(
377 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
379 if (typeof robj.ilsevent != 'undefined') {
382 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
386 g.retrieve_templates();
388 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
394 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
398 /******************************************************************************************************/
399 /* Delete Template */
401 g.delete_template = function() {
403 var name = g.template_menu.value;
405 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
406 delete(g.templates[name]);
407 var robj = g.network.simple_request(
408 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
410 if (typeof robj.ilsevent != 'undefined') {
413 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
417 g.retrieve_templates();
419 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
425 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
429 /******************************************************************************************************/
430 /* Export Templates */
432 g.export_templates = function() {
434 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
435 JSAN.use('util.file'); var f = new util.file('');
436 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
438 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
442 /******************************************************************************************************/
443 /* Import Templates */
445 g.import_templates = function() {
447 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
448 JSAN.use('util.file'); var f = new util.file('');
449 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
451 for (var i in temp) {
453 if (g.templates[i]) {
455 var r = g.error.yns_alert(
456 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
457 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
458 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
459 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
461 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
464 if (r == 0 /* Yes */) g.templates[i] = temp[i];
468 g.templates[i] = temp[i];
474 var r = g.error.yns_alert(
475 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
476 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
477 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
478 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
480 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
483 if (r == 0 /* Yes */) {
484 var robj = g.network.simple_request(
485 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
487 if (typeof robj.ilsevent != 'undefined') {
490 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
494 g.retrieve_templates();
496 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
502 util.widgets.remove_children('template_placeholder');
503 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
504 g.template_menu = util.widgets.make_menulist( list );
505 $('template_placeholder').appendChild(g.template_menu);
506 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
511 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
516 /******************************************************************************************************/
517 /* Restore backup copies */
519 g.reset = function() {
520 g.applied_templates = [];
522 g.copies = JSON2js( g.original_copies );
523 g.summarize( g.copies );
525 g.check_for_unmet_required_fields();
527 if (xulG.unified_interface) {
528 xulG.reset_batch_menus();
532 /******************************************************************************************************/
533 /* Apply a value to a specific field on all the copies being edited */
535 g.apply = function(field,value) {
536 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
537 if (value == '<HACK:KLUDGE:NULL>') {
540 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
541 if (field == 'price' || field == 'deposit_amount') {
545 JSAN.use('util.money'); value = util.money.sanitize( value );
548 for (var i = 0; i < g.copies.length; i++) {
549 var copy = g.copies[i];
551 copy[field]( value ); copy.ischanged('1');
560 /******************************************************************************************************/
561 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
563 g.apply_stat_cat = function(sc_id,entry_id) {
564 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
565 for (var i = 0; i < g.copies.length; i++) {
566 var copy = g.copies[i];
569 var temp = copy.stat_cat_entries();
570 if (!temp) temp = [];
571 temp = util.functional.filter_list(
574 return (obj.stat_cat() != sc_id);
579 util.functional.find_id_object_in_list(
580 g.data.hash.asc[sc_id].entries(),
585 copy.stat_cat_entries( temp );
588 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
595 /******************************************************************************************************/
596 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
598 g.apply_owning_lib = function(ou_id) {
599 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
600 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
601 if (! g.safe_to_change_owning_lib() ) { return; }
602 for (var i = 0; i < g.copies.length; i++) {
603 var copy = g.copies[i];
605 if (!g.map_acn[copy.call_number()]) {
606 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
607 if (typeof volume.ilsevent != 'undefined') {
608 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
611 g.map_acn[copy.call_number()] = volume;
613 var old_volume = g.map_acn[copy.call_number()];
614 var acn_blob = g.network.simple_request(
615 'FM_ACN_FIND_OR_CREATE',
616 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
618 if (typeof acn_blob.ilsevent != 'undefined') {
619 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
622 copy.call_number(acn_blob.acn_id);
625 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
632 /******************************************************************************************************/
633 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
635 g.safe_to_change_owning_lib = function() {
637 if (xulG.unified_interface) { return false; }
639 for (var i = 0; i < g.copies.length; i++) {
640 var cn = g.copies[i].call_number();
641 if (typeof cn == 'object') { cn = cn.id(); }
642 if (cn == -1) { safe = false; }
646 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
651 /******************************************************************************************************/
652 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
654 g.safe_to_edit_copy_status = function() {
657 for (var i = 0; i < g.copies.length; i++) {
658 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
659 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
663 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
668 /******************************************************************************************************/
669 /* This returns true if the field has been hidden via util.hide */
671 g.is_field_hidden = function(field) {
673 g.data.stash_retrieve();
674 if (g.data.hash.aous['ui.hide_copy_editor_fields']
675 && g.data.hash.aous['ui.hide_copy_editor_fields'].indexOf(field) > -1) {
679 g.error.standard_unexpected_error_alert('is_field_hidden?',E);
685 /******************************************************************************************************/
686 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
688 g.populate_alert_message_input = function(tb) {
690 var seen = {}; var s = '';
691 for (var i = 0; i < g.copies.length; i++) {
692 var msg = g.copies[i].alert_message();
694 if (typeof seen[msg] == 'undefined') {
700 tb.setAttribute('value',s);
702 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
706 /***************************************************************************************************************/
707 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
709 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
710 g.data.stash_retrieve();
711 var label = 'acpl_list_for_lib_'+lib_id;
712 if (typeof g.data[label] == 'undefined') {
713 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
714 if (typeof robj.ilsevent != 'undefined') throw(robj);
716 for (var j = 0; j < robj.length; j++) {
717 var my_acpl = robj[j];
718 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
719 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
720 g.data.list.acpl.push( my_acpl );
722 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
723 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
724 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
725 temp_list.push( my_acpl );
728 g.data[label] = temp_list; g.data.stash(label,'hash','list');
730 return g.data[label];
733 /******************************************************************************************************/
734 /* This returns a list of acpl's appropriate for the copies being edited */
736 g.get_acpl_list = function() {
739 JSAN.use('util.functional');
743 /**************************************/
744 /* get owning libs from call numbers */
746 var owning_libs = {};
747 for (var i = 0; i < g.copies.length; i++) {
748 var callnumber = g.copies[i].call_number();
749 if (!callnumber) continue;
750 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
752 if (! g.map_acn[ cn_id ]) {
753 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
754 if (typeof req.ilsevent == 'undefined') {
755 g.map_acn[ cn_id ] = req;
760 var consider_lib = g.map_acn[ cn_id ].owning_lib();
761 if (!consider_lib) continue;
762 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
766 for (var i in g.callnumbers) {
767 var consider_lib = g.callnumbers[i].owning_lib;
768 if (!consider_lib) continue;
769 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
773 /***************************************************************************************************/
774 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
776 JSAN.use('util.fm_utils');
777 var libs = []; for (var i in owning_libs) libs.push(i);
778 if (libs.length > 0) {
779 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
780 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
783 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
784 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
785 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
786 if (acpl_list[i] != null) {
787 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
798 for (var i = 0; i < g.copies.length; i++) {
799 var consider_lib = g.copies[i].circ_lib();
800 if (!consider_lib) continue;
801 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
804 /***************************************************************************************************/
805 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
807 libs = []; for (var i in circ_libs) libs.push(i);
808 if (libs.length > 0) {
809 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
810 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
813 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
814 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
815 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
816 if (acpl_list[i] != null) {
817 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
823 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
824 return acpl_list.sort(
826 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
827 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
828 if (label_a < label_b) return -1;
829 if (label_a > label_b) return 1;
835 g.error.standard_unexpected_error_alert('get_acpl_list',E);
841 /******************************************************************************************************/
842 /* This keeps track of which fields have been edited for styling purposes */
846 /******************************************************************************************************/
847 /* This keeps track of which fields are required, and which fields have been populated */
852 /******************************************************************************************************/
853 /* These need data from the middle layer to render */
855 function init_panes0() {
856 g.special_exception = {};
857 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
858 JSAN.use('util.widgets');
859 if (value>0) { /* an existing call number */
860 g.network.simple_request(
861 'FM_ACN_RETRIEVE.authoritative',
864 var cn = '??? id = ' + value;
866 cn = req.getResultObject();
868 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
870 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
873 } else { /* a yet to be created call number */
875 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
879 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
880 if (!Number(value)) return;
881 g.network.simple_request(
882 'FM_AU_RETRIEVE_VIA_ID',
885 var p = '??? id = ' + value;
887 p = req.getResultObject();
891 g.error.sdump('D_ERROR','patron retrieve: ' + E);
893 JSAN.use('util.widgets');
894 util.widgets.set_text(label,p);
898 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
899 if (!Number(value)) return;
900 g.network.simple_request(
901 'FM_AU_RETRIEVE_VIA_ID',
904 var p = '??? id = ' + value;
906 p = req.getResultObject();
910 g.error.sdump('D_ERROR','patron retrieve: ' + E);
912 util.widgets.set_text(label,p);
918 /******************************************************************************************************/
919 g.readonly_stat_cat_names = [];
920 g.editable_stat_cat_names = [];
922 /******************************************************************************************************/
923 /* These get show in the left panel */
925 function init_panes() {
926 g.panes_and_field_names = {
931 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
933 render: 'fm.barcode();',
937 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
939 render: 'util.date.formatted_date( fm.create_date(), "%F");',
943 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
945 render: 'util.date.formatted_date( fm.active_date(), "%F");',
949 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
951 render: 'fm.creator();',
955 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
957 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
961 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
963 render: 'fm.editor();',
972 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
974 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
975 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);',
980 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
982 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
983 //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);',
984 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);',
988 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
990 render: 'fm.call_number();',
991 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,
995 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
997 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
998 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);',
1008 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
1010 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") )',
1011 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);',
1015 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
1017 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") )',
1018 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);',
1022 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
1024 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() )',
1025 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);',
1030 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
1032 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") )',
1033 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);',
1037 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
1039 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; }',
1040 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);',
1045 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1047 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; }',
1048 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);',
1053 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1055 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',
1056 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);',
1060 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1062 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()])',
1063 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);',
1070 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1072 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1073 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);',
1078 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1080 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") )',
1081 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);',
1085 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1087 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1088 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);',
1092 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1094 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1095 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);',
1100 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1102 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") )',
1103 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);',
1107 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1109 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") )',
1110 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);',
1114 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1116 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")',
1117 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);',
1129 /******************************************************************************************************/
1130 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1132 g.summarize = function( copies ) {
1133 /******************************************************************************************************/
1136 JSAN.use('util.date'); JSAN.use('util.money');
1139 for (var i in g.panes_and_field_names) {
1140 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1142 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1143 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1145 /******************************************************************************************************/
1146 /* Loop through the field names */
1148 for (var i = 0; i < g.field_names.length; i++) {
1150 var field_name = g.field_names[i][0];
1151 var render = g.field_names[i][1].render;
1152 var attr = g.field_names[i][1].attr;
1153 g.summary[ field_name ] = {};
1154 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1156 /******************************************************************************************************/
1157 /* Loop through the copies */
1159 for (var j = 0; j < copies.length; j++) {
1162 var cmd = render || ('fm.' + field_name + '();');
1163 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1165 /**********************************************************************************************/
1166 /* Try to retrieve the value for this field for this copy */
1169 value = eval( cmd );
1171 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1173 if (typeof value == 'object' && value != null) {
1174 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1176 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1177 delete g.populated[field_name];
1180 /**********************************************************************************************/
1181 /* Tally the count */
1183 if (g.summary[ field_name ][ value ]) {
1184 g.summary[ field_name ][ value ]++;
1186 g.summary[ field_name ][ value ] = 1;
1190 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1193 /******************************************************************************************************/
1194 /* Display the summarized data and inputs for editing */
1196 g.render = function() {
1198 /******************************************************************************************************/
1199 /* Library setup and clear any existing interface */
1201 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1203 for (var i in g.panes_and_field_names) {
1204 var p = document.getElementById(i);
1205 if (p) util.widgets.remove_children(p);
1208 /******************************************************************************************************/
1209 /* Populate the library filter menu for stat cats */
1212 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1213 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1216 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1218 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1219 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1220 for (var i = 0; i < sc_libs2.length; i++) {
1221 var menuitem = document.createElement('menuitem');
1222 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1223 menuitem.setAttribute('type','checkbox');
1224 menuitem.setAttribute('checked','true');
1225 menuitem.setAttribute('label',sc_libs2[i][0]);
1226 menuitem.setAttribute('value',sc_libs2[i][1]);
1227 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1228 x.appendChild(menuitem);
1231 /******************************************************************************************************/
1232 /* Prepare the panes */
1234 var groupbox; var caption; var vbox; var grid; var rows;
1236 /******************************************************************************************************/
1237 /* Loop through the field names */
1239 for (h in g.panes_and_field_names) {
1240 if (!document.getElementById(h)) continue;
1241 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1243 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1244 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1245 groupbox.setAttribute('hideable',fn);
1247 for (var a in attr) {
1248 groupbox.setAttribute(a,attr[a]);
1251 caption = document.createElement('caption'); groupbox.appendChild(caption);
1252 caption.setAttribute('label',fn);
1253 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1254 caption.setAttribute('hideable',fn);
1255 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1256 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1257 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1258 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1259 grid.setAttribute('flex','1');
1260 rows = grid.lastChild;
1263 /**************************************************************************************/
1264 /* Loop through each value for the field */
1266 for (var j in g.summary[fn]) {
1267 var value = j; var count = g.summary[fn][j];
1268 row = document.createElement('row'); rows.appendChild(row);
1269 var label1 = document.createElement('description'); row.appendChild(label1);
1270 if (g.special_exception[ fn ]) {
1271 g.special_exception[ fn ]( label1, value );
1273 label1.appendChild( document.createTextNode(value) );
1275 var label2 = document.createElement('description'); row.appendChild(label2);
1278 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1280 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1282 label2.appendChild( document.createTextNode(copy_count) );
1284 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1285 var hbox = document.createElement('hbox'); // main input controls go here
1286 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1287 groupbox.appendChild(hbox);
1288 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1289 groupbox.appendChild(hbox2);
1291 /**************************************************************************************/
1292 /* Render the input widget */
1294 if (f[1].input && g.edit) {
1295 g.render_input(hbox,f[1]);
1299 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1305 /******************************************************************************************************/
1306 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1307 JSAN.use('util.file');
1308 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1309 g.copy_editor_prefs = util.widgets.load_attributes(file);
1310 for (var i in g.copy_editor_prefs) {
1311 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1313 g.toggle_stat_cat_display( document.getElementById(i) );
1314 } catch(E) { alert(E); }
1317 if (g.template_menu) {
1318 g.template_menu.value = g.template_menu.getAttribute('value');
1319 if (xulG.unified_interface) {
1320 if (typeof xulG.update_unified_template_selection == 'function') {
1321 xulG.update_unified_template_selection(g.template_menu.value);
1326 util.hide.generate_css('ui.hide_copy_editor_fields');
1329 /******************************************************************************************************/
1330 /* This actually draws the change button and input widget for a given field */
1331 g.render_input = function(node,blob) {
1333 // node = hbox ; groupbox -> hbox, hbox
1335 var groupbox = node.parentNode;
1336 var caption = groupbox.firstChild;
1337 var vbox = node.previousSibling;
1339 var hbox2 = node.nextSibling;
1341 var input_cmd = blob.input;
1342 var render_cmd = blob.render;
1343 var attr = blob.attr;
1345 var block = false; var first = true;
1347 function on_mouseover(ev) {
1348 groupbox.setAttribute('style','background: white');
1351 function on_mouseout(ev) {
1352 groupbox.setAttribute('style','');
1355 vbox.addEventListener('mouseover',on_mouseover,false);
1356 vbox.addEventListener('mouseout',on_mouseout,false);
1357 groupbox.addEventListener('mouseover',on_mouseover,false);
1358 groupbox.addEventListener('mouseout',on_mouseout,false);
1359 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1360 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1362 function on_click(ev){
1364 if (block || g.disabled || !g.edit) {
1371 function post_c(v) {
1373 /* FIXME - kludgy */
1374 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1378 f = input_cmd.match(/apply\("(.+?)",/)[1];
1381 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1387 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1391 g.summarize( g.copies );
1393 g.check_for_unmet_required_fields();
1394 document.getElementById(caption.id).focus();
1398 g.error.standard_unexpected_error_alert('post_c',E);
1401 var x; var c; eval( input_cmd );
1403 util.widgets.remove_children(vbox);
1404 util.widgets.remove_children(hbox);
1405 util.widgets.remove_children(hbox2);
1406 hbox.appendChild(x);
1407 var apply = document.createElement('button');
1408 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1409 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1410 hbox2.appendChild(apply);
1411 apply.addEventListener('command',function() { c(x.value); },false);
1412 var cancel = document.createElement('button');
1413 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1414 cancel.addEventListener('command',function() {
1415 setTimeout( function() {
1416 g.summarize( g.copies );
1418 g.check_for_unmet_required_fields();
1419 document.getElementById(caption.id).focus();
1424 hbox2.appendChild(cancel);
1425 setTimeout( function() { x.focus(); }, 0 );
1428 g.error.standard_unexpected_error_alert('render_input',E);
1431 vbox.addEventListener('click',on_click, false);
1432 hbox.addEventListener('click',on_click, false);
1433 caption.addEventListener('click',on_click, false);
1434 caption.addEventListener('keypress',function(ev) {
1435 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1437 caption.setAttribute('style','-moz-user-focus: normal');
1438 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1439 caption.setAttribute('onblur','this.setAttribute("class","")');
1442 g.error.sdump('D_ERROR',E + '\n');
1446 /******************************************************************************************************/
1447 /* store the copies in the global xpcom stash */
1449 g.stash_and_close = function() {
1453 if (g.handle_update) {
1455 var r = g.network.request(
1456 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1457 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1458 [ ses(), g.copies, true ]
1460 if (typeof r.ilsevent != 'undefined') {
1461 g.error.standard_unexpected_error_alert('copy update',r);
1463 /* FIXME -- revisit the return value here */
1465 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1468 //g.data.temp_copies = js2JSON( g.copies );
1469 //g.data.stash('temp_copies');
1470 xulG.copies = g.copies;
1471 update_modal_xulG(xulG);
1472 JSAN.use('util.widgets');
1473 util.widgets.dispatch('close',window);
1475 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1479 /******************************************************************************************************/
1480 /* spawn copy notes interface */
1482 g.copy_notes = function() {
1483 JSAN.use('util.window'); var win = new util.window();
1485 urls.XUL_COPY_NOTES,
1486 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1487 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1488 { 'copy_id' : g.copies[0].id() }
1492 /******************************************************************************************************/
1493 /* hides or unhides stat cats based on library stat cat filter menu */
1494 g.toggle_stat_cat_display = function(el) {
1496 var visible = el.getAttribute('checked');
1497 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1498 for (var n = 0; n < nl.length; n++) {
1500 nl[n].setAttribute('hidden','false');
1502 nl[n].setAttribute('hidden','true');
1505 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1506 g.save_attributes();
1509 /******************************************************************************************************/
1510 /* This adds a stat cat definition to the stat cat pane for rendering */
1511 g.save_attributes = function() {
1512 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1513 var what_to_save = {};
1514 for (var i in g.copy_editor_prefs) {
1515 what_to_save[i] = [];
1516 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1518 util.widgets.save_attributes(file, what_to_save );
1521 /******************************************************************************************************/
1522 /* This adds a stat cat definition to the stat cat pane for rendering */
1523 g.add_stat_cat = function(sc) {
1525 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1529 if (typeof sc == 'object') {
1534 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1536 g.stat_cat_seen[ sc_id ] = 1;
1538 if (typeof sc != 'object') {
1540 sc = g.network.simple_request(
1541 'FM_ASC_BATCH_RETRIEVE',
1542 [ ses(), [ sc_id ] ]
1547 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1549 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1551 if (get_bool( sc.required() )) {
1552 g.required[ label_name ] = 1;
1558 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1559 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1560 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()
1561 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1562 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1569 g.panes_and_field_names.right_pane4.push( temp_array );
1571 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1575 /******************************************************************************************************/
1576 /* Add stat cats to the panes_and_field_names.right_pane4 */
1577 g.populate_stat_cats = function() {
1579 g.data.stash_retrieve();
1580 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1582 function get(lib_id,only_these) {
1583 g.data.stash_retrieve();
1584 var label = 'asc_list_for_lib_'+lib_id;
1585 if (typeof g.data[label] == 'undefined') {
1586 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1587 if (typeof robj.ilsevent != 'undefined') throw(robj);
1589 for (var j = 0; j < robj.length; j++) {
1590 var my_asc = robj[j];
1591 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1592 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1593 g.data.hash.asc[ my_asc.id() ] = my_asc;
1595 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1596 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1597 temp_list.push( my_asc );
1600 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1602 return g.data[label];
1605 /* The stat cats for the pertinent library -- this is based on workstation ou */
1606 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1607 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1608 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1609 g.add_stat_cat( g.data.list.my_asc[i] );
1612 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1613 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1615 function add_common_ancestors(sc_libs) {
1616 JSAN.use('util.fm_utils');
1617 var libs = []; for (var i in sc_libs) libs.push(i);
1618 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1619 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1621 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1622 var asc_list = get(ancestor, ancestors);
1623 for (var i = 0; i < asc_list.length; i++) {
1624 g.add_stat_cat( asc_list[i] );
1629 /* stat cats based on stat cat entries present on these copies */
1631 for (var i = 0; i < g.copies.length; i++) {
1632 var entries = g.copies[i].stat_cat_entries();
1633 if (!entries) entries = [];
1634 for (var j = 0; j < entries.length; j++) {
1635 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1636 sc_libs[ lib ] = true;
1639 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1641 /* stat cats based on Circ Lib */
1643 for (var i = 0; i < g.copies.length; i++) {
1644 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1645 sc_libs[ circ_lib ] = true;
1647 add_common_ancestors(sc_libs);
1649 /* stat cats based on Owning Lib */
1651 for (var i = 0; i < g.copies.length; i++) {
1652 var cn_id = g.copies[i].call_number();
1654 if (! g.map_acn[ cn_id ]) {
1655 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1656 if (typeof req.ilsevent == 'undefined') {
1657 g.map_acn[ cn_id ] = req;
1662 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1663 sc_libs[ owning_lib ] = true;
1666 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1668 g.panes_and_field_names.right_pane4.sort();
1672 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1676 g.check_for_unmet_required_fields = function() {
1678 for (var fn in g.required) {
1679 if (typeof g.populated[fn] == 'undefined') {
1683 if (xulG.unified_interface) {
1684 if (abort.length > 0) {
1685 if (typeof xulG.lock_save_button == 'function') {
1686 xulG.lock_save_button();
1689 if (typeof xulG.unlock_save_button == 'function') {
1690 xulG.unlock_save_button();
1694 if (abort.length > 0) {
1695 $('save').setAttribute('disabled','true');
1697 $('save').setAttribute('disabled','false');