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 if (g.copies.length > 0) {
192 // Stop tracking these templates once they're applied
194 g.applied_templates = [];
196 g.summarize( g.copies );
198 g.check_for_unmet_required_fields();
201 removeCSSClass(document.documentElement,'blue_bg');
205 alert('Error in copy_editor.js, xulG.refresh_copy_editor(): ' + E);
208 xulG.unlock_copy_editor = function() {
211 xulG.notify_of_templatable_field_change = function(id,v) {
212 g.changed[ 'volume_copy_creator.'+id ] = { 'type' : 'volume_copy_creator', 'field' : id, 'value' : v };
215 g.hide_copy_notes_button();
219 var err_msg = $("commonStrings").getFormattedString('common.exception', ['cat/copy_editor.js', E]);
220 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
225 /******************************************************************************************************/
226 /* Show copy notes button */
227 g.hide_copy_notes_button = function() {
228 if (g.copies.length > 0 && g.copies[0].id() < 0) {
229 document.getElementById('copy_notes').setAttribute('hidden','true');
230 $('save').setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.create_copies'));
231 $('save').setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.create_copies.accesskey'));
233 if (g.copies.length != 1) {
234 document.getElementById('copy_notes').setAttribute('hidden','true');
238 /******************************************************************************************************/
239 /* Retrieve Templates */
241 g.retrieve_templates = function() {
243 JSAN.use('util.widgets'); JSAN.use('util.functional');
245 var robj = g.network.simple_request('FM_AUS_RETRIEVE',[ses(),g.data.list.au[0].id()]);
246 if (typeof robj['staff_client.copy_editor.templates'] != 'undefined') {
247 g.templates = robj['staff_client.copy_editor.templates'];
249 util.widgets.remove_children('template_placeholder');
250 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } ).sort();
252 g.template_menu = util.widgets.make_menulist( list );
253 g.template_menu.setAttribute('id','template_menu');
254 $('template_placeholder').appendChild(g.template_menu);
255 g.template_menu.addEventListener(
257 function() { g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value }; g.save_attributes(); },
261 if (xulG.unified_interface) {
262 if (typeof xulG.update_unified_template_list == 'function') {
263 xulG.update_unified_template_list(list);
264 // functions the unified wrapper should use to let the item attribute editor do the heavy lifting for templates
265 xulG.update_item_editor_template_selection = function(new_value) {
266 g.template_menu.value = new_value;
267 g.copy_editor_prefs[ 'template_menu' ] = { 'value' : g.template_menu.value };
270 xulG.item_editor_apply_template = function() { g.apply_template(true); };
271 xulG.item_editor_delete_template = function() { g.delete_template(); };
272 xulG.item_editor_save_template = function() { g.save_template(); };
273 xulG.item_editor_import_templates = function() { g.import_templates(); };
274 xulG.item_editor_export_templates = function() { g.export_templates(); };
275 xulG.item_editor_reset = function() { g.reset(); };
280 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.retrieve_templates.error'), E);
284 /******************************************************************************************************/
287 g.applied_templates = [];
289 g.apply_template = function(apply_volume_editor_template_changes) {
291 var name = g.template_menu.value;
292 if (g.templates[ name ] != 'undefined') {
294 // We're only tracking these applied templates temporarily,
295 // specifically when they're used prior to copies being
296 // created in the unified interface.
297 g.applied_templates.push( name );
299 g._apply_template(name,apply_volume_editor_template_changes);
300 g.summarize( g.copies );
302 g.check_for_unmet_required_fields();
305 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.apply_templates.error'), E);
309 g._apply_template = function(name,apply_volume_editor_template_changes) {
311 if (g.templates[ name ] != 'undefined') {
312 var template = g.templates[ name ];
313 for (var i in template) {
314 g.changed[ i ] = template[ i ];
315 switch( template[i].type ) {
317 g.apply(template[i].field,template[i].value);
320 if (g.stat_cat_seen[ template[i].field ]) g.apply_stat_cat(template[i].field,template[i].value);
323 g.apply_owning_lib(template[i].value);
325 case 'volume_copy_creator' :
326 if (xulG.unified_interface && apply_volume_editor_template_changes) {
327 xulG.apply_template_to_batch(template[i].field,template[i].value);
334 alert('Error in copy_editor.js, g._apply_template('+name+'): ' + E);
338 /******************************************************************************************************/
339 /* Save as Template */
341 g.save_template = function() {
343 var name = window.prompt(
344 $('catStrings').getString('staff.cat.copy_editor.save_as_template.prompt'),
346 $('catStrings').getString('staff.cat.copy_editor.save_as_template.title')
349 g.templates[name] = g.changed;
350 var robj = g.network.simple_request(
351 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
353 if (typeof robj.ilsevent != 'undefined') {
356 alert($('catStrings').getFormattedString('staff.cat.copy_editor.save_as_template.success', [name]));
360 g.retrieve_templates();
362 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
368 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.save_as_template.error'), E);
372 /******************************************************************************************************/
373 /* Delete Template */
375 g.delete_template = function() {
377 var name = g.template_menu.value;
379 if (! window.confirm($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]))) return;
380 delete(g.templates[name]);
381 var robj = g.network.simple_request(
382 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
384 if (typeof robj.ilsevent != 'undefined') {
387 alert($('catStrings').getFormattedString('staff.cat.copy_editor.delete_template.confirm', [name]));
391 g.retrieve_templates();
393 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
399 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.delete_template.error'), E);
403 /******************************************************************************************************/
404 /* Export Templates */
406 g.export_templates = function() {
408 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
409 JSAN.use('util.file'); var f = new util.file('');
410 f.export_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.export_templates.title'), 'data' : g.templates } );
412 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.export_templates.error'), E);
416 /******************************************************************************************************/
417 /* Import Templates */
419 g.import_templates = function() {
421 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
422 JSAN.use('util.file'); var f = new util.file('');
423 var temp = f.import_file( { 'title' : $('catStrings').getString('staff.cat.copy_editor.import_templates.title') } );
425 for (var i in temp) {
427 if (g.templates[i]) {
429 var r = g.error.yns_alert(
430 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.prompt') + '\n' + g.error.pretty_print( js2JSON( temp[i] ) ),
431 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.replace.title', [i]),
432 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.yes'),
433 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.no'),
435 $('catStrings').getString('staff.cat.copy_editor.import_templates.replace.click_here')
438 if (r == 0 /* Yes */) g.templates[i] = temp[i];
442 g.templates[i] = temp[i];
448 var r = g.error.yns_alert(
449 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.prompt'),
450 $('catStrings').getFormattedString('staff.cat.copy_editor.import_templates.save.title'),
451 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.yes'),
452 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.no'),
454 $('catStrings').getString('staff.cat.copy_editor.import_templates.save.click_here')
457 if (r == 0 /* Yes */) {
458 var robj = g.network.simple_request(
459 'FM_AUS_UPDATE',[ses(),g.data.list.au[0].id(), { 'staff_client.copy_editor.templates' : g.templates }]
461 if (typeof robj.ilsevent != 'undefined') {
464 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.success'));
468 g.retrieve_templates();
470 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.save.error'), E);
476 util.widgets.remove_children('template_placeholder');
477 var list = util.functional.map_object_to_list( g.templates, function(obj,i) { return [i, i]; } );
478 g.template_menu = util.widgets.make_menulist( list );
479 $('template_placeholder').appendChild(g.template_menu);
480 alert($('catStrings').getString('staff.cat.copy_editor.import_templates.note'));
485 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.import_templates.error'), E);
490 /******************************************************************************************************/
491 /* Restore backup copies */
493 g.reset = function() {
494 g.applied_templates = [];
496 g.copies = JSON2js( g.original_copies );
497 g.summarize( g.copies );
499 g.check_for_unmet_required_fields();
501 if (xulG.unified_interface) {
502 xulG.reset_batch_menus();
506 /******************************************************************************************************/
507 /* Apply a value to a specific field on all the copies being edited */
509 g.apply = function(field,value) {
510 g.error.sdump('D_TRACE','applying field = <' + field + '> value = <' + value + '>\n');
511 if (value == '<HACK:KLUDGE:NULL>') {
514 if (field == 'alert_message') { value = value.replace(/^\W+$/g,''); }
515 if (field == 'price' || field == 'deposit_amount') {
519 JSAN.use('util.money'); value = util.money.sanitize( value );
522 for (var i = 0; i < g.copies.length; i++) {
523 var copy = g.copies[i];
525 copy[field]( value ); copy.ischanged('1');
534 /******************************************************************************************************/
535 /* Apply a stat cat entry to all the copies being edited. An entry_id of < 0 signifies the stat cat is being removed. */
537 g.apply_stat_cat = function(sc_id,entry_id) {
538 g.error.sdump('D_TRACE','sc_id = ' + sc_id + ' entry_id = ' + entry_id + '\n');
539 for (var i = 0; i < g.copies.length; i++) {
540 var copy = g.copies[i];
543 var temp = copy.stat_cat_entries();
544 if (!temp) temp = [];
545 temp = util.functional.filter_list(
548 return (obj.stat_cat() != sc_id);
553 util.functional.find_id_object_in_list(
554 g.data.hash.asc[sc_id].entries(),
559 copy.stat_cat_entries( temp );
562 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
569 /******************************************************************************************************/
570 /* Apply an "owning lib" to all the copies being edited. That is, change and auto-vivicating volumes */
572 g.apply_owning_lib = function(ou_id) {
573 g.error.sdump('D_TRACE','ou_id = ' + ou_id + '\n');
574 // but don't allow this when bundled with the volume/copy creator UI, or if we're editing pre-cats
575 if (! g.safe_to_change_owning_lib() ) { return; }
576 for (var i = 0; i < g.copies.length; i++) {
577 var copy = g.copies[i];
579 if (!g.map_acn[copy.call_number()]) {
580 var volume = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ copy.call_number() ]);
581 if (typeof volume.ilsevent != 'undefined') {
582 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.undefined_volume.error', [copy.barcode()]), volume);
585 g.map_acn[copy.call_number()] = volume;
587 var old_volume = g.map_acn[copy.call_number()];
588 var acn_blob = g.network.simple_request(
589 'FM_ACN_FIND_OR_CREATE',
590 [ses(),old_volume.label(),old_volume.record(),ou_id,old_volume.prefix().id(),old_volume.suffix().id(),old_volume.label_class().id()]
592 if (typeof acn_blob.ilsevent != 'undefined') {
593 g.error.standard_unexpected_error_alert($('catStrings').getFormattedString('staff.cat.copy_editor.apply_owning_lib.call_number.error', [copy.barcode()]), acn_blob);
596 copy.call_number(acn_blob.acn_id);
599 g.error.standard_unexpected_error_alert('apply_stat_cat',E);
606 /******************************************************************************************************/
607 /* This returns false if any of the copies being edited are pre-cats, or if we're embedded in the unified volume/copy UI */
609 g.safe_to_change_owning_lib = function() {
611 if (xulG.unified_interface) { return false; }
613 for (var i = 0; i < g.copies.length; i++) {
614 var cn = g.copies[i].call_number();
615 if (typeof cn == 'object') { cn = cn.id(); }
616 if (cn == -1) { safe = false; }
620 g.error.standard_unexpected_error_alert('safe_to_change_owning_lib?',E);
625 /******************************************************************************************************/
626 /* This returns true if none of the copies being edited have a magical status found in my_constants.magical_statuses */
628 g.safe_to_edit_copy_status = function() {
631 for (var i = 0; i < g.copies.length; i++) {
632 var status = g.copies[i].status(); if (typeof status == 'object') status = status.id();
633 if (typeof my_constants.magical_statuses[ status ] != 'undefined') safe = false;
637 g.error.standard_unexpected_error_alert('safe_to_edit_copy_status?',E);
642 /******************************************************************************************************/
643 /* This concats and uniques all the alert messages for use as the default value for a new alert message */
645 g.populate_alert_message_input = function(tb) {
647 var seen = {}; var s = '';
648 for (var i = 0; i < g.copies.length; i++) {
649 var msg = g.copies[i].alert_message();
651 if (typeof seen[msg] == 'undefined') {
657 tb.setAttribute('value',s);
659 g.error.standard_unexpected_error_alert('populate_alert_message_input',E);
663 /***************************************************************************************************************/
664 /* This returns a list of acpl's appropriate for the copies being edited (and caches them in the global stash) */
666 g.get_acpl_list_for_lib = function(lib_id,but_only_these) {
667 g.data.stash_retrieve();
668 var label = 'acpl_list_for_lib_'+lib_id;
669 if (typeof g.data[label] == 'undefined') {
670 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
671 if (typeof robj.ilsevent != 'undefined') throw(robj);
673 for (var j = 0; j < robj.length; j++) {
674 var my_acpl = robj[j];
675 if (typeof g.data.hash.acpl[ my_acpl.id() ] == 'undefined') {
676 g.data.hash.acpl[ my_acpl.id() ] = my_acpl;
677 g.data.list.acpl.push( my_acpl );
679 var only_this_lib = my_acpl.owning_lib(); if (!only_this_lib) continue;
680 if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
681 if (but_only_these.indexOf( String( only_this_lib ) ) != -1) { // This filters out some of the libraries (usually the descendants)
682 temp_list.push( my_acpl );
685 g.data[label] = temp_list; g.data.stash(label,'hash','list');
687 return g.data[label];
690 /******************************************************************************************************/
691 /* This returns a list of acpl's appropriate for the copies being edited */
693 g.get_acpl_list = function() {
696 JSAN.use('util.functional');
700 /**************************************/
701 /* get owning libs from call numbers */
703 var owning_libs = {};
704 for (var i = 0; i < g.copies.length; i++) {
705 var callnumber = g.copies[i].call_number();
706 if (!callnumber) continue;
707 var cn_id = typeof callnumber == 'object' ? callnumber.id() : callnumber;
709 if (! g.map_acn[ cn_id ]) {
710 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
711 if (typeof req.ilsevent == 'undefined') {
712 g.map_acn[ cn_id ] = req;
717 var consider_lib = g.map_acn[ cn_id ].owning_lib();
718 if (!consider_lib) continue;
719 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
723 for (var i in g.callnumbers) {
724 var consider_lib = g.callnumbers[i].owning_lib;
725 if (!consider_lib) continue;
726 owning_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
730 /***************************************************************************************************/
731 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
733 JSAN.use('util.fm_utils');
734 var libs = []; for (var i in owning_libs) libs.push(i);
735 if (libs.length > 0) {
736 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
737 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
740 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
741 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
742 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
743 if (acpl_list[i] != null) {
744 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
755 for (var i = 0; i < g.copies.length; i++) {
756 var consider_lib = g.copies[i].circ_lib();
757 if (!consider_lib) continue;
758 circ_libs[ typeof consider_lib == 'object' ? consider_lib.id() : consider_lib ] = true;
761 /***************************************************************************************************/
762 /* now find the first ancestor they all have in common, get the acpl's for it and higher ancestors */
764 libs = []; for (var i in circ_libs) libs.push(i);
765 if (libs.length > 0) {
766 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
767 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
770 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
771 var acpl_list = g.get_acpl_list_for_lib(ancestor, ancestors);
772 if (acpl_list) for (var i = 0; i < acpl_list.length; i++) {
773 if (acpl_list[i] != null) {
774 my_acpls[ typeof acpl_list[i] == 'object' ? acpl_list[i].id() : acpl_list[i] ] = true;
780 var acpl_list = []; for (var i in my_acpls) acpl_list.push( g.data.hash.acpl[ i ] );
781 return acpl_list.sort(
783 var label_a = g.data.hash.aou[ a.owning_lib() ].shortname() + ' : ' + a.name();
784 var label_b = g.data.hash.aou[ b.owning_lib() ].shortname() + ' : ' + b.name();
785 if (label_a < label_b) return -1;
786 if (label_a > label_b) return 1;
792 g.error.standard_unexpected_error_alert('get_acpl_list',E);
798 /******************************************************************************************************/
799 /* This keeps track of which fields have been edited for styling purposes */
803 /******************************************************************************************************/
804 /* This keeps track of which fields are required, and which fields have been populated */
809 /******************************************************************************************************/
810 /* These need data from the middle layer to render */
812 function init_panes0() {
813 g.special_exception = {};
814 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.owning_library.label')] = function(label,value) {
815 JSAN.use('util.widgets');
816 if (value>0) { /* an existing call number */
817 g.network.simple_request(
818 'FM_ACN_RETRIEVE.authoritative',
821 var cn = '??? id = ' + value;
823 cn = req.getResultObject();
825 g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
827 util.widgets.set_text(label,g.data.hash.aou[ cn.owning_lib() ].shortname() + ' : ' + cn.label());
830 } else { /* a yet to be created call number */
832 util.widgets.set_text(label,g.data.hash.aou[ g.callnumbers[value].owning_lib ].shortname() + ' : ' + g.callnumbers[value].label);
836 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.creator.label')] = function(label,value) {
837 if (!Number(value)) return;
838 g.network.simple_request(
839 'FM_AU_RETRIEVE_VIA_ID',
842 var p = '??? id = ' + value;
844 p = req.getResultObject();
848 g.error.sdump('D_ERROR','patron retrieve: ' + E);
850 JSAN.use('util.widgets');
851 util.widgets.set_text(label,p);
855 g.special_exception[$('catStrings').getString('staff.cat.copy_editor.field.last_editor.label')] = function(label,value) {
856 if (!Number(value)) return;
857 g.network.simple_request(
858 'FM_AU_RETRIEVE_VIA_ID',
861 var p = '??? id = ' + value;
863 p = req.getResultObject();
867 g.error.sdump('D_ERROR','patron retrieve: ' + E);
869 util.widgets.set_text(label,p);
875 /******************************************************************************************************/
876 g.readonly_stat_cat_names = [];
877 g.editable_stat_cat_names = [];
879 /******************************************************************************************************/
880 /* These get show in the left panel */
882 function init_panes() {
883 g.panes_and_field_names = {
888 $('catStrings').getString('staff.cat.copy_editor.field.barcode.label'),
890 render: 'fm.barcode();',
894 $('catStrings').getString('staff.cat.copy_editor.field.creation_date.label'),
896 render: 'util.date.formatted_date( fm.create_date(), "%F");',
900 $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
902 render: 'util.date.formatted_date( fm.active_date(), "%F");',
906 $('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
908 render: 'fm.creator();',
912 $('catStrings').getString('staff.cat.copy_editor.field.last_edit_date.label'),
914 render: 'util.date.formatted_date( fm.edit_date(), "%F");',
918 $('catStrings').getString('staff.cat.copy_editor.field.last_editor.label'),
920 render: 'fm.editor();',
929 $('catStrings').getString('staff.cat.copy_editor.field.location.label'),
931 render: 'typeof fm.location() == "object" ? fm.location().name() : g.data.lookup("acpl",fm.location()).name()',
932 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);',
937 $('catStrings').getString('staff.cat.copy_editor.field.circulation_library.label'),
939 render: 'typeof fm.circ_lib() == "object" ? fm.circ_lib().shortname() : g.data.hash.aou[ fm.circ_lib() ].shortname()',
940 //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);',
941 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);',
945 $('catStrings').getString('staff.cat.copy_editor.field.owning_library.label'),
947 render: 'fm.call_number();',
948 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,
952 $('catStrings').getString('staff.cat.copy_editor.field.copy_number.label'),
954 render: 'fm.copy_number() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.copy_number()',
955 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);',
965 $('catStrings').getString('staff.cat.copy_editor.field.circulate.label'),
967 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") )',
968 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);',
972 $('catStrings').getString('staff.cat.copy_editor.field.holdable.label'),
974 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") )',
975 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);',
979 $('catStrings').getString('staff.cat.copy_editor.field.age_based_hold_protection.label'),
981 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() )',
982 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);',
987 $('catStrings').getString('staff.cat.copy_editor.field.floating.label'),
989 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") )',
990 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);',
994 $('catStrings').getString('staff.cat.copy_editor.field.loan_duration.label'),
996 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; }',
997 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);',
1002 $('catStrings').getString('staff.cat.copy_editor.field.fine_level.label'),
1004 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; }',
1005 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);',
1010 $('catStrings').getString('staff.cat.copy_editor.field.circulate_as_type.label'),
1012 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',
1013 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);',
1017 $('catStrings').getString('staff.cat.copy_editor.field.circulation_modifier.label'),
1019 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()])',
1020 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);',
1027 $('catStrings').getString('staff.cat.copy_editor.field.alert_message.label'),
1029 render: 'fm.alert_message() == null ? $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null") : fm.alert_message()',
1030 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);',
1035 $('catStrings').getString('staff.cat.copy_editor.field.deposit.label'),
1037 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") )',
1038 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);',
1042 $('catStrings').getString('staff.cat.copy_editor.field.deposit_amount.label'),
1044 render: 'if (fm.deposit_amount() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.deposit_amount() ); }',
1045 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);',
1049 $('catStrings').getString('staff.cat.copy_editor.field.price.label'),
1051 render: 'if (fm.price() == null) { $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null"); } else { util.money.sanitize( fm.price() ); }',
1052 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);',
1057 $('catStrings').getString('staff.cat.copy_editor.field.opac_visible.label'),
1059 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") )',
1060 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);',
1064 $('catStrings').getString('staff.cat.copy_editor.field.reference.label'),
1066 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") )',
1067 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);',
1071 $('catStrings').getString('staff.cat.copy_editor.field.mint_condition.label'),
1073 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")',
1074 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);',
1086 /******************************************************************************************************/
1087 /* This loops through all our fieldnames and all the copies, tallying up counts for the different values */
1089 g.summarize = function( copies ) {
1090 /******************************************************************************************************/
1093 JSAN.use('util.date'); JSAN.use('util.money');
1096 for (var i in g.panes_and_field_names) {
1097 g.field_names = g.field_names.concat( g.panes_and_field_names[i] );
1099 g.field_names = g.field_names.concat( g.editable_stat_cat_names );
1100 g.field_names = g.field_names.concat( g.readonly_stat_cat_names );
1102 /******************************************************************************************************/
1103 /* Loop through the field names */
1105 for (var i = 0; i < g.field_names.length; i++) {
1107 var field_name = g.field_names[i][0];
1108 var render = g.field_names[i][1].render;
1109 var attr = g.field_names[i][1].attr;
1110 g.summary[ field_name ] = {};
1111 g.populated[ field_name ] = 1; // delete later if we encounter a copy with the field unset
1113 /******************************************************************************************************/
1114 /* Loop through the copies */
1116 for (var j = 0; j < copies.length; j++) {
1119 var cmd = render || ('fm.' + field_name + '();');
1120 var value = $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");
1122 /**********************************************************************************************/
1123 /* Try to retrieve the value for this field for this copy */
1126 value = eval( cmd );
1128 g.error.sdump('D_ERROR','Attempted ' + cmd + '\n' + E + '\n');
1130 if (typeof value == 'object' && value != null) {
1131 alert('FIXME: field_name = <' + field_name + '> value = <' + js2JSON(value) + '>\n');
1133 if (value == $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null")) {
1134 delete g.populated[field_name];
1137 /**********************************************************************************************/
1138 /* Tally the count */
1140 if (g.summary[ field_name ][ value ]) {
1141 g.summary[ field_name ][ value ]++;
1143 g.summary[ field_name ][ value ] = 1;
1147 g.error.sdump('D_TRACE','summary = ' + js2JSON(g.summary) + '\n');
1150 /******************************************************************************************************/
1151 /* Display the summarized data and inputs for editing */
1153 g.render = function() {
1155 /******************************************************************************************************/
1156 /* Library setup and clear any existing interface */
1158 JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
1160 for (var i in g.panes_and_field_names) {
1161 var p = document.getElementById(i);
1162 if (p) util.widgets.remove_children(p);
1165 /******************************************************************************************************/
1166 /* Populate the library filter menu for stat cats */
1169 for (var i = 0; i < g.panes_and_field_names.right_pane4.length; i++) {
1170 sc_libs[ g.panes_and_field_names.right_pane4[i][1].attr.sc_lib ] = true;
1173 for (var i in sc_libs) { sc_libs2.push( [ g.data.hash.aou[ i ].shortname(), i ] ); }
1175 var x = document.getElementById("stat_cat_lib_filter_menu").firstChild;
1176 JSAN.use('util.widgets'); util.widgets.remove_children(x);
1177 for (var i = 0; i < sc_libs2.length; i++) {
1178 var menuitem = document.createElement('menuitem');
1179 menuitem.setAttribute('id','filter_'+sc_libs2[i][1]);
1180 menuitem.setAttribute('type','checkbox');
1181 menuitem.setAttribute('checked','true');
1182 menuitem.setAttribute('label',sc_libs2[i][0]);
1183 menuitem.setAttribute('value',sc_libs2[i][1]);
1184 menuitem.setAttribute('oncommand','try{g.toggle_stat_cat_display(this);}catch(E){alert(E);}');
1185 x.appendChild(menuitem);
1188 /******************************************************************************************************/
1189 /* Prepare the panes */
1191 var groupbox; var caption; var vbox; var grid; var rows;
1193 /******************************************************************************************************/
1194 /* Loop through the field names */
1196 for (h in g.panes_and_field_names) {
1197 if (!document.getElementById(h)) continue;
1198 for (var i = 0; i < g.panes_and_field_names[h].length; i++) {
1200 var f = g.panes_and_field_names[h][i]; var fn = f[0]; var attr = f[1].attr;
1201 groupbox = document.createElement('groupbox'); document.getElementById(h).appendChild(groupbox);
1203 for (var a in attr) {
1204 groupbox.setAttribute(a,attr[a]);
1207 caption = document.createElement('caption'); groupbox.appendChild(caption);
1208 caption.setAttribute('label',fn);
1209 caption.setAttribute('id','caption_'+fn); // used for focus/keyboard navigation
1210 vbox = document.createElement('vbox'); groupbox.appendChild(vbox); // main display widget goes here
1211 if (typeof g.changed[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_changed'); }
1212 if (typeof g.required[fn] != 'undefined') { addCSSClass(vbox,'copy_editor_field_required'); }
1213 grid = util.widgets.make_grid( [ { 'flex' : 1 }, {}, {} ] ); vbox.appendChild(grid);
1214 grid.setAttribute('flex','1');
1215 rows = grid.lastChild;
1218 /**************************************************************************************/
1219 /* Loop through each value for the field */
1221 for (var j in g.summary[fn]) {
1222 var value = j; var count = g.summary[fn][j];
1223 row = document.createElement('row'); rows.appendChild(row);
1224 var label1 = document.createElement('description'); row.appendChild(label1);
1225 if (g.special_exception[ fn ]) {
1226 g.special_exception[ fn ]( label1, value );
1228 label1.appendChild( document.createTextNode(value) );
1230 var label2 = document.createElement('description'); row.appendChild(label2);
1233 copy_count = $('catStrings').getString('staff.cat.copy_editor.copy_count');
1235 copy_count = $('catStrings').getFormattedString('staff.cat.copy_editor.copy_count.plural', [count]);
1237 label2.appendChild( document.createTextNode(copy_count) );
1239 groupbox.setAttribute('id','groupbox_'+fn); // this id is meant to be referenced by cat_custom.css for hiding fields
1240 var hbox = document.createElement('hbox'); // main input controls go here
1241 hbox.setAttribute('id',fn); // this id gets used to color areas green, etc.
1242 groupbox.appendChild(hbox);
1243 var hbox2 = document.createElement('hbox'); // cancel/apply buttons go here
1244 groupbox.appendChild(hbox2);
1246 /**************************************************************************************/
1247 /* Render the input widget */
1249 if (f[1].input && g.edit) {
1250 g.render_input(hbox,f[1]);
1254 g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
1260 /******************************************************************************************************/
1261 /* Synchronize stat cat visibility with library filter menu, and default template selection */
1262 JSAN.use('util.file');
1263 var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1264 g.copy_editor_prefs = util.widgets.load_attributes(file);
1265 for (var i in g.copy_editor_prefs) {
1266 if (i.match(/filter_/) && g.copy_editor_prefs[i].checked == '') {
1268 g.toggle_stat_cat_display( document.getElementById(i) );
1269 } catch(E) { alert(E); }
1272 if (g.template_menu) g.template_menu.value = g.template_menu.getAttribute('value');
1276 /******************************************************************************************************/
1277 /* This actually draws the change button and input widget for a given field */
1278 g.render_input = function(node,blob) {
1280 // node = hbox ; groupbox -> hbox, hbox
1282 var groupbox = node.parentNode;
1283 var caption = groupbox.firstChild;
1284 var vbox = node.previousSibling;
1286 var hbox2 = node.nextSibling;
1288 var input_cmd = blob.input;
1289 var render_cmd = blob.render;
1290 var attr = blob.attr;
1292 var block = false; var first = true;
1294 function on_mouseover(ev) {
1295 groupbox.setAttribute('style','background: white');
1298 function on_mouseout(ev) {
1299 groupbox.setAttribute('style','');
1302 vbox.addEventListener('mouseover',on_mouseover,false);
1303 vbox.addEventListener('mouseout',on_mouseout,false);
1304 groupbox.addEventListener('mouseover',on_mouseover,false);
1305 groupbox.addEventListener('mouseout',on_mouseout,false);
1306 groupbox.firstChild.addEventListener('mouseover',on_mouseover,false);
1307 groupbox.firstChild.addEventListener('mouseout',on_mouseout,false);
1309 function on_click(ev){
1311 if (block || g.disabled || !g.edit) {
1318 function post_c(v) {
1320 /* FIXME - kludgy */
1321 var t = input_cmd.match('apply_stat_cat') ? 'stat_cat' : ( input_cmd.match('apply_owning_lib') ? 'owning_lib' : 'attribute' );
1325 f = input_cmd.match(/apply\("(.+?)",/)[1];
1328 f = input_cmd.match(/apply_stat_cat\((.+?),/)[1];
1334 g.changed[ hbox.id ] = { 'type' : t, 'field' : f, 'value' : v };
1338 g.summarize( g.copies );
1340 g.check_for_unmet_required_fields();
1341 document.getElementById(caption.id).focus();
1345 g.error.standard_unexpected_error_alert('post_c',E);
1348 var x; var c; eval( input_cmd );
1350 util.widgets.remove_children(vbox);
1351 util.widgets.remove_children(hbox);
1352 util.widgets.remove_children(hbox2);
1353 hbox.appendChild(x);
1354 var apply = document.createElement('button');
1355 apply.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.apply.label'));
1356 apply.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_editor.apply.accesskey'));
1357 hbox2.appendChild(apply);
1358 apply.addEventListener('command',function() { c(x.value); },false);
1359 var cancel = document.createElement('button');
1360 cancel.setAttribute('label', $('catStrings').getString('staff.cat.copy_editor.cancel.label'));
1361 cancel.addEventListener('command',function() {
1362 setTimeout( function() {
1363 g.summarize( g.copies );
1365 g.check_for_unmet_required_fields();
1366 document.getElementById(caption.id).focus();
1371 hbox2.appendChild(cancel);
1372 setTimeout( function() { x.focus(); }, 0 );
1375 g.error.standard_unexpected_error_alert('render_input',E);
1378 vbox.addEventListener('click',on_click, false);
1379 hbox.addEventListener('click',on_click, false);
1380 caption.addEventListener('click',on_click, false);
1381 caption.addEventListener('keypress',function(ev) {
1382 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) on_click();
1384 caption.setAttribute('style','-moz-user-focus: normal');
1385 caption.setAttribute('onfocus','this.setAttribute("class","outline_me")');
1386 caption.setAttribute('onblur','this.setAttribute("class","")');
1389 g.error.sdump('D_ERROR',E + '\n');
1393 /******************************************************************************************************/
1394 /* store the copies in the global xpcom stash */
1396 g.stash_and_close = function() {
1400 if (g.handle_update) {
1402 var r = g.network.request(
1403 api.FM_ACP_FLESHED_BATCH_UPDATE.app,
1404 api.FM_ACP_FLESHED_BATCH_UPDATE.method,
1405 [ ses(), g.copies, true ]
1407 if (typeof r.ilsevent != 'undefined') {
1408 g.error.standard_unexpected_error_alert('copy update',r);
1410 /* FIXME -- revisit the return value here */
1412 alert($('catStrings').getString('staff.cat.copy_editor.handle_update.error') + ' ' + js2JSON(E));
1415 //g.data.temp_copies = js2JSON( g.copies );
1416 //g.data.stash('temp_copies');
1417 xulG.copies = g.copies;
1418 update_modal_xulG(xulG);
1419 JSAN.use('util.widgets');
1420 util.widgets.dispatch('close',window);
1422 alert('Error in copy_editor.js, g.stash_and_close(): '+E);
1426 /******************************************************************************************************/
1427 /* spawn copy notes interface */
1429 g.copy_notes = function() {
1430 JSAN.use('util.window'); var win = new util.window();
1432 urls.XUL_COPY_NOTES,
1433 //+ '?copy_id=' + window.escape(g.copies[0].id()),
1434 $("catStrings").getString("staff.cat.copy_editor.copy_notes"),'chrome,resizable,modal',
1435 { 'copy_id' : g.copies[0].id() }
1439 /******************************************************************************************************/
1440 /* hides or unhides stat cats based on library stat cat filter menu */
1441 g.toggle_stat_cat_display = function(el) {
1443 var visible = el.getAttribute('checked');
1444 var nl = document.getElementsByAttribute('sc_lib',el.getAttribute('value'));
1445 for (var n = 0; n < nl.length; n++) {
1447 nl[n].setAttribute('hidden','false');
1449 nl[n].setAttribute('hidden','true');
1452 g.copy_editor_prefs[ el.getAttribute('id') ] = { 'checked' : visible };
1453 g.save_attributes();
1456 /******************************************************************************************************/
1457 /* This adds a stat cat definition to the stat cat pane for rendering */
1458 g.save_attributes = function() {
1459 JSAN.use('util.widgets'); JSAN.use('util.file'); var file = new util.file('copy_editor_prefs.'+g.data.server_unadorned);
1460 var what_to_save = {};
1461 for (var i in g.copy_editor_prefs) {
1462 what_to_save[i] = [];
1463 for (var j in g.copy_editor_prefs[i]) what_to_save[i].push(j);
1465 util.widgets.save_attributes(file, what_to_save );
1468 /******************************************************************************************************/
1469 /* This adds a stat cat definition to the stat cat pane for rendering */
1470 g.add_stat_cat = function(sc) {
1472 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; g.data.stash('hash'); }
1476 if (typeof sc == 'object') {
1481 if (typeof g.stat_cat_seen[sc_id] != 'undefined') { return; }
1483 g.stat_cat_seen[ sc_id ] = 1;
1485 if (typeof sc != 'object') {
1487 sc = g.network.simple_request(
1488 'FM_ASC_BATCH_RETRIEVE',
1489 [ ses(), [ sc_id ] ]
1494 g.data.hash.asc[ sc.id() ] = sc; g.data.stash('hash');
1496 var label_name = g.data.hash.aou[ sc.owner() ].shortname() + " : " + sc.name();
1498 if (get_bool( sc.required() )) {
1499 g.required[ label_name ] = 1;
1505 render: 'var l = util.functional.find_list( fm.stat_cat_entries(), function(e){ return e.stat_cat() == '
1506 + sc.id() + '; } ); l ? l.value() : $("catStrings").getString("staff.cat.copy_editor.field.unset_or_null");',
1507 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()
1508 + '].entries(), function(obj){ return [ obj.value(), obj.id() ]; } ) ).sort() ); '
1509 + 'x.addEventListener("apply",function(f){ return function(ev) { f(ev.target.value); } }(c),false);',
1516 g.panes_and_field_names.right_pane4.push( temp_array );
1518 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.add_stat_cat.error'), E);
1522 /******************************************************************************************************/
1523 /* Add stat cats to the panes_and_field_names.right_pane4 */
1524 g.populate_stat_cats = function() {
1526 g.data.stash_retrieve();
1527 g.stat_cat_seen = {}; // used for determining whether a stat cat is displayed (and is eligible to be manipulated via a template)
1529 function get(lib_id,only_these) {
1530 g.data.stash_retrieve();
1531 var label = 'asc_list_for_lib_'+lib_id;
1532 if (typeof g.data[label] == 'undefined') {
1533 var robj = g.network.simple_request('FM_ASC_RETRIEVE_VIA_AOU', [ ses(), lib_id ]);
1534 if (typeof robj.ilsevent != 'undefined') throw(robj);
1536 for (var j = 0; j < robj.length; j++) {
1537 var my_asc = robj[j];
1538 if (typeof g.data.hash.asc == 'undefined') { g.data.hash.asc = {}; }
1539 if (typeof g.data.hash.asc[ my_asc.id() ] == 'undefined') {
1540 g.data.hash.asc[ my_asc.id() ] = my_asc;
1542 var only_this_lib = my_asc.owner(); if (typeof only_this_lib == 'object') only_this_lib = only_this_lib.id();
1543 if (only_these.indexOf( String( only_this_lib ) ) != -1) {
1544 temp_list.push( my_asc );
1547 g.data[label] = temp_list; g.data.stash(label,'hash','list');
1549 return g.data[label];
1552 /* The stat cats for the pertinent library -- this is based on workstation ou */
1553 var label = 'asc_list_for_' + typeof g.data.ws_ou == 'object' ? g.data.ws_ou.id() : g.data.ws_ou;
1554 g.data[ label ] = g.data.list.my_asc; g.data.stash('label');
1555 for (var i = 0; i < g.data.list.my_asc.length; i++) {
1556 g.add_stat_cat( g.data.list.my_asc[i] );
1559 /* For the others, we want to consider the owning libs, circ libs, and any libs that have stat cats already on the copies,
1560 however, if batch editing, we only want to show the ones they have in common. So let's compile the libs */
1562 function add_common_ancestors(sc_libs) {
1563 JSAN.use('util.fm_utils');
1564 var libs = []; for (var i in sc_libs) libs.push(i);
1565 var ancestor = util.fm_utils.find_common_aou_ancestor( libs );
1566 if (typeof ancestor == 'object' && ancestor != null) ancestor = ancestor.id();
1568 var ancestors = util.fm_utils.find_common_aou_ancestors( libs );
1569 var asc_list = get(ancestor, ancestors);
1570 for (var i = 0; i < asc_list.length; i++) {
1571 g.add_stat_cat( asc_list[i] );
1576 /* stat cats based on stat cat entries present on these copies */
1578 for (var i = 0; i < g.copies.length; i++) {
1579 var entries = g.copies[i].stat_cat_entries();
1580 if (!entries) entries = [];
1581 for (var j = 0; j < entries.length; j++) {
1582 var lib = entries[j].owner(); if (typeof lib == 'object') lib = lib.id();
1583 sc_libs[ lib ] = true;
1586 add_common_ancestors(sc_libs); // CAVEAT - if a copy has no stat_cat_entries, it basically gets no vote here
1588 /* stat cats based on Circ Lib */
1590 for (var i = 0; i < g.copies.length; i++) {
1591 var circ_lib = g.copies[i].circ_lib(); if (typeof circ_lib == 'object') circ_lib = circ_lib.id();
1592 sc_libs[ circ_lib ] = true;
1594 add_common_ancestors(sc_libs);
1596 /* stat cats based on Owning Lib */
1598 for (var i = 0; i < g.copies.length; i++) {
1599 var cn_id = g.copies[i].call_number();
1601 if (! g.map_acn[ cn_id ]) {
1602 var req = g.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ cn_id ]);
1603 if (typeof req.ilsevent == 'undefined') {
1604 g.map_acn[ cn_id ] = req;
1609 var owning_lib = g.map_acn[ cn_id ].owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
1610 sc_libs[ owning_lib ] = true;
1613 add_common_ancestors(sc_libs); // CAVEAT - if a copy is a pre-cat, it basically gets no vote here
1615 g.panes_and_field_names.right_pane4.sort();
1619 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_editor.populate_stat_cat.error'),E);
1623 g.check_for_unmet_required_fields = function() {
1625 for (var fn in g.required) {
1626 if (typeof g.populated[fn] == 'undefined') {
1630 if (xulG.unified_interface) {
1631 if (abort.length > 0) {
1632 if (typeof xulG.lock_save_button == 'function') {
1633 xulG.lock_save_button();
1636 if (typeof xulG.unlock_save_button == 'function') {
1637 xulG.unlock_save_button();
1641 if (abort.length > 0) {
1642 $('save').setAttribute('disabled','true');
1644 $('save').setAttribute('disabled','false');