]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/cat/marcedit.js
Enable the 001 and 003 control fields to be edited
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / cat / marcedit.js
1 // vim: noet:sw=4:ts=4:
2 var xmlDeclaration = /^<\?xml version[^>]+?>/;
3
4 var serializer = new XMLSerializer();
5 var marcns = new Namespace("http://www.loc.gov/MARC21/slim");
6 var gw = new Namespace("http://opensrf.org/-/namespaces/gateway/v1");
7 var xulns = new Namespace("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
8 default xml namespace = marcns;
9
10 var tooltip_hash = {};
11 var current_focus;
12 var _record;
13 var _record_type;
14 var bib_data;
15
16 var xml_record;
17
18 var context_menus;
19 var tag_menu;
20 var p;
21
22 function $(id) { return document.getElementById(id); }
23
24 function mangle_005() {
25         var now = new Date();
26         var y = now.getUTCFullYear();
27
28         var m = now.getUTCMonth() + 1;
29         if (m < 10) m = '0' + m;
30         
31         var d = now.getUTCDate();
32         if (d < 10) d = '0' + d;
33         
34         var H = now.getUTCHours();
35         if (H < 10) H = '0' + H;
36         
37         var M = now.getUTCMinutes();
38         if (M < 10) M = '0' + M;
39         
40         var S = now.getUTCSeconds();
41         if (S < 10) S = '0' + S;
42         
43
44         var stamp = '' + y + m + d + H + M + S + '.0';
45         createControlField('005',stamp);
46
47 }
48
49 function createControlField (tag,data) {
50         // first, remove the old field, if any;
51         for (var i in xml_record.controlfield.(@tag == tag)) delete xml_record.controlfield.(@tag == tag)[i];
52
53         var cf = <controlfield tag="" xmlns="http://www.loc.gov/MARC21/slim">{ data }</controlfield>;
54         cf.@tag = tag;
55
56         // then, find the right position and insert it
57         var done = 0;
58         var cfields = xml_record.controlfield;
59         var base = Number(tag.substring(2));
60         for (var i in cfields) {
61                 var t = Number(cfields[i].@tag.toString().substring(2));
62                 if (t > base) {
63                         xml_record.insertChildBefore( cfields[i], cf );
64                         done = 1
65                         break;
66                 }
67         }
68
69         if (!done) xml_record.insertChildBefore( xml_record.datafield[0], cf );
70
71         return cf;
72 }
73
74 function xml_escape_unicode ( str ) {
75         return str.replace(
76                 /([\u0080-\ufffe])/g,
77                 function (r,s) { return "&#x" + s.charCodeAt(0).toString(16) + ";"; }
78         );
79 }
80
81 function my_init() {
82         try {
83
84                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
85                 if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
86                 JSAN.errorLevel = "die"; // none, warn, or die
87                 JSAN.addRepository('/xul/server/');
88
89                 // Fake xulG for standalone...
90                 try {
91                         window.xulG.record;
92                 } catch (e) {
93                         window.xulG = {};
94                         window.xulG.record = {};
95                         window.xulG.save = {};
96
97                         window.xulG.save.label = $('catStrings').getString('staff.cat.marcedit.save.label');
98                         window.xulG.save.func = function (r) { alert(r); }
99
100                         var cgi = new CGI();
101                         var _rid = cgi.param('record');
102                         if (_rid) {
103                                 window.xulG.record.url = '/opac/extras/supercat/retrieve/marcxml/record/' + _rid;
104                         }
105                 }
106                 // End faking part...
107
108                 document.getElementById('save-button').setAttribute('label', window.xulG.save.label);
109                 document.getElementById('save-button').setAttribute('oncommand',
110                         'mangle_005(); ' + 
111                         'var xml_string = xml_escape_unicode( xml_record.toXMLString() ); ' + 
112                         'save_attempt( xml_string ); ' +
113                         'loadRecord(xml_record);'
114                 );
115
116                 if (window.xulG.record.url) {
117                         var req =  new XMLHttpRequest();
118                         req.open('POST',window.xulG.record.url,false);
119                         req.send(null);
120                         window.xulG.record.marc = req.responseText.replace(xmlDeclaration, '');
121                 }
122
123                 xml_record = new XML( window.xulG.record.marc );
124                 if (xml_record..record[0]) xml_record = xml_record..record[0];
125
126                 // Get the tooltip xml all async like
127                 req =  new XMLHttpRequest();
128
129                 // Set a default locale in case preferences fail us
130                 var locale = "en-US";
131
132                 // Try to get the locale from our preferences
133                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
134                 try {
135                         const Cc = Components.classes;
136                         const Ci = Components.interfaces;
137                         locale = Cc["@mozilla.org/preferences-service;1"].
138                                 getService(Ci.nsIPrefBranch).
139                                 getCharPref("general.useragent.locale");
140                 }
141                 catch (e) { }
142
143                 // TODO: We should send a HEAD request to check for the existence of the desired file
144                 // then fall back to the default locale if preferred locale is not necessary;
145                 // however, for now we have a simplistic check:
146                 //
147                 // we currently have translations for only two locales; in the absence of a
148                 // valid locale, default to the almighty en-US
149                 if (locale != 'en-US' && locale != 'fr-CA') {
150                         locale = 'en-US';
151                 }
152
153                 // Get the locale-specific tooltips
154                 req.open('GET','/xul/server/locale/' + locale + '/marcedit-tooltips.xml',true);
155
156                 context_menus = createComplexXULElement('popupset');
157                 document.documentElement.appendChild( context_menus );
158
159                 tag_menu = createPopup({position : 'after_start', id : 'tags_popup'});
160                 context_menus.appendChild( tag_menu );
161
162                 tag_menu.appendChild(
163                         createMenuitem(
164                                 { label : $('catStrings').getString('staff.cat.marcedit.add_row.label'),
165                                   oncommand : 
166                                         'var e = document.createEvent("KeyEvents");' +
167                                         'e.initKeyEvent("keypress",1,1,null,1,0,0,0,13,0);' +
168                                         'current_focus.inputField.dispatchEvent(e);'
169                                  }
170                         )
171                 );
172
173                 tag_menu.appendChild(
174                         createMenuitem(
175                                 { label : $('catStrings').getString('staff.cat.marcedit.insert_row.label'),
176                                   oncommand : 
177                                         'var e = document.createEvent("KeyEvents");' +
178                                         'e.initKeyEvent("keypress",1,1,null,1,0,1,0,13,0);' +
179                                         'current_focus.inputField.dispatchEvent(e);'
180                                  }
181                         )
182                 );
183
184                 tag_menu.appendChild(
185                         createMenuitem(
186                                 { label : $('catStrings').getString('staff.cat.marcedit.remove_row.label'),
187                                   oncommand : 
188                                         'var e = document.createEvent("KeyEvents");' +
189                                         'e.initKeyEvent("keypress",1,1,null,1,0,0,0,46,0);' +
190                                         'current_focus.inputField.dispatchEvent(e);'
191                                 }
192                         )
193                 );
194
195                 tag_menu.appendChild( createComplexXULElement( 'separator' ) );
196
197                 tag_menu.appendChild(
198                         createMenuitem(
199                                 { label : $('catStrings').getString('staff.cat.marcedit.replace_006.label'),
200                                   oncommand : 
201                                         'var e = document.createEvent("KeyEvents");' +
202                                         'e.initKeyEvent("keypress",1,1,null,1,0,0,0,64,0);' +
203                                         'current_focus.inputField.dispatchEvent(e);'
204                                  }
205                         )
206                 );
207
208                 tag_menu.appendChild(
209                         createMenuitem(
210                                 { label : $('catStrings').getString('staff.cat.marcedit.replace_007.label'),
211                                   oncommand : 
212                                         'var e = document.createEvent("KeyEvents");' +
213                                         'e.initKeyEvent("keypress",1,1,null,1,0,0,0,65,0);' +
214                                         'current_focus.inputField.dispatchEvent(e);'
215                                 }
216                         )
217                 );
218
219                 tag_menu.appendChild(
220                         createMenuitem(
221                                 { label : $('catStrings').getString('staff.cat.marcedit.replace_008.label'),
222                                   oncommand : 
223                                         'var e = document.createEvent("KeyEvents");' +
224                                         'e.initKeyEvent("keypress",1,1,null,1,0,0,0,66,0);' +
225                                         'current_focus.inputField.dispatchEvent(e);'
226                                 }
227                         )
228                 );
229
230                 tag_menu.appendChild( createComplexXULElement( 'separator' ) );
231
232                 p = createComplexXULElement('popupset');
233                 document.documentElement.appendChild( p );
234
235                 req.onreadystatechange = function () {
236                         if (req.readyState == 4) {
237                                 bib_data = new XML( req.responseText.replace(xmlDeclaration, '') );
238                                 genToolTips();
239                         }
240                 }
241                 req.send(null);
242
243                 loadRecord(xml_record);
244
245         if (! xulG.fast_add_item) {
246             document.getElementById('fastItemAdd_checkbox').hidden = true;
247         }
248         document.getElementById('fastItemAdd_textboxes').hidden = document.getElementById('fastItemAdd_checkbox').hidden || !document.getElementById('fastItemAdd_checkbox').checked;
249
250         } catch(E) {
251                 alert('FIXME, MARC Editor, my_init: ' + E);
252         }
253 }
254
255
256 function createComplexHTMLElement (e, attrs, objects, text) {
257         var l = document.createElementNS('http://www.w3.org/1999/xhtml',e);
258
259         if (attrs) {
260                 for (var i in attrs) l.setAttribute(i,attrs[i]);
261         }
262
263         if (objects) {
264                 for ( var i in objects ) l.appendChild( objects[i] );
265         }
266
267         if (text) {
268                 l.appendChild( document.createTextNode(text) )
269         }
270
271         return l;
272 }
273
274 function createComplexXULElement (e, attrs, objects) {
275         var l = document.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul',e);
276
277         if (attrs) {
278                 for (var i in attrs) {
279                         if (typeof attrs[i] == 'function') {
280                                 l.addEventListener( i, attrs[i], true );
281                         } else {
282                                 l.setAttribute(i,attrs[i]);
283                         }
284                 }
285         } 
286
287         if (objects) {
288                 for ( var i in objects ) l.appendChild( objects[i] );
289         }
290
291         return l;
292 }
293
294 function createDescription (attrs) {
295         return createComplexXULElement('description', attrs, Array.prototype.slice.apply(arguments, [1]) );
296 }
297
298 function createTooltip (attrs) {
299         return createComplexXULElement('tooltip', attrs, Array.prototype.slice.apply(arguments, [1]) );
300 }
301
302 function createLabel (attrs) {
303         return createComplexXULElement('label', attrs, Array.prototype.slice.apply(arguments, [1]) );
304 }
305
306 function createVbox (attrs) {
307         return createComplexXULElement('vbox', attrs, Array.prototype.slice.apply(arguments, [1]) );
308 }
309
310 function createHbox (attrs) {
311         return createComplexXULElement('hbox', attrs, Array.prototype.slice.apply(arguments, [1]) );
312 }
313
314 function createRow (attrs) {
315         return createComplexXULElement('row', attrs, Array.prototype.slice.apply(arguments, [1]) );
316 }
317
318 function createTextbox (attrs) {
319         return createComplexXULElement('textbox', attrs, Array.prototype.slice.apply(arguments, [1]) );
320 }
321
322 function createMenu (attrs) {
323         return createComplexXULElement('menu', attrs, Array.prototype.slice.apply(arguments, [1]) );
324 }
325
326 function createMenuPopup (attrs) {
327         return createComplexXULElement('menupopup', attrs, Array.prototype.slice.apply(arguments, [1]) );
328 }
329
330 function createPopup (attrs) {
331         return createComplexXULElement('popup', attrs, Array.prototype.slice.apply(arguments, [1]) );
332 }
333
334 function createMenuitem (attrs) {
335         return createComplexXULElement('menuitem', attrs, Array.prototype.slice.apply(arguments, [1]) );
336 }
337
338 function createCheckbox (attrs) {
339         return createComplexXULElement('checkbox', attrs, Array.prototype.slice.apply(arguments, [1]) );
340 }
341
342 function createMARCTextbox (element,attrs) {
343
344         var box = createComplexXULElement('textbox', attrs, Array.prototype.slice.apply(arguments, [2]) );
345         box.onkeypress = function (event) {
346                 var root_node;
347                 var node = element;
348                 while(node = node.parent()) {
349                         root_node = node;
350                 }
351
352                 var row = event.target;
353                 while (row.tagName != 'row') row = row.parentNode;
354
355                 if (element.nodeKind() == 'attribute') element[0]=box.value;
356                 else element.setChildren( box.value );
357
358                 if (element.localName() != 'controlfield') {
359                         if ((event.charCode == 100 || event.charCode == 105) && event.ctrlKey) { // ctrl+d or ctrl+i
360
361                                 var index_sf, target, move_data;
362                                 if (element.localName() == 'subfield') {
363                                         index_sf = element;
364                                         target = event.target.parentNode;
365
366                                         var start = event.target.selectionStart;
367                                         var end = event.target.selectionEnd - event.target.selectionStart ?
368                                                         event.target.selectionEnd :
369                                                         event.target.value.length;
370
371                                         move_data = event.target.value.substring(start,end);
372                                         event.target.value = event.target.value.substring(0,start) + event.target.value.substring(end);
373                                         event.target.setAttribute('size', event.target.value.length + 2);
374         
375                                         element.setChildren( event.target.value );
376
377                                 } else if (element.localName() == 'code') {
378                                         index_sf = element.parent();
379                                         target = event.target.parentNode;
380                                 } else if (element.localName() == 'tag' || element.localName() == 'ind1' || element.localName() == 'ind2') {
381                                         index_sf = element.parent().children()[element.parent().children().length() - 1];
382                                         target = event.target.parentNode.lastChild.lastChild;
383                                 }
384
385                                 var sf = <subfield code="" xmlns="http://www.loc.gov/MARC21/slim">{ move_data }</subfield>;
386
387                                 index_sf.parent().insertChildAfter( index_sf, sf );
388
389                                 var new_sf = marcSubfield(sf);
390
391                                 if (target === target.parentNode.lastChild) {
392                                         target.parentNode.appendChild( new_sf );
393                                 } else {
394                                         target.parentNode.insertBefore( new_sf, target.nextSibling );
395                                 }
396
397                                 new_sf.firstChild.nextSibling.focus();
398
399                                 event.preventDefault();
400                                 return false;
401
402                         } else if (event.keyCode == 13 || event.keyCode == 77) {
403                                 if (event.ctrlKey) { // ctrl+enter
404
405                                         var index;
406                                         if (element.localName() == 'subfield') index = element.parent();
407                                         if (element.localName() == 'code') index = element.parent().parent();
408                                         if (element.localName() == 'tag') index = element.parent();
409                                         if (element.localName() == 'ind1') index = element.parent();
410                                         if (element.localName() == 'ind2') index = element.parent();
411
412                                         var df = <datafield tag="" ind1="" ind2="" xmlns="http://www.loc.gov/MARC21/slim"><subfield code="" /></datafield>;
413
414                                         if (event.shiftKey) { // ctrl+shift+enter
415                                                 index.parent().insertChildBefore( index, df );
416                                         } else {
417                                                 index.parent().insertChildAfter( index, df );
418                                         }
419
420                                         var new_df = marcDatafield(df);
421
422                                         if (row.parentNode.lastChild === row) {
423                                                 row.parentNode.appendChild( new_df );
424                                         } else {
425                                                 if (event.shiftKey) { // ctrl+shift+enter
426                                                         row.parentNode.insertBefore( new_df, row );
427                                                 } else {
428                                                         row.parentNode.insertBefore( new_df, row.nextSibling );
429                                                 }
430                                         }
431
432                                         new_df.firstChild.focus();
433
434                                         event.preventDefault();
435                                         return false;
436
437                                 } else if (event.shiftKey) {
438                                         if (row.previousSibling.className.match('marcDatafieldRow'))
439                                                 row.previousSibling.firstChild.focus();
440                                 } else {
441                                         row.nextSibling.firstChild.focus();
442                                 }
443
444                         } else if (event.keyCode == 38 || event.keyCode == 40) { // up-arrow or down-arrow
445                                 if (event.ctrlKey) { // CTRL key: copy the field
446                                         var index;
447                                         if (element.localName() == 'subfield') index = element.parent();
448                                         if (element.localName() == 'code') index = element.parent().parent();
449                                         if (element.localName() == 'tag') index = element.parent();
450                                         if (element.localName() == 'ind1') index = element.parent();
451                                         if (element.localName() == 'ind2') index = element.parent();
452
453                                         var copyField = index.copy();
454
455                                         if (event.keyCode == 38) { // ctrl+up-arrow
456                                                 index.parent().insertChildBefore( index, copyField );
457                                         } else {
458                                                 index.parent().insertChildAfter( index, copyField );
459                                         }
460
461                                         var new_df = marcDatafield(copyField);
462
463                                         if (row.parentNode.lastChild === row) {
464                                                 row.parentNode.appendChild( new_df );
465                                         } else {
466                                                 if (event.keyCode == 38) { // ctrl+up-arrow
467                                                         row.parentNode.insertBefore( new_df, row );
468                                                 } else { // ctrl+down-arrow
469                                                         row.parentNode.insertBefore( new_df, row.nextSibling );
470                                                 }
471                                         }
472
473                                         new_df.firstChild.focus();
474
475                                         event.preventDefault();
476
477                                         return false;
478                                 }
479
480                         } else if (event.keyCode == 46 && event.ctrlKey) { // ctrl+del
481
482                                 var index;
483                                 if (element.localName() == 'subfield') index = element.parent();
484                                 if (element.localName() == 'code') index = element.parent().parent();
485                                 if (element.localName() == 'tag') index = element.parent();
486                                 if (element.localName() == 'ind1') index = element.parent();
487                                 if (element.localName() == 'ind2') index = element.parent();
488
489                                 for (var i in index.parent().children()) {
490                                         if (index === index.parent().children()[i]) {
491                                                 delete index.parent().children()[i];
492                                                 break;
493                                         }
494                                 }
495
496                                 row.previousSibling.firstChild.focus();
497                                 row.parentNode.removeChild(row);
498
499                                 event.preventDefault();
500                                 return false;
501
502                         } else if (event.keyCode == 46 && event.shiftKey) { // shift+del
503
504                                 var index;
505                                 if (element.localName() == 'subfield') index = element;
506                                 if (element.localName() == 'code') index = element.parent();
507
508                                 if (index) {
509                                         for (var i in index.parent().children()) {
510                                                 if (index === index.parent().children()[i]) {
511                                                         delete index.parent().children()[i];
512                                                         break;
513                                                 }
514                                         }
515
516                                         if (event.target.parentNode === event.target.parentNode.parentNode.lastChild) {
517                                                 event.target.parentNode.previousSibling.lastChild.focus();
518                                         } else {
519                                                 event.target.parentNode.nextSibling.firstChild.nextSibling.focus();
520                                         }
521
522                                         event.target.parentNode.parentNode.removeChild(event.target.parentNode);
523
524                                         event.preventDefault();
525                                         return false;
526                                 }
527                         } else if (event.keyCode == 64 && event.ctrlKey) { // ctrl + F6
528                                 createControlField('006','');
529                                 loadRecord(xml_record);
530                         } else if (event.keyCode == 65 && event.ctrlKey) { // ctrl + F7
531                                 createControlField('007','');
532                                 loadRecord(xml_record);
533                         } else if (event.keyCode == 66 && event.ctrlKey) { // ctrl + F8
534                                 createControlField('008','');
535                                 loadRecord(xml_record);
536                         }
537                         return true;
538                 }
539         };
540
541         box.addEventListener(
542                 'keypress', 
543                 function () {
544                         if (element.nodeKind() == 'attribute') element[0]=box.value;
545                         else element.setChildren( box.value );
546                         return true;
547                 },
548                 false
549         );
550
551         box.addEventListener(
552                 'change', 
553                 function () {
554                         if (element.nodeKind() == 'attribute') element[0]=box.value;
555                         else element.setChildren( box.value );
556                         return true;
557                 },
558                 false
559         );
560
561         box.addEventListener(
562                 'keypress', 
563                 function () {
564                         if (element.nodeKind() == 'attribute') element[0]=box.value;
565                         else element.setChildren( box.value );
566                         return true;
567                 },
568                 true
569         );
570
571         box.addEventListener(
572                 'keyup', 
573                 function () {
574                         if (element.localName() == 'controlfield')
575                                 eval('fillFixedFields(xml_record);');
576                 },
577                 true
578         );
579
580         return box;
581 }
582
583 var rec_type = {
584         BKS : { Type : /[at]{1}/,       BLvl : /[acdm]{1}/ },
585         SER : { Type : /[a]{1}/,        BLvl : /[bs]{1}/ },
586         VIS : { Type : /[gkro]{1}/,     BLvl : /[abcdms]{1}/ },
587         MIX : { Type : /[p]{1}/,        BLvl : /[cd]{1}/ },
588         MAP : { Type : /[ef]{1}/,       BLvl : /[abcdms]{1}/ },
589         SCO : { Type : /[cd]{1}/,       BLvl : /[abcdms]{1}/ },
590         REC : { Type : /[ij]{1}/,       BLvl : /[abcdms]{1}/ },
591         COM : { Type : /[m]{1}/,        BLvl : /[abcdms]{1}/ }
592 };
593
594 var ff_pos = {
595         TrAr : {
596                 _8 : {
597                         SCO : {start : 33, len : 1, def : ' ' },
598                         REC : {start : 33, len : 1, def : 'n' }
599                 },
600                 _6 : {
601                         SCO : {start : 16, len : 1, def : ' ' },
602                         REC : {start : 16, len : 1, def : 'n' }
603                 }
604         },
605         TMat : {
606                 _8 : {
607                         VIS : {start : 33, len : 1, def : ' ' }
608                 },
609                 _6 : {
610                         VIS : {start : 16, len : 1, def : ' ' }
611                 }
612         },
613         Time : {
614                 _8 : {
615                         VIS : {start : 18, len : 3, def : ' ' }
616                 },
617                 _6 : {
618                         VIS : {start : 1, len : 3, def : ' ' }
619                 }
620         },
621         Tech : {
622                 _8 : {
623                         VIS : {start : 34, len : 1, def : 'n' }
624                 },
625                 _6 : {
626                         VIS : {start : 17, len : 1, def : 'n' }
627                 }
628         },
629         SrTp : {
630                 _8 : {
631                         SER : {start : 21, len : 1, def : ' ' }
632                 },
633                 _6 : {
634                         SER : {start : 4, len : 1, def : ' ' }
635                 }
636         },
637         Srce : {
638                 _8 : {
639                         BKS : {start : 39, len : 1, def : 'd' },
640                         SER : {start : 39, len : 1, def : 'd' },
641                         VIS : {start : 39, len : 1, def : 'd' },
642                         MIX : {start : 39, len : 1, def : 'd' },
643                         MAP : {start : 39, len : 1, def : 'd' },
644                         SCO : {start : 39, len : 1, def : 'd' },
645                         REC : {start : 39, len : 1, def : 'd' },
646                         COM : {start : 39, len : 1, def : 'd' }
647                 }
648         },
649         SpFm : {
650                 _8 : {
651                         MAP : {start : 33, len : 2, def : ' ' }
652                 },
653                 _6 : {
654                         MAP : {start : 16, len : 2, def : ' ' }
655                 }
656         },
657         Relf : {
658                 _8 : {
659                         MAP : {start : 18, len : 4, def : ' ' }
660                 },
661                 _6 : {
662                         MAP : {start : 1, len : 4, def : ' ' }
663                 }
664         },
665         Regl : {
666                 _8 : {
667                         SER : {start : 19, len : 1, def : ' ' }
668                 },
669                 _6 : {
670                         SER : {start : 2, len : 1, def : ' ' }
671                 }
672         },
673         Proj : {
674                 _8 : {
675                         MAP : {start : 22, len : 2, def : ' ' }
676                 },
677                 _6 : {
678                         MAP : {start : 5, len : 2, def : ' ' }
679                 }
680         },
681         Part : {
682                 _8 : {
683                         SCO : {start : 21, len : 1, def : ' ' },
684                         REC : {start : 21, len : 1, def : 'n' }
685                 },
686                 _6 : {
687                         SCO : {start : 4, len : 1, def : ' ' },
688                         REC : {start : 4, len : 1, def : 'n' }
689                 }
690         },
691         Orig : {
692                 _8 : {
693                         SER : {start : 22, len : 1, def : ' ' }
694                 },
695                 _6 : {
696                         SER : {start : 5, len : 1, def : ' ' }
697                 }
698         },
699         LTxt : {
700                 _8 : {
701                         SCO : {start : 30, len : 2, def : ' ' },
702                         REC : {start : 30, len : 2, def : ' ' }
703                 },
704                 _6 : {
705                         SCO : {start : 13, len : 2, def : ' ' },
706                         REC : {start : 13, len : 2, def : ' ' }
707                 }
708         },
709         Freq : {
710                 _8 : {
711                         SER : {start : 18, len : 1, def : ' ' }
712                 },
713                 _6 : {
714                         SER : {start : 1, len : 1, def : ' ' }
715                 }
716         },
717         FMus : {
718                 _8 : {
719                         SCO : {start : 20, len : 1, def : ' ' },
720                         REC : {start : 20, len : 1, def : 'n' }
721                 },
722                 _6 : {
723                         SCO : {start : 3, len : 1, def : ' ' },
724                         REC : {start : 3, len : 1, def : 'n' }
725                 }
726         },
727         File : {
728                 _8 : {
729                         COM : {start : 26, len : 1, def : 'u' }
730                 },
731                 _6 : {
732                         COM : {start : 9, len : 1, def : 'u' }
733                 }
734         },
735         EntW : {
736                 _8 : {
737                         SER : {start : 24, len : 1, def : ' ' }
738                 },
739                 _6 : {
740                         SER : {start : 7, len : 1, def : ' ' }
741                 }
742         },
743         AccM : {
744                 _8 : {
745                         SCO : {start : 24, len : 6, def : ' ' },
746                         REC : {start : 24, len : 6, def : ' ' }
747                 },
748                 _6 : {
749                         SCO : {start : 7, len : 6, def : ' ' },
750                         REC : {start : 7, len : 6, def : ' ' }
751                 }
752         },
753         Comp : {
754                 _8 : {
755                         SCO : {start : 18, len : 2, def : ' ' },
756                         REC : {start : 18, len : 2, def : ' ' }
757                 },
758                 _6 : {
759                         SCO : {start : 1, len : 2, def : ' ' },
760                         REC : {start : 1, len : 2, def : ' ' }
761                 }
762         },
763         CrTp : {
764                 _8 : {
765                         MAP : {start : 25, len : 1, def : ' ' }
766                 },
767                 _6 : {
768                         MAP : {start : 8, len : 1, def : ' ' }
769                 }
770         },
771         Ctry : {
772                 _8 : {
773                         BKS : {start : 15, len : 3, def : ' ' },
774                         SER : {start : 15, len : 3, def : ' ' },
775                         VIS : {start : 15, len : 3, def : ' ' },
776                         MIX : {start : 15, len : 3, def : ' ' },
777                         MAP : {start : 15, len : 3, def : ' ' },
778                         SCO : {start : 15, len : 3, def : ' ' },
779                         REC : {start : 15, len : 3, def : ' ' },
780                         COM : {start : 15, len : 3, def : ' ' }
781                 }
782         },
783         Lang : {
784                 _8 : {
785                         BKS : {start : 35, len : 3, def : ' ' },
786                         SER : {start : 35, len : 3, def : ' ' },
787                         VIS : {start : 35, len : 3, def : ' ' },
788                         MIX : {start : 35, len : 3, def : ' ' },
789                         MAP : {start : 35, len : 3, def : ' ' },
790                         SCO : {start : 35, len : 3, def : ' ' },
791                         REC : {start : 35, len : 3, def : ' ' },
792                         COM : {start : 35, len : 3, def : ' ' }
793                 }
794         },
795         MRec : {
796                 _8 : {
797                         BKS : {start : 38, len : 1, def : ' ' },
798                         SER : {start : 38, len : 1, def : ' ' },
799                         VIS : {start : 38, len : 1, def : ' ' },
800                         MIX : {start : 38, len : 1, def : ' ' },
801                         MAP : {start : 38, len : 1, def : ' ' },
802                         SCO : {start : 38, len : 1, def : ' ' },
803                         REC : {start : 38, len : 1, def : ' ' },
804                         COM : {start : 38, len : 1, def : ' ' }
805                 }
806         },
807         DtSt : {
808                 _8 : {
809                         BKS : {start : 6, len : 1, def : ' ' },
810                         SER : {start : 6, len : 1, def : 'c' },
811                         VIS : {start : 6, len : 1, def : ' ' },
812                         MIX : {start : 6, len : 1, def : ' ' },
813                         MAP : {start : 6, len : 1, def : ' ' },
814                         SCO : {start : 6, len : 1, def : ' ' },
815                         REC : {start : 6, len : 1, def : ' ' },
816                         COM : {start : 6, len : 1, def : ' ' }
817                 }
818         },
819         Type : {
820                 ldr : {
821                         BKS : {start : 6, len : 1, def : 'a' },
822                         SER : {start : 6, len : 1, def : 'a' },
823                         VIS : {start : 6, len : 1, def : 'g' },
824                         MIX : {start : 6, len : 1, def : 'p' },
825                         MAP : {start : 6, len : 1, def : 'e' },
826                         SCO : {start : 6, len : 1, def : 'c' },
827                         REC : {start : 6, len : 1, def : 'i' },
828                         COM : {start : 6, len : 1, def : 'm' }
829                 }
830         },
831         Ctrl : {
832                 ldr : {
833                         BKS : {start : 8, len : 1, def : ' ' },
834                         SER : {start : 8, len : 1, def : ' ' },
835                         VIS : {start : 8, len : 1, def : ' ' },
836                         MIX : {start : 8, len : 1, def : ' ' },
837                         MAP : {start : 8, len : 1, def : ' ' },
838                         SCO : {start : 8, len : 1, def : ' ' },
839                         REC : {start : 8, len : 1, def : ' ' },
840                         COM : {start : 8, len : 1, def : ' ' }
841                 }
842         },
843         BLvl : {
844                 ldr : {
845                         BKS : {start : 7, len : 1, def : 'm' },
846                         SER : {start : 7, len : 1, def : 's' },
847                         VIS : {start : 7, len : 1, def : 'm' },
848                         MIX : {start : 7, len : 1, def : 'c' },
849                         MAP : {start : 7, len : 1, def : 'm' },
850                         SCO : {start : 7, len : 1, def : 'm' },
851                         REC : {start : 7, len : 1, def : 'm' },
852                         COM : {start : 7, len : 1, def : 'm' }
853                 }
854         },
855         Desc : {
856                 ldr : {
857                         BKS : {start : 18, len : 1, def : ' ' },
858                         SER : {start : 18, len : 1, def : ' ' },
859                         VIS : {start : 18, len : 1, def : ' ' },
860                         MIX : {start : 18, len : 1, def : ' ' },
861                         MAP : {start : 18, len : 1, def : ' ' },
862                         SCO : {start : 18, len : 1, def : ' ' },
863                         REC : {start : 18, len : 1, def : ' ' },
864                         COM : {start : 18, len : 1, def : ' ' }
865                 }
866         },
867         ELvl : {
868                 ldr : {
869                         BKS : {start : 17, len : 1, def : ' ' },
870                         SER : {start : 17, len : 1, def : ' ' },
871                         VIS : {start : 17, len : 1, def : ' ' },
872                         MIX : {start : 17, len : 1, def : ' ' },
873                         MAP : {start : 17, len : 1, def : ' ' },
874                         SCO : {start : 17, len : 1, def : ' ' },
875                         REC : {start : 17, len : 1, def : ' ' },
876                         COM : {start : 17, len : 1, def : ' ' }
877                 }
878         },
879         Indx : {
880                 _8 : {
881                         BKS : {start : 31, len : 1, def : '0' },
882                         MAP : {start : 31, len : 1, def : '0' }
883                 },
884                 _6 : {
885                         BKS : {start : 14, len : 1, def : '0' },
886                         MAP : {start : 14, len : 1, def : '0' }
887                 }
888         },
889         Date1 : {
890                 _8 : {
891                         BKS : {start : 7, len : 4, def : ' ' },
892                         SER : {start : 7, len : 4, def : ' ' },
893                         VIS : {start : 7, len : 4, def : ' ' },
894                         MIX : {start : 7, len : 4, def : ' ' },
895                         MAP : {start : 7, len : 4, def : ' ' },
896                         SCO : {start : 7, len : 4, def : ' ' },
897                         REC : {start : 7, len : 4, def : ' ' },
898                         COM : {start : 7, len : 4, def : ' ' }
899                 }
900         },
901         Date2 : {
902                 _8 : {
903                         BKS : {start : 11, len : 4, def : ' ' },
904                         SER : {start : 11, len : 4, def : '9' },
905                         VIS : {start : 11, len : 4, def : ' ' },
906                         MIX : {start : 11, len : 4, def : ' ' },
907                         MAP : {start : 11, len : 4, def : ' ' },
908                         SCO : {start : 11, len : 4, def : ' ' },
909                         REC : {start : 11, len : 4, def : ' ' },
910                         COM : {start : 11, len : 4, def : ' ' }
911                 }
912         },
913         LitF : {
914                 _8 : {
915                         BKS : {start : 33, len : 1, def : '0' }
916                 },
917                 _6 : {
918                         BKS : {start : 16, len : 1, def : '0' }
919                 }
920         },
921         Biog : {
922                 _8 : {
923                         BKS : {start : 34, len : 1, def : ' ' }
924                 },
925                 _6 : {
926                         BKS : {start : 17, len : 1, def : ' ' }
927                 }
928         },
929         Ills : {
930                 _8 : {
931                         BKS : {start : 18, len : 4, def : ' ' }
932                 },
933                 _6 : {
934                         BKS : {start : 1, len : 4, def : ' ' }
935                 }
936         },
937         Fest : {
938                 _8 : {
939                         BKS : {start : 30, len : 1, def : '0' }
940                 },
941                 _6 : {
942                         BKS : {start : 13, len : 1, def : '0' }
943                 }
944         },
945         Conf : {
946                 _8 : {
947                         BKS : {start : 29, len : 1, def : '0' },
948                         SER : {start : 29, len : 1, def : '0' }
949                 },
950                 _6 : {
951                         BKS : {start : 12, len : 1, def : '0' },
952                         SER : {start : 12, len : 1, def : '0' }
953                 }
954         },
955         Cont : {
956                 _8 : {
957                         BKS : {start : 24, len : 4, def : ' ' },
958                         SER : {start : 25, len : 3, def : ' ' }
959                 },
960                 _6 : {
961                         BKS : {start : 7, len : 4, def : ' ' },
962                         SER : {start : 8, len : 3, def : ' ' }
963                 }
964         },
965         GPub : {
966                 _8 : {
967                         BKS : {start : 28, len : 1, def : ' ' },
968                         SER : {start : 28, len : 1, def : ' ' },
969                         VIS : {start : 28, len : 1, def : ' ' },
970                         MAP : {start : 28, len : 1, def : ' ' },
971                         COM : {start : 28, len : 1, def : ' ' }
972                 },
973                 _6 : {
974                         BKS : {start : 11, len : 1, def : ' ' },
975                         SER : {start : 11, len : 1, def : ' ' },
976                         VIS : {start : 11, len : 1, def : ' ' },
977                         MAP : {start : 11, len : 1, def : ' ' },
978                         COM : {start : 11, len : 1, def : ' ' }
979                 }
980         },
981         Audn : {
982                 _8 : {
983                         BKS : {start : 22, len : 1, def : ' ' },
984                         SER : {start : 22, len : 1, def : ' ' },
985                         VIS : {start : 22, len : 1, def : ' ' },
986                         SCO : {start : 22, len : 1, def : ' ' },
987                         REC : {start : 22, len : 1, def : ' ' },
988                         COM : {start : 22, len : 1, def : ' ' }
989                 },
990                 _6 : {
991                         BKS : {start : 5, len : 1, def : ' ' },
992                         SER : {start : 5, len : 1, def : ' ' },
993                         VIS : {start : 5, len : 1, def : ' ' },
994                         SCO : {start : 5, len : 1, def : ' ' },
995                         REC : {start : 5, len : 1, def : ' ' },
996                         COM : {start : 5, len : 1, def : ' ' }
997                 }
998         },
999         Form : {
1000                 _8 : {
1001                         BKS : {start : 23, len : 1, def : ' ' },
1002                         SER : {start : 23, len : 1, def : ' ' },
1003                         VIS : {start : 29, len : 1, def : ' ' },
1004                         MIX : {start : 23, len : 1, def : ' ' },
1005                         MAP : {start : 29, len : 1, def : ' ' },
1006                         SCO : {start : 23, len : 1, def : ' ' },
1007                         REC : {start : 23, len : 1, def : ' ' }
1008                 },
1009                 _6 : {
1010                         BKS : {start : 6, len : 1, def : ' ' },
1011                         SER : {start : 6, len : 1, def : ' ' },
1012                         VIS : {start : 12, len : 1, def : ' ' },
1013                         MIX : {start : 6, len : 1, def : ' ' },
1014                         MAP : {start : 12, len : 1, def : ' ' },
1015                         SCO : {start : 6, len : 1, def : ' ' },
1016                         REC : {start : 6, len : 1, def : ' ' }
1017                 }
1018         },
1019         'S/L' : {
1020                 _8 : {
1021                         SER : {start : 34, len : 1, def : '0' }
1022                 },
1023                 _6 : {
1024                         SER : {start : 17, len : 1, def : '0' }
1025                 }
1026         },
1027         'Alph' : {
1028                 _8 : {
1029                         SER : {start : 33, len : 1, def : ' ' }
1030                 },
1031                 _6 : {
1032                         SER : {start : 16, len : 1, def : ' ' }
1033                 }
1034         }
1035 };
1036
1037 function recordType (rec) {
1038         try {
1039                 var _l = rec.leader.toString();
1040
1041                 var _t = _l.substr(ff_pos.Type.ldr.BKS.start, ff_pos.Type.ldr.BKS.len);
1042                 var _b = _l.substr(ff_pos.BLvl.ldr.BKS.start, ff_pos.BLvl.ldr.BKS.len);
1043
1044                 for (var t in rec_type) {
1045                         if (_t.match(rec_type[t].Type) && _b.match(rec_type[t].BLvl)) {
1046                                 document.getElementById('recordTypeLabel').value = t;
1047                                 _record_type = t;
1048                                 return t;
1049                         }
1050                 }
1051
1052                 // in case we don't have a valid record type ...
1053                 _record_type = 'BKS';
1054                 return _record_type;
1055
1056         } catch(E) {
1057                 alert('FIXME, MARC Editor, recordType: ' + E);
1058         }
1059 }
1060
1061 function toggleFFE () {
1062         var grid = document.getElementById('leaderGrid');
1063         if (grid.hidden) {
1064                 grid.hidden = false;
1065         } else {
1066                 grid.hidden = true;
1067         }
1068         return true;
1069 }
1070
1071 function changeFFEditor (type) {
1072         var grid = document.getElementById('leaderGrid');
1073         grid.setAttribute('type',type);
1074 }
1075
1076 function fillFixedFields (rec) {
1077         try {
1078                         var grid = document.getElementById('leaderGrid');
1079
1080                         var rtype = _record_type;
1081
1082                         var _l = rec.leader.toString();
1083                         var _6 = rec.controlfield.(@tag=='006').toString();
1084                         var _7 = rec.controlfield.(@tag=='007').toString();
1085                         var _8 = rec.controlfield.(@tag=='008').toString();
1086
1087                         var list = [];
1088                         var pre_list = grid.getElementsByTagName('label');
1089                         for (var i in pre_list) {
1090                                 if ( pre_list[i].getAttribute && pre_list[i].getAttribute('set').indexOf(grid.getAttribute('type')) > -1 ) {
1091                                         list.push( pre_list[i] );
1092                                 }
1093                         }
1094
1095                         for (var i in list) {
1096                                 var name = list[i].getAttribute('name');
1097
1098                                 if (!ff_pos[name])
1099                                         continue;
1100
1101                                 var value = '';
1102                                 if ( ff_pos[name].ldr && ff_pos[name].ldr[rtype] )
1103                                         value = _l.substr(ff_pos[name].ldr[rtype].start, ff_pos[name].ldr[rtype].len);
1104
1105                                 if ( ff_pos[name]._8 && ff_pos[name]._8[rtype] )
1106                                         value = _8.substr(ff_pos[name]._8[rtype].start, ff_pos[name]._8[rtype].len);
1107
1108                                 if ( !value && ff_pos[name]._6 && ff_pos[name]._6[rtype] )
1109                                         value = _6.substr(ff_pos[name]._6[rtype].start, ff_pos[name]._6[rtype].len);
1110
1111                                 if ( ff_pos[name]._7 && ff_pos[name]._7[rtype] )
1112                                         value = _7.substr(ff_pos[name]._7[rtype].start, ff_pos[name]._7[rtype].len);
1113                                 
1114                                 if (!value) {
1115                                         var d;
1116                                         var p;
1117                                         if (ff_pos[name].ldr && ff_pos[name].ldr[rtype]) {
1118                                                 d = ff_pos[name].ldr[rtype].def;
1119                                                 p = 'ldr';
1120                                         }
1121
1122                                         if (ff_pos[name]._8 && ff_pos[name]._8[rtype]) {
1123                                                 d = ff_pos[name]._8[rtype].def;
1124                                                 p = '_8';
1125                                         }
1126
1127                                         if (!value && ff_pos[name]._6 && ff_pos[name]._6[rtype]) {
1128                                                 d = ff_pos[name]._6[rtype].def;
1129                                                 p = '_6';
1130                                         }
1131
1132                                         if (ff_pos[name]._7 && ff_pos[name]._7[rtype]) {
1133                                                 d = ff_pos[name]._7[rtype].def;
1134                                                 p = '_7';
1135                                         }
1136
1137                                         if (!value) {
1138                                                 for (var j = 0; j < ff_pos[name][p][rtype].len; j++) {
1139                                                         value += d;
1140                                                 }
1141                                         }
1142                                 }
1143
1144                                 list[i].nextSibling.value = value;
1145                         }
1146
1147                         return true;
1148         } catch(E) {
1149                 alert('FIXME, MARC Editor, fillFixedFields: ' + E);
1150         }
1151 }
1152
1153 function updateFixedFields (element) {
1154         var grid = document.getElementById('leaderGrid');
1155         var recGrid = document.getElementById('recGrid');
1156
1157         var rtype = _record_type;
1158         var new_value = element.value;
1159
1160         var parts = {
1161                 ldr : _record.leader,
1162                 _6 : _record.controlfield.(@tag=='006'),
1163                 _7 : _record.controlfield.(@tag=='007'),
1164                 _8 : _record.controlfield.(@tag=='008')
1165         };
1166
1167         var name = element.getAttribute('name');
1168         for (var i in ff_pos[name]) {
1169
1170                 if (!ff_pos[name][i][rtype]) continue;
1171                 if (!parts[i]) continue;
1172
1173                 var before = parts[i].substr(0, ff_pos[name][i][rtype].start);
1174                 var after = parts[i].substr(ff_pos[name][i][rtype].start + ff_pos[name][i][rtype].len);
1175
1176                 for (var j = 0; new_value.length < ff_pos[name][i][rtype].len; j++) {
1177                         new_value += ff_pos[name][i][rtype].def;
1178                 }
1179
1180                 parts[i].setChildren( before + new_value + after );
1181                 recGrid.getElementsByAttribute('tag',i)[0].lastChild.value = parts[i].toString();
1182         }
1183
1184         return true;
1185 }
1186
1187 function marcLeader (leader) {
1188         var row = createRow(
1189                 { class : 'marcLeaderRow',
1190                   tag : 'ldr' },
1191                 createLabel(
1192                         { value : 'LDR',
1193                           class : 'marcTag',
1194                           tooltiptext : $('catStrings').getString('staff.cat.marcedit.marcTag.LDR.label') } ),
1195                 createLabel(
1196                         { value : '',
1197                           class : 'marcInd1' } ),
1198                 createLabel(
1199                         { value : '',
1200                           class : 'marcInd2' } ),
1201                 createLabel(
1202                         { value : leader.text(),
1203                           class : 'marcLeader' } )
1204         );
1205
1206         return row;
1207 }
1208
1209 function marcControlfield (field) {
1210         tagname = field.@tag.toString().substr(2);
1211         var row;
1212         if (tagname == '1' || tagname == '3' || tagname == '6' || tagname == '7' || tagname == '8') {
1213                 row = createRow(
1214                         { class : 'marcControlfieldRow',
1215                           tag : '_' + tagname },
1216                         createLabel(
1217                                 { value : field.@tag,
1218                                   class : 'marcTag',
1219                                   context : 'tags_popup',
1220                                   onmouseover : 'getTooltip(this, "tag");',
1221                                   tooltipid : 'tag' + field.@tag } ),
1222                         createLabel(
1223                                 { value : field.@ind1,
1224                                   class : 'marcInd1',
1225                                   onmouseover : 'getTooltip(this, "ind1");',
1226                                   tooltipid : 'tag' + field.@tag + 'ind1val' + field.@ind1 } ),
1227                         createLabel(
1228                                 { value : field.@ind2,
1229                                   class : 'marcInd2',
1230                                   onmouseover : 'getTooltip(this, "ind2");',
1231                                   tooltipid : 'tag' + field.@tag + 'ind2val' + field.@ind2 } ),
1232                         createMARCTextbox(
1233                                 field,
1234                                 { value : field.text(),
1235                                   class : 'plain marcEditableControlfield',
1236                                   name : 'CONTROL' + tagname,
1237                                   oncontext : 'return false();',
1238                                   size : 50,
1239                                   maxlength : 50 } )
1240                         );
1241         } else {
1242                 row = createRow(
1243                         { class : 'marcControlfieldRow',
1244                           tag : '_' + tagname },
1245                         createLabel(
1246                                 { value : field.@tag,
1247                                   class : 'marcTag',
1248                                   onmouseover : 'getTooltip(this, "tag");',
1249                                   tooltipid : 'tag' + field.@tag } ),
1250                         createLabel(
1251                                 { value : field.@ind1,
1252                                   class : 'marcInd1',
1253                                   onmouseover : 'getTooltip(this, "ind1");',
1254                                   tooltipid : 'tag' + field.@tag + 'ind1val' + field.@ind1 } ),
1255                         createLabel(
1256                                 { value : field.@ind2,
1257                                   class : 'marcInd2',
1258                                   onmouseover : 'getTooltip(this, "ind2");',
1259                                   tooltipid : 'tag' + field.@tag + 'ind2val' + field.@ind2 } ),
1260                         createLabel(
1261                                 { value : field.text(),
1262                                   class : 'marcControlfield' } )
1263                 );
1264         }
1265
1266         return row;
1267 }
1268
1269 function stackSubfields(checkbox) {
1270         var list = document.getElementsByAttribute('name','sf_box');
1271
1272         var o = 'vertical';
1273         if (!checkbox.checked) o = 'horizontal';
1274         
1275         for (var i = 0; i < list.length; i++) {
1276                 if (list[i]) list[i].setAttribute('orient',o);
1277         }
1278 }
1279
1280 function fastItemAdd_toggle(checkbox) {
1281     var x = document.getElementById('fastItemAdd_textboxes');
1282     if (checkbox.checked) {
1283         x.hidden = false;
1284         document.getElementById('fastItemAdd_callnumber').focus();
1285         document.getElementById('fastItemAdd_callnumber').select();
1286     } else {
1287         x.hidden = true;
1288     }
1289 }
1290
1291 function fastItemAdd_attempt(doc_id) {
1292     try {
1293         if (typeof window.xulG.fast_add_item != 'function') { return; }
1294         if (!document.getElementById('fastItemAdd_checkbox').checked) { return; }
1295         if (!document.getElementById('fastItemAdd_callnumber').value) { return; }
1296         if (!document.getElementById('fastItemAdd_barcode').value) { return; }
1297         window.xulG.fast_add_item( doc_id, document.getElementById('fastItemAdd_callnumber').value, document.getElementById('fastItemAdd_barcode').value );
1298     } catch(E) {
1299         alert('fastItemAdd_attempt: ' + E);
1300     }
1301 }
1302
1303 function save_attempt(xml_string) {
1304     try {
1305         var result = window.xulG.save.func( xml_string );   
1306         if (result) {
1307             if (result.id) fastItemAdd_attempt(result.id);
1308             if (typeof result.on_complete == 'function') result.on_complete();
1309         }
1310     } catch(E) {
1311         alert('save_attempt: ' + E);
1312     }
1313 }
1314
1315 function marcDatafield (field) {
1316         var row = createRow(
1317                 { class : 'marcDatafieldRow' },
1318                 createMARCTextbox(
1319                         field.@tag,
1320                         { value : field.@tag,
1321                           class : 'plain marcTag',
1322                           name : 'marcTag',
1323                           context : 'tags_popup',
1324                           oninput : 'if (this.value.length == 3) { this.nextSibling.focus(); }',
1325                           size : 3,
1326                           maxlength : 3,
1327                           onmouseover : 'current_focus = this; getTooltip(this, "tag");' } ),
1328                 createMARCTextbox(
1329                         field.@ind1,
1330                         { value : field.@ind1,
1331                           class : 'plain marcInd1',
1332                           name : 'marcInd1',
1333                           oninput : 'if (this.value.length == 1) { this.nextSibling.focus(); }',
1334                           size : 1,
1335                           maxlength : 1,
1336                           onmouseover : 'current_focus = this; getContextMenu(this, "ind1"); getTooltip(this, "ind1");',
1337                           oncontextmenu : 'getContextMenu(this, "ind1");' } ),
1338                 createMARCTextbox(
1339                         field.@ind2,
1340                         { value : field.@ind2,
1341                           class : 'plain marcInd2',
1342                           name : 'marcInd2',
1343                           oninput : 'if (this.value.length == 1) { this.nextSibling.firstChild.firstChild.focus(); }',
1344                           size : 1,
1345                           maxlength : 1,
1346                           onmouseover : 'current_focus = this; getContextMenu(this, "ind2"); getTooltip(this, "ind2");',
1347                           oncontextmenu : 'getContextMenu(this, "ind2");' } ),
1348                 createHbox({ name : 'sf_box' })
1349         );
1350
1351         if (!current_focus && field.@tag == '') current_focus = row.childNodes[0];
1352         if (!current_focus && field.@ind1 == '') current_focus = row.childNodes[1];
1353         if (!current_focus && field.@ind2 == '') current_focus = row.childNodes[2];
1354
1355         var sf_box = row.lastChild;
1356         if (document.getElementById('stackSubfields').checked)
1357                 sf_box.setAttribute('orient','vertical');
1358
1359         sf_box.addEventListener(
1360                 'click',
1361                 function (e) {
1362                         if (sf_box === e.target) {
1363                                 sf_box.lastChild.lastChild.focus();
1364                         } else if (e.target.parentNode === sf_box) {
1365                                 e.target.lastChild.focus();
1366                         }
1367                 },
1368                 false
1369         );
1370
1371
1372         for (var i in field.subfield) {
1373                 var sf = field.subfield[i];
1374                 sf_box.appendChild(
1375                         marcSubfield(sf)
1376                 );
1377
1378                 if (sf.@code == '' && (!current_focus || current_focus.className.match(/Ind/)))
1379                         current_focus = sf_box.lastChild.childNodes[1];
1380         }
1381
1382         return row;
1383 }
1384
1385 function marcSubfield (sf) {                    
1386         return createHbox(
1387                 { class : 'marcSubfieldBox' },
1388                 createLabel(
1389                         { value : "\u2021",
1390                           class : 'plain marcSubfieldDelimiter',
1391                           onmouseover : 'getTooltip(this.nextSibling, "subfield");',
1392                           oncontextmenu : 'getContextMenu(this.nextSibling, "subfield");',
1393                           //onclick : 'this.nextSibling.focus();',
1394                           onfocus : 'this.nextSibling.focus();',
1395                           size : 2 } ),
1396                 createMARCTextbox(
1397                         sf.@code,
1398                         { value : sf.@code,
1399                           class : 'plain marcSubfieldCode',
1400                           name : 'marcSubfieldCode',
1401                           onmouseover : 'current_focus = this; getContextMenu(this, "subfield"); getTooltip(this, "subfield");',
1402                           oncontextmenu : 'getContextMenu(this, "subfield");',
1403                           oninput : 'if (this.value.length == 1) { this.nextSibling.focus(); }',
1404                           size : 2,
1405                           maxlength : 1 } ),
1406                 createMARCTextbox(
1407                         sf,
1408                         { value : sf.text(),
1409                           name : sf.parent().@tag + ':' + sf.@code,
1410                           class : 'plain marcSubfield', 
1411                           onmouseover : 'getTooltip(this, "subfield");',
1412                           contextmenu : function (event) { getAuthorityContextMenu(event.target, sf) },
1413                           size : new String(sf.text()).length + 2,
1414                           oninput : "this.setAttribute('size', this.value.length + 2);"
1415                         } )
1416         );
1417 }
1418
1419 function loadRecord(rec) {
1420         try {
1421                         _record = rec;
1422                         var grid_rows = document.getElementById('recGrid').lastChild;
1423
1424                         while (grid_rows.firstChild) grid_rows.removeChild(grid_rows.firstChild);
1425
1426                         grid_rows.appendChild( marcLeader( rec.leader ) );
1427
1428                         for (var i in rec.controlfield) {
1429                                 grid_rows.appendChild( marcControlfield( rec.controlfield[i] ) );
1430                         }
1431
1432                         for (var i in rec.datafield) {
1433                                 grid_rows.appendChild( marcDatafield( rec.datafield[i] ) );
1434                         }
1435
1436                         grid_rows.getElementsByAttribute('class','marcDatafieldRow')[0].firstChild.focus();
1437                         changeFFEditor(recordType(rec));
1438                         fillFixedFields(rec);
1439         } catch(E) {
1440                 alert('FIXME, MARC Editor, loadRecord: ' + E);
1441         }
1442 }
1443
1444
1445 function genToolTips () {
1446         for (var i in bib_data.field) {
1447                 var f = bib_data.field[i];
1448         
1449                 tag_menu.appendChild(
1450                         createMenuitem(
1451                                 { label : f.@tag,
1452                                   oncommand : 
1453                                         'current_focus.value = "' + f.@tag + '";' +
1454                                         'var e = document.createEvent("MutationEvents");' +
1455                                         'e.initMutationEvent("change",1,1,null,0,0,0,0);' +
1456                                         'current_focus.inputField.dispatchEvent(e);',
1457                                   disabled : f.@tag < '010' ? "true" : "false",
1458                                   tooltiptext : f.description }
1459                         )
1460                 );
1461         
1462                 var i1_popup = createPopup({position : 'after_start', id : 't' + f.@tag + 'i1' });
1463                 context_menus.appendChild( i1_popup );
1464         
1465                 var i2_popup = createPopup({position : 'after_start', id : 't' + f.@tag + 'i2' });
1466                 context_menus.appendChild( i2_popup );
1467         
1468                 var sf_popup = createPopup({position : 'after_start', id : 't' + f.@tag + 'sf' });
1469                 context_menus.appendChild( sf_popup );
1470         
1471                 tooltip_hash['tag' + f.@tag] = f.description;
1472                 for (var j in f.indicator) {
1473                         var ind = f.indicator[j];
1474                         tooltip_hash['tag' + f.@tag + 'ind' + ind.@position + 'val' + ind.@value] = ind.description;
1475         
1476                         if (ind.@position == 1) {
1477                                 i1_popup.appendChild(
1478                                         createMenuitem(
1479                                                 { label : ind.@value,
1480                                                   oncommand : 
1481                                                         'current_focus.value = "' + ind.@value + '";' +
1482                                                         'var e = document.createEvent("MutationEvents");' +
1483                                                         'e.initMutationEvent("change",1,1,null,0,0,0,0);' +
1484                                                         'current_focus.inputField.dispatchEvent(e);',
1485                                                   tooltiptext : ind.description }
1486                                         )
1487                                 );
1488                         }
1489         
1490                         if (ind.@position == 2) {
1491                                 i2_popup.appendChild(
1492                                         createMenuitem(
1493                                                 { label : ind.@value,
1494                                                   oncommand : 
1495                                                         'current_focus.value = "' + ind.@value + '";' +
1496                                                         'var e = document.createEvent("MutationEvents");' +
1497                                                         'e.initMutationEvent("change",1,1,null,0,0,0,0);' +
1498                                                         'current_focus.inputField.dispatchEvent(e);',
1499                                                   tooltiptext : ind.description }
1500                                         )
1501                                 );
1502                         }
1503                 }
1504         
1505                 for (var j in f.subfield) {
1506                         var sf = f.subfield[j];
1507                         tooltip_hash['tag' + f.@tag + 'sf' + sf.@code] = sf.description;
1508         
1509                         sf_popup.appendChild(
1510                                 createMenuitem(
1511                                         { label : sf.@code,
1512                                           oncommand : 
1513                                                 'current_focus.value = "' + sf.@code + '";' +
1514                                                 'var e = document.createEvent("MutationEvents");' +
1515                                                 'e.initMutationEvent("change",1,1,null,0,0,0,0);' +
1516                                                 'current_focus.inputField.dispatchEvent(e);',
1517                                           tooltiptext : sf.description
1518                                         }
1519                                 )
1520                         );
1521                 }
1522         }
1523 }
1524
1525 function getTooltip (target, type) {
1526
1527         var tt = '';
1528         if (type == 'subfield')
1529                 tt = 'tag' + target.parentNode.parentNode.parentNode.firstChild.value + 'sf' + target.parentNode.childNodes[1].value;
1530
1531         if (type == 'ind1')
1532                 tt = 'tag' + target.parentNode.firstChild.value + 'ind1val' + target.value;
1533
1534         if (type == 'ind2')
1535                 tt = 'tag' + target.parentNode.firstChild.value + 'ind2val' + target.value;
1536
1537         if (type == 'tag')
1538                 tt = 'tag' + target.parentNode.firstChild.value;
1539
1540         if (!document.getElementById( tt )) {
1541                 p.appendChild(
1542                         createTooltip(
1543                                 { id : tt,
1544                                   flex : "1",
1545                                   orient : 'vertical',
1546                                   onpopupshown : 'this.width = this.firstChild.boxObject.width + 10; this.height = this.firstChild.boxObject.height + 10;',
1547                                   class : 'tooltip' },
1548                                 createDescription({}, document.createTextNode( tooltip_hash[tt] ) )
1549                         )
1550                 );
1551         }
1552
1553         target.tooltip = tt;
1554         return true;
1555 }
1556
1557 function getContextMenu (target, type) {
1558
1559         var tt = '';
1560         if (type == 'subfield')
1561                 tt = 't' + target.parentNode.parentNode.parentNode.firstChild.value + 'sf';
1562
1563         if (type == 'ind1')
1564                 tt = 't' + target.parentNode.firstChild.value + 'i1';
1565
1566         if (type == 'ind2')
1567                 tt = 't' + target.parentNode.firstChild.value + 'i2';
1568
1569         target.setAttribute('context', tt);
1570         return true;
1571 }
1572
1573 var authority_tag_map = {
1574         100 : ['[100,400,500,700]',100],
1575         400 : ['[100,400,500,700]',100],
1576         700 : ['[100,400,500,700]',100],
1577         800 : ['[100,400,500,700]',100],
1578         110 : ['[110,410,510,710]',110],
1579         410 : ['[110,410,510,710]',110],
1580         710 : ['[110,410,510,710]',110],
1581         810 : ['[110,410,510,710]',110],
1582         111 : ['[111,411,511,711]',111],
1583         411 : ['[111,411,511,711]',111],
1584         711 : ['[111,411,511,711]',111],
1585         811 : ['[111,411,511,711]',111],
1586         240 : ['[130,430,530,730]',130],
1587         440 : ['[130,430,530,730]',130],
1588         130 : ['[130,430,530,730]',130],
1589         730 : ['[130,430,530,730]',130],
1590         830 : ['[130,430,530,730]',130],
1591         600 : ['[100,400,480,481,482,485,500,580,581,582,585,700,780,781,782,785]',100],
1592         650 : ['[150,450,480,481,482,485,550,580,581,582,585,750,780,781,782,785]',150],
1593         651 : ['[151,451,480,481,482,485,551,580,581,582,585,751,780,781,782,785]',151],
1594         655 : ['[155,455,480,481,482,485,555,580,581,582,585,755,780,781,782,785]',155]
1595 };
1596
1597 function getAuthorityContextMenu (target, sf) {
1598         var menu_id = sf.parent().@tag + ':' + sf.@code + '-authority-context-' + sf;
1599
1600         var old = document.getElementById( menu_id );
1601         if (old) old.parentNode.removeChild(old);
1602
1603         var sf_popup = createPopup({ id : menu_id, flex : 1 });
1604         context_menus.appendChild( sf_popup );
1605
1606         if (!authority_tag_map[sf.parent().@tag]) {
1607                 sf_popup.appendChild(createLabel( { value : $('catStrings').getString('staff.cat.marcedit.not_authority_field.label') } ) );
1608                 target.setAttribute('context', menu_id);
1609                 return false;
1610         }
1611
1612         var auth_data = searchAuthority( sf, authority_tag_map[sf.parent().@tag][0], sf.@code, 50);
1613
1614         var res = new XML( auth_data.responseText );
1615
1616         var rec_list = [];
1617
1618         var recs = res.gw::payload.gw::array.gw::string;
1619         for (var i in recs) {
1620                 var x = recs[i];
1621                 var xml = new XML(x.toString());
1622                 var main = xml.datafield.(@tag.toString().match(/^1/)).subfield;
1623
1624                 if (! (main[0].parent().@tag == authority_tag_map[sf.parent().@tag][1]) ) continue;
1625
1626                 var main_text = '';
1627                 for (var i in main) {
1628                         if (main_text) main_text += ' / ';
1629                         main_text += main[i];
1630                 }
1631
1632                 rec_list.push( [ main_text, xml ] );
1633         }
1634         
1635         for (var i in rec_list.sort( function (a, b) { if(a[0] > b[0]) return 1; return -1; } )) {
1636
1637                 var main_text = rec_list[i][0];
1638                 var xml = rec_list[i][1];
1639                 var main = xml.datafield.(@tag.toString().match(/^1/)).subfield;
1640
1641                 if (! (main[0].parent().@tag == authority_tag_map[sf.parent().@tag][1]) ) continue;
1642
1643                 var grid = document.getElementsByAttribute('name','authority-marc-template')[0].cloneNode(true);
1644                 grid.setAttribute('name','-none-');
1645                 grid.setAttribute('style','overflow:scroll');
1646
1647
1648                 var submenu = createMenu( { label : main_text } );
1649
1650                 var popup = createMenuPopup({ flex : "1" });
1651                 submenu.appendChild(popup);
1652
1653                 var fields = xml.datafield;
1654                 for (var j in fields) {
1655
1656                         var row = createRow(
1657                                 {},
1658                                 createLabel( { value : fields[j].@tag } ),
1659                                 createLabel( { value : fields[j].@ind1 } ),
1660                                 createLabel( { value : fields[j].@ind2 } )
1661                         );
1662
1663                         var sf_box = createHbox();
1664
1665                         var subfields = fields[j].subfield;
1666                         for (var k in subfields) {
1667                                 sf_box.appendChild(
1668                                         createCheckbox(
1669                                                 { label    : '\u2021' + subfields[k].@code + ' ' + subfields[k],
1670                                                   subfield : subfields[k].@code,
1671                                                   tag      : subfields[k].parent().@tag,
1672                                                   value    : subfields[k]
1673                                                 }
1674                                         )
1675                                 );
1676                                 row.appendChild(sf_box);
1677                         }
1678
1679                         grid.lastChild.appendChild(row);
1680                 }
1681
1682                 grid.hidden = false;
1683                 popup.appendChild( grid );
1684
1685                 popup.appendChild(
1686                         createMenuitem(
1687                                 { label : $('catStrings').getString('staff.cat.marcedit.apply_selected.label'),
1688                                   command : function (event) {
1689                                                 applyAuthority(event.target.previousSibling, target, sf);
1690                                                 return true;
1691                                   }
1692                                 }
1693                         )
1694                 );
1695
1696                 sf_popup.appendChild( submenu );
1697         }
1698
1699         if (sf_popup.childNodes.length == 0)
1700                 sf_popup.appendChild(createLabel( { value : $('catStrings').getString('staff.cat.marcedit.no_authority_match.label') } ) );
1701
1702         target.setAttribute('context', menu_id);
1703         return true;
1704 }
1705
1706 function applyAuthority ( target, ui_sf, e4x_sf ) {
1707
1708         var new_vals = target.getElementsByAttribute('checked','true');
1709         var field = e4x_sf.parent();
1710
1711         for (var i = 0; i < new_vals.length; i++) {
1712
1713                 var sf_list = field.subfield;
1714                 for (var j in sf_list) {
1715
1716                         if (sf_list[j].@code == new_vals[i].getAttribute('subfield')) {
1717                                 sf_list[j] = new_vals[i].getAttribute('value');
1718                                 new_vals[i].setAttribute('subfield','');
1719                                 break;
1720                         }
1721                 }
1722         }
1723
1724         for (var i = 0; i < new_vals.length; i++) {
1725                 if (!new_vals[i].getAttribute('subfield')) continue;
1726
1727                 var val = new_vals[i].getAttribute('value');
1728
1729                 var sf = <subfield code="" xmlns="http://www.loc.gov/MARC21/slim">{val}</subfield>;
1730                 sf.@code = new_vals[i].getAttribute('subfield');
1731
1732                 field.insertChildAfter(field.subfield[field.subfield.length() - 1], sf);
1733         }
1734
1735         var row = marcDatafield( field );
1736
1737         var node = ui_sf;
1738         while (node.nodeName != 'row') {
1739                 node = node.parentNode;
1740         }
1741
1742         node.parentNode.replaceChild( row, node );
1743         return true;
1744 }
1745
1746 var control_map = {
1747         100 : {
1748                 'a' : { 100 : 'a' },
1749                 'd' : { 100 : 'd' },
1750                 'q' : { 100 : 'q' }
1751         },
1752         110 : {
1753                 'a' : { 110 : 'a' },
1754                 'd' : { 110 : 'd' }
1755         },
1756         111 : {
1757                 'a' : { 111 : 'a' },
1758                 'd' : { 111 : 'd' }
1759         },
1760         130 : {
1761                 'a' : { 130 : 'a' },
1762                 'd' : { 130 : 'd' }
1763         },
1764         240 : {
1765                 'a' : { 130 : 'a' },
1766                 'd' : { 130 : 'd' }
1767         },
1768         400 : {
1769                 'a' : { 100 : 'a' },
1770                 'd' : { 100 : 'd' }
1771         },
1772         410 : {
1773                 'a' : { 110 : 'a' },
1774                 'd' : { 110 : 'd' }
1775         },
1776         411 : {
1777                 'a' : { 111 : 'a' },
1778                 'd' : { 111 : 'd' }
1779         },
1780         440 : {
1781                 'a' : { 130 : 'a' },
1782                 'n' : { 130 : 'n' },
1783                 'p' : { 130 : 'p' }
1784         },
1785         700 : {
1786                 'a' : { 100 : 'a' },
1787                 'd' : { 100 : 'd' },
1788                 'q' : { 100 : 'q' },
1789                 't' : { 100 : 't' }
1790         },
1791         710 : {
1792                 'a' : { 110 : 'a' },
1793                 'd' : { 110 : 'd' }
1794         },
1795         711 : {
1796                 'a' : { 111 : 'a' },
1797                 'd' : { 111 : 'd' }
1798         },
1799         730 : {
1800                 'a' : { 130 : 'a' },
1801                 'd' : { 130 : 'd' }
1802         },
1803         800 : {
1804                 'a' : { 100 : 'a' },
1805                 'd' : { 100 : 'd' }
1806         },
1807         810 : {
1808                 'a' : { 110 : 'a' },
1809                 'd' : { 110 : 'd' }
1810         },
1811         811 : {
1812                 'a' : { 111 : 'a' },
1813                 'd' : { 111 : 'd' }
1814         },
1815         830 : {
1816                 'a' : { 130 : 'a' },
1817                 'd' : { 130 : 'd' }
1818         },
1819         600 : {
1820                 'a' : { 100 : 'a' },
1821                 'd' : { 100 : 'd' },
1822                 'q' : { 100 : 'q' },
1823                 't' : { 100 : 't' },
1824                 'v' : { 180 : 'v',
1825                         100 : 'v',
1826                         181 : 'v',
1827                         182 : 'v',
1828                         185 : 'v'
1829                 },
1830                 'x' : { 180 : 'x',
1831                         100 : 'x',
1832                         181 : 'x',
1833                         182 : 'x',
1834                         185 : 'x'
1835                 },
1836                 'y' : { 180 : 'y',
1837                         100 : 'y',
1838                         181 : 'y',
1839                         182 : 'y',
1840                         185 : 'y'
1841                 },
1842                 'z' : { 180 : 'z',
1843                         100 : 'z',
1844                         181 : 'z',
1845                         182 : 'z',
1846                         185 : 'z'
1847                 }
1848         },
1849         610 : {
1850                 'a' : { 110 : 'a' },
1851                 'd' : { 110 : 'd' },
1852                 't' : { 110 : 't' },
1853                 'v' : { 180 : 'v',
1854                         110 : 'v',
1855                         181 : 'v',
1856                         182 : 'v',
1857                         185 : 'v'
1858                 },
1859                 'x' : { 180 : 'x',
1860                         110 : 'x',
1861                         181 : 'x',
1862                         182 : 'x',
1863                         185 : 'x'
1864                 },
1865                 'y' : { 180 : 'y',
1866                         110 : 'y',
1867                         181 : 'y',
1868                         182 : 'y',
1869                         185 : 'y'
1870                 },
1871                 'z' : { 180 : 'z',
1872                         110 : 'z',
1873                         181 : 'z',
1874                         182 : 'z',
1875                         185 : 'z'
1876                 }
1877         },
1878         611 : {
1879                 'a' : { 111 : 'a' },
1880                 'd' : { 111 : 'd' },
1881                 't' : { 111 : 't' },
1882                 'v' : { 180 : 'v',
1883                         111 : 'v',
1884                         181 : 'v',
1885                         182 : 'v',
1886                         185 : 'v'
1887                 },
1888                 'x' : { 180 : 'x',
1889                         111 : 'x',
1890                         181 : 'x',
1891                         182 : 'x',
1892                         185 : 'x'
1893                 },
1894                 'y' : { 180 : 'y',
1895                         111 : 'y',
1896                         181 : 'y',
1897                         182 : 'y',
1898                         185 : 'y'
1899                 },
1900                 'z' : { 180 : 'z',
1901                         111 : 'z',
1902                         181 : 'z',
1903                         182 : 'z',
1904                         185 : 'z'
1905                 }
1906         },
1907         630 : {
1908                 'a' : { 130 : 'a' },
1909                 'd' : { 130 : 'd' }
1910         },
1911         650 : {
1912                 'a' : { 150 : 'a' },
1913                 'b' : { 150 : 'b' },
1914                 'v' : { 180 : 'v',
1915                         150 : 'v',
1916                         181 : 'v',
1917                         182 : 'v',
1918                         185 : 'v'
1919                 },
1920                 'x' : { 180 : 'x',
1921                         150 : 'x',
1922                         181 : 'x',
1923                         182 : 'x',
1924                         185 : 'x'
1925                 },
1926                 'y' : { 180 : 'y',
1927                         150 : 'y',
1928                         181 : 'y',
1929                         182 : 'y',
1930                         185 : 'y'
1931                 },
1932                 'z' : { 180 : 'z',
1933                         150 : 'z',
1934                         181 : 'z',
1935                         182 : 'z',
1936                         185 : 'z'
1937                 }
1938         },
1939         651 : {
1940                 'a' : { 151 : 'a' },
1941                 'v' : { 180 : 'v',
1942                         151 : 'v',
1943                         181 : 'v',
1944                         182 : 'v',
1945                         185 : 'v'
1946                 },
1947                 'x' : { 180 : 'x',
1948                         151 : 'x',
1949                         181 : 'x',
1950                         182 : 'x',
1951                         185 : 'x'
1952                 },
1953                 'y' : { 180 : 'y',
1954                         151 : 'y',
1955                         181 : 'y',
1956                         182 : 'y',
1957                         185 : 'y'
1958                 },
1959                 'z' : { 180 : 'z',
1960                         151 : 'z',
1961                         181 : 'z',
1962                         182 : 'z',
1963                         185 : 'z'
1964                 }
1965         },
1966         655 : {
1967                 'a' : { 155 : 'a' },
1968                 'v' : { 180 : 'v',
1969                         155 : 'v',
1970                         181 : 'v',
1971                         182 : 'v',
1972                         185 : 'v'
1973                 },
1974                 'x' : { 180 : 'x',
1975                         155 : 'x',
1976                         181 : 'x',
1977                         182 : 'x',
1978                         185 : 'x'
1979                 },
1980                 'y' : { 180 : 'y',
1981                         155 : 'y',
1982                         181 : 'y',
1983                         182 : 'y',
1984                         185 : 'y'
1985                 },
1986                 'z' : { 180 : 'z',
1987                         155 : 'z',
1988                         181 : 'z',
1989                         182 : 'z',
1990                         185 : 'z'
1991                 }
1992         }
1993 };
1994
1995 function validateAuthority (button) {
1996         var grid = document.getElementById('recGrid');
1997         var label = button.getAttribute('label');
1998
1999         //loop over rows
2000         var rows = grid.lastChild.childNodes;
2001         for (var i = 0; i < rows.length; i++) {
2002                 var row = rows[i];
2003                 var tag = row.firstChild;
2004
2005                 if (!control_map[tag.value]) continue
2006                 button.setAttribute('label', label + ' - ' + tag.value);
2007
2008                 var ind1 = tag.nextSibling;
2009                 var ind2 = ind1.nextSibling;
2010                 var subfields = ind2.nextSibling.childNodes;
2011
2012         var tags = {};
2013
2014                 for (var j = 0; j < subfields.length; j++) {
2015                         var sf = subfields[j];
2016             var sf_code = sf.childNodes[1].value;
2017             var sf_value = sf.childNodes[2].value;
2018
2019                         if (!control_map[tag.value][sf_code]) continue;
2020
2021                         var found = 0;
2022                         for (var a_tag in control_map[tag.value][sf_code]) {
2023                 if (!tags[a_tag]) tags[a_tag] = [];
2024                 tags[a_tag].push({ term : sf_value, subfield : sf_code });
2025                         }
2026
2027                 }
2028
2029         for (var val_tag in tags) {
2030                 var auth_data = validateBibField( [val_tag], tags[val_tag]);
2031                 var res = new XML( auth_data.responseText );
2032                 found = parseInt(res.gw::payload.gw::string.toString());
2033             if (found) break;
2034         }
2035
2036                 // XXX If adt, etc should be validated separately from vxz, etc then move this up into the above for loop
2037                 for (var j = 0; j < subfields.length; j++) {
2038                         var sf = subfields[j];
2039                         if (!found) {
2040                                 sf.childNodes[2].inputField.style.color = 'red';
2041                         } else {
2042                                 sf.childNodes[2].inputField.style.color = 'black';
2043                         }
2044         }
2045         }
2046
2047         button.setAttribute('label', label);
2048
2049         return true;
2050 }
2051
2052
2053 function validateBibField (tags, searches) {
2054         var url = "/gateway?input_format=json&format=xml&service=open-ils.search&method=open-ils.search.authority.validate.tag";
2055         url += '&param="tags"&param=' + js2JSON(tags);
2056         url += '&param="searches"&param=' + js2JSON(searches);
2057
2058
2059         var req = new XMLHttpRequest();
2060         req.open('GET',url,false);
2061         req.send(null);
2062
2063         return req;
2064
2065 }
2066 function searchAuthority (term, tag, sf, limit) {
2067         var url = "/gateway?input_format=json&format=xml&service=open-ils.search&method=open-ils.search.authority.fts";
2068         url += '&param="term"&param="' + term + '"';
2069         url += '&param="limit"&param=' + limit;
2070         url += '&param="tag"&param=' + tag;
2071         url += '&param="subfield"&param="' + sf + '"';
2072
2073
2074         var req = new XMLHttpRequest();
2075         req.open('GET',url,false);
2076         req.send(null);
2077
2078         return req;
2079
2080 }
2081