]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Evergreen/staff_client/chrome/content/evergreen/cat/marc.js
don't need this for z39.50 import
[working/Evergreen.git] / Evergreen / staff_client / chrome / content / evergreen / cat / marc.js
1 mw.sdump('D_CAT','loading marc.js\n');
2
3 var character_measure = {};
4 var tree;
5 var meta;
6 var backup_tree;
7
8 function my_init() {
9         mw.sdump('D_CAT','Entering my_init() : ' + timer_elapsed('cat') + '\n');
10         mw.sdump('D_CAT','TESTING: marc.js: ' + mw.G['main_test_variable'] + '\n');
11
12         try {
13                 mw.sdump('D_CAT',"DOC ID " + find_this_id + "\n" );
14         } catch(E) {
15                 
16         }
17
18         if (! params.import_tree ) {
19                 tree = retrieve_record( find_this_id );
20                 meta = retrieve_meta_record( find_this_id );
21                 document.getElementById('meta_create_date').setAttribute('value',
22                         meta.create_date().split('.')[0]        
23                 );
24                 document.getElementById('meta_creator').setAttribute('value',
25                         meta.creator()  
26                 );
27                 document.getElementById('meta_edit_date').setAttribute('value',
28                         meta.edit_date().split('.')[0]
29                 );
30                 document.getElementById('meta_editor').setAttribute('value',
31                         meta.editor()   
32                 );
33                 document.getElementById('meta_tcn_publisher').setAttribute('value',
34                         meta.tcn_value()        
35                 );
36                 if (params.record_columns) {
37                         var text = document.createTextNode(
38                                 params.record_columns[1] + ' / ' + params.record_columns[2]
39                         );
40                         document.getElementById('meta_title_author').appendChild(
41                                 text
42                         );
43                 }
44         } else {
45                 tree = params.import_tree;
46                 if (tree.name() == 'collection') { 
47                         tree = find_list(
48                                 tree.children(),
49                                 function (obj) {
50                                         return (obj.name() == 'record');
51                                 }
52                         ); 
53                 }
54         }
55         //mw.sdump('D_CAT','Retrieved: ' + js2JSON(tree) + '\n');
56         //mw.sdump('D_CAT','Retrieved: ' + js2JSON(meta) + '\n');
57         build_grid( 
58                 document.getElementById('ctrl_rows'), 
59                 document.getElementById('data_rows'), 
60                 tree
61         );
62         fixed_fields_show_only('fixed_grid','BKS');
63         apply_event_listeners('fixed_grid','fixed');
64         character_measure = measure_character('marc_win','M');
65         window.addEventListener('resize',my_resize_handler,false);
66         handle_tag_change();
67         document.getElementById('data_rows').firstChild.firstChild.firstChild.focus();
68         mw.sdump('D_CAT','Exiting my_init() : ' + timer_elapsed('cat') + '\n');
69 }
70
71 function measure_character(w,c) {
72         var el = document.getElementById(w);
73         var b = document.createElement('hbox');
74         var l = document.createElement('label');
75         l.setAttribute('class','marc');
76         el.appendChild(b);
77         b.appendChild(l);
78         var lwidth = l.boxObject.width;
79         l.value = c;
80         lwidth = Math.abs( l.boxObject.width - lwidth);
81         var lheight = l.boxObject.height;
82         b.removeChild(l); el.removeChild(b);
83         return { "width" : lwidth, "height" : lheight };
84 }
85
86 function my_resize_handler(ev) {
87         mw.sdump('D_CAT','resize\n');
88         resizeAllWrappers('ctrl_rows');
89         resizeAllWrappers('data_rows');
90 }
91
92 function retrieve_record(id) {
93         mw.sdump('D_CAT','Entering retrieve_record() : ' + timer_elapsed('cat') + '\n');
94         var result = user_request(
95                 'open-ils.cat',
96                 'open-ils.cat.biblio.record.tree.retrieve',
97                 [ id ]
98         );
99         //var result = [ JSON2js( test_nodeset() ) ];
100         /*var result = user_request(
101                 'open-ils.cat',
102                 'open-ils.cat.biblio.record.tree.retrieve.test',
103                 [ id ]
104         );*/
105         if (typeof(result[0]) != 'object') {
106                 alert( 'user_request gave ' + js2JSON(result) );
107                 mw.sdump('D_CAT','Exiting retrieve_record() : ' + timer_elapsed('cat') + '\n');
108                 return 0;
109         } else {
110                 /*
111                 mw.sdump('D_CAT','Entering nodeset2tree() : ' + timer_elapsed('cat') + '\n');
112                 result[0] = nodeset2tree( result[0] )[0];
113                 mw.sdump('D_CAT','Exiting nodeset2tree() : ' + timer_elapsed('cat') + '\n');
114                 */
115                 mw.sdump('D_CAT','Exiting retrieve_record() : ' + timer_elapsed('cat') + '\n');
116                 return result[0];
117         }
118 }
119
120 function retrieve_meta_record(id) {
121         mw.sdump('D_CAT','Entering retrieve_meta_record() : ' + timer_elapsed('cat') + '\n');
122         var result = user_request(
123                 'open-ils.cat',
124                 'open-ils.cat.biblio.record.metadata.retrieve',
125                 [ id ]
126         );
127         if (typeof(result[0]) != 'object') {
128                 alert( 'user_request gave ' + js2JSON(result) );
129                 mw.sdump('D_CAT','Exiting retrieve_meta_record() : ' + timer_elapsed('cat') + '\n');
130                 return 0;
131         } else {
132                 mw.sdump('D_CAT','Exiting retrieve_meta_record() : ' + timer_elapsed('cat') + '\n');
133                 return result[0][0];
134         }
135 }
136
137
138
139 function empty_me(p) {
140         while (p.lastChild) {
141                 //mw.sdump('D_CAT','emptying ' + p.lastChild.tagName + '\n');
142                 empty_me(p.lastChild);
143                 p.removeChild(p.lastChild);
144         }
145 }
146
147 function empty_grid( ctrl_rows, data_rows ) {
148         var rows = document.getElementById(ctrl_rows);
149         empty_me(rows);
150         rows = document.getElementById(data_rows);
151         empty_me(rows);
152 }
153
154 function build_grid( ctrl_rows, data_rows, root ) {
155         mw.sdump('D_CAT','Entering build_grid() : ' + timer_elapsed('cat') + '\n');
156         var ctrl_count = 1; var data_count = 1;
157         //mw.sdump('D_CAT', 'what is root?\n' + pretty_print(js2JSON(root)) + '\n');
158         mw.sdump('D_CAT','root.children.length = ' + root.children.length + '\n');
159         root_loop: 
160         var children = root.children();
161         for (var i in children) {
162                 var node = children[i];
163                 var node_type = node.node_type();
164                 var row = {};
165                 switch(node_type) {
166                         case '18': /* namespace */ 
167                                 break;
168                         case '1': /* element */
169                                 row = get_row(node);
170                                 switch(row.type) {
171                                         case 'leader': case 'controlfield':
172                                                         populate_xul_row( 
173                                                                 ctrl_rows, 
174                                                                 row, 
175                                                                 'ctrl_' + ctrl_count++
176                                                         );
177                                                 break;
178                                         case 'datafield':
179                                                         populate_xul_row( 
180                                                                 data_rows, 
181                                                                 row, 
182                                                                 'data_' + data_count++
183                                                         );
184                                                 break;
185                                         default:
186                                                 mw.sdump('D_CAT','Unexpected row type: ' + 
187                                                         js2JSON(node) + '\n');
188                                                 break;
189                                 }
190                                 break;
191                         default: /* eh? */
192                                 mw.sdump('D_CAT', 'Did not expect node_type = ' + node_type + 
193                                         ' : ' + js2JSON(node) + '\n');
194                                 break;
195                 }
196                 //mw.sdump('D_CAT', i + ' ' + dump_ns_node(node) + '\n');
197         }
198         mw.sdump('D_CAT','Exiting build_grid() : ' + timer_elapsed('cat') + '\n');
199 }
200
201 function get_row( top ) {
202         var row = { 
203                 'field' : { 'id' : '1' },
204                 'tag' : { 'value' : '', 'id' : '-1' },
205                 'ind1' : { 'value' : '', 'id' : '-1' },
206                 'ind2' : { 'value' : '', 'id' : '-1' },
207                 'data' : { 'value' : '', 'id' : '-1' }
208         };
209         var name = top.name(); 
210         var id = top.intra_doc_id(); 
211         var children = top.children();
212         row.field.id = id;
213         mw.sdump('D_CAT','Making row.... row.field.id = <' + id + '>\n');
214         if (name == 'leader') { row.tag.value = 'LDR'; row.tag.id = id; }
215         row.type = name;
216         top_loop:
217         for (var i in children) {
218                 var node = children[i];
219                 var node_type = node.node_type();
220                 var node_name = node.name();
221                 var node_value = node.value();
222                 var node_id = node.intra_doc_id();
223                 var node_children = node.children();
224                 switch(node_type) {
225                         case '18': /* namespace */ 
226                                 continue top_loop;
227                         case '2': /* attribute */ 
228                                 switch(node_name) {
229                                         case 'tag':
230                                                 row.tag.value = node_value;
231                                                 row.tag.id = node_id;
232                                                 break;
233                                         case 'ind1':
234                                                 row.ind1.value = node_value;
235                                                 row.ind1.id = node_id;
236                                                 break;
237                                         case 'ind2':
238                                                 row.ind2.value = node_value;
239                                                 row.ind2.id = node_id;
240                                                 break;
241                                         default:
242                                                 mw.sdump('D_CAT','\tattribute surprise on node_name = ' +
243                                                         node_name + ' : ' 
244                                                         + js2JSON(node) + '\n');
245                                                 break;
246                                 }
247                                 break;
248                         case '1': /* element */
249                                 switch(node_name) {
250                                         case 'subfield':
251                                                 row.data.value = row.data.value + 
252                                                 String.fromCharCode(8225) +
253                                                 node_children[0].value() + ' ' + 
254                                                 node_children[1].value() + ' ';
255                                                 row.data.id = node_id;
256                                                 break;
257                                         default:
258                                                 mw.sdump('D_CAT','\telement surprise on node_name = ' +
259                                                         node_name + ' : ' 
260                                                         + js2JSON(node) + '\n');
261                                                 break;
262                                 }
263                                 break;
264                         case '3': /* textNode */
265                                 row.data.value = node_value;
266                                 row.data.id = node_id;
267                                 break;
268                         default: /* eh? */
269                                 mw.sdump('D_CAT','\tunknown type surprise on node_type = ' +
270                                         node_type + ' : '  +
271                                         js2JSON(node) + '\n');
272                                 break;
273                 }
274         }
275         //mw.sdump('D_CAT',js2JSON(row) + '\n');
276         return row;
277 }
278
279 function build_xul_row( id, type ) {
280         switch(type) {
281                 case 'leader': case 'controlfield':
282                         return build_ctrl_row( id );
283                         break;
284                 case 'datafield':
285                         return build_data_row( id );
286                         break;
287                 default:
288                         mw.sdump('D_CAT','Unexpected row type\n');
289                         break;
290         }
291 }
292
293 function build_data_row( id ) {
294         //mw.sdump('D_CAT','Entering build_xul_row() : ' + timer_elapsed('cat') + '\n');
295         var xul_row = document.createElement('row');
296         xul_row.setAttribute('id',id);
297         xul_row.setAttribute('class','field_row data_row');
298         //xul_rows.appendChild(xul_row);
299
300         /* the elements in the row */
301         var wrapper1 = document.createElement('hbox');
302         wrapper1.setAttribute( 'class', 'marc_wrapper marc_tag_wrapper');
303         var xul_col1 = document.createElement('textbox');
304                 xul_col1.setAttribute( 'cols', '3');
305                 xul_col1.setAttribute( 'rows', '1');
306                 xul_col1.setAttribute( 'multiline', 'true');
307                 xul_col1.setAttribute( 'size', '3');
308                 xul_col1.setAttribute( 'class', 'marc marc_tag');
309                 wrapper1.appendChild(xul_col1);
310                 xul_row.appendChild(wrapper1);
311         var wrapper2 = document.createElement('hbox');
312         wrapper2.setAttribute( 'class', 'marc_wrapper marc_ind_wrapper marc_ind1_wrapper');
313         var xul_col2 = document.createElement('textbox');
314                 xul_col2.setAttribute( 'cols', '1');
315                 xul_col2.setAttribute( 'rows', '1');
316                 xul_col2.setAttribute( 'multiline', 'true');
317                 xul_col2.setAttribute( 'size', '1');
318                 xul_col2.setAttribute( 'class', 'marc marc_ind marc_ind1');
319                 wrapper2.appendChild(xul_col2);
320                 xul_row.appendChild(wrapper2);
321         var wrapper3 = document.createElement('hbox');
322         wrapper3.setAttribute( 'class', 'marc_wrapper marc_ind_wrapper marc_ind2_wrapper');
323         var xul_col3 = document.createElement('textbox');
324                 xul_col3.setAttribute( 'cols', '1');
325                 xul_col3.setAttribute( 'rows', '1');
326                 xul_col3.setAttribute( 'multiline', 'true');
327                 xul_col3.setAttribute( 'size', '1');
328                 xul_col3.setAttribute( 'class', 'marc marc_ind marc_ind2');
329                 wrapper3.appendChild(xul_col3);
330                 xul_row.appendChild(wrapper3);
331         var wrapper4 = document.createElement('hbox');
332         wrapper4.setAttribute( 'class', 'marc_wrapper marc_data_wrapper');
333         var xul_col4 = document.createElement('textbox');
334                 xul_col4.setAttribute( 'subfields', 'true');
335                 xul_col4.setAttribute( 'cols', '60');
336                 xul_col4.setAttribute( 'size', '60');
337                 xul_col4.setAttribute( 'rows', '1');
338                 xul_col4.setAttribute( 'multiline', 'true');
339                 xul_col4.setAttribute( 'class', 'marc marc_data resizable');
340                 xul_col4.setAttribute( 'flex', '1');
341                 wrapper4.appendChild(xul_col4);
342                 xul_row.appendChild(wrapper4);
343
344         return xul_row;
345         //mw.sdump('D_CAT','Exiting build_xul_row() : ' + timer_elapsed('cat') + '\n');
346 }
347
348 function build_ctrl_row( id ) {
349         //mw.sdump('D_CAT','Entering build_xul_row() : ' + timer_elapsed('cat') + '\n');
350         var xul_row = document.createElement('row');
351         xul_row.setAttribute('class','field_row ctrl_row');
352         xul_row.setAttribute('id',id);
353         //xul_rows.appendChild(xul_row);
354
355         /* the elements in the row */
356         var wrapper1 = document.createElement('hbox');
357         wrapper1.setAttribute( 'class', 'marc_wrapper marc_tag_wrapper ctrl_wrapper');
358         var xul_col1 = document.createElement('textbox');
359                 xul_col1.setAttribute( 'cols', '3');
360                 xul_col1.setAttribute( 'rows', '1');
361                 xul_col1.setAttribute( 'multiline', 'true');
362                 xul_col1.setAttribute( 'size', '3');
363                 xul_col1.setAttribute( 'class', 'marc marc_tag ctrl');
364                 xul_col1.setAttribute( 'disabled', 'true');
365                 wrapper1.appendChild(xul_col1);
366                 xul_row.appendChild(wrapper1);
367         var wrapper4 = document.createElement('hbox');
368         wrapper4.setAttribute( 'class', 'marc_wrapper marc_data_wrapper ctrl_wrapper');
369         var xul_col4 = document.createElement('textbox');
370                 xul_col4.setAttribute( 'cols', '60');
371                 xul_col4.setAttribute( 'size', '60');
372                 xul_col4.setAttribute( 'rows', '1');
373                 xul_col4.setAttribute( 'multiline', 'true');
374                 xul_col4.setAttribute( 'class', 'marc marc_data ctrl');
375                 xul_col4.setAttribute( 'flex', '1');
376                 xul_col4.setAttribute( 'disabled', 'true');
377                 wrapper4.appendChild(xul_col4);
378                 xul_row.appendChild(wrapper4);
379
380         return xul_row;
381         //mw.sdump('D_CAT','Exiting build_xul_row() : ' + timer_elapsed('cat') + '\n');
382 }
383
384
385 function apply_event_listeners(c,which) {
386         switch(which) {
387                 case 'ctrl':
388                         break;
389                 case 'data':
390                         c[0].firstChild.addEventListener("change",handle_tag_change,false);
391                         c[0].firstChild.addEventListener("keypress",handle_keypress,false);
392                         c[1].firstChild.addEventListener("keypress",handle_keypress,false);
393                         c[1].firstChild.addEventListener("change",handle_tag_change,false);
394                         c[2].firstChild.addEventListener("keypress",handle_keypress,false);
395                         c[2].firstChild.addEventListener("change",handle_tag_change,false);
396                         c[3].firstChild.addEventListener("keypress",handle_keypress,false);
397                         c[3].firstChild.addEventListener("change",handle_tag_change,false);
398                         c[3].firstChild.addEventListener("change",handle_change,false);
399                         break;
400                 case 'fixed':
401                         var g = document.getElementById(c);
402                         var nl = g.getElementsByTagName('textbox');
403                         for (var i in nl) {
404                                 if (typeof(nl[i])=='object') {
405                                         nl[i].addEventListener("change",handle_fixed_change,false);
406                                 }
407                         }
408                         break;
409         }
410 }
411
412 function populate_xul_row( xul_rows, row, id ) {
413
414         var r = document.getElementById(id);
415         if (!r) {
416                 r = build_xul_row(id,row.type);
417                 xul_rows.appendChild(r);
418                 //r = document.getElementById(id);
419         }
420         r.setAttribute('notempty','true');
421         r.setAttribute('mynode',row.field.id);
422         var c = r.childNodes;
423         switch(row.type) {
424                 case 'leader': case 'controlfield':
425                         c[0].firstChild.value = row.tag.value;
426                         c[0].firstChild.select();
427                         c[0].firstChild.setAttribute('mynode', row.tag.id);
428                         c[1].firstChild.value = row.data.value;
429                         c[1].firstChild.select();
430                         c[1].firstChild.setAttribute('mynode', row.data.id);
431                         apply_event_listeners(c,'ctrl');
432                         break;
433                 case 'datafield':
434                         c[0].firstChild.value = row.tag.value;
435                         c[0].firstChild.select();
436                         c[0].firstChild.setAttribute('mynode', row.tag.id);
437                         c[1].firstChild.value = row.ind1.value;
438                         c[1].firstChild.select();
439                         c[1].firstChild.setAttribute('mynode', row.ind1.id);
440                         c[2].firstChild.value = row.ind2.value;
441                         c[2].firstChild.select();
442                         c[2].firstChild.setAttribute('mynode', row.ind2.id);
443                         c[3].firstChild.value = row.data.value;
444                         c[3].firstChild.select();
445                         c[3].firstChild.setAttribute('mynode', row.data.id);
446                         apply_event_listeners(c,'data');
447                         break;
448         }
449         //resizeWrapper(c3);
450 }
451
452 function handle_change(ev) {
453         mw.sdump('D_CAT','handle_change\n');
454         var t = ev.target;
455         // parse subfields
456         resizeWrapper(t);
457 }
458
459 function resizeWrapper(t) {
460         if (t.tagName != 'textbox') { return; }
461         var wrapper = t.parentNode;
462         var width = wrapper.boxObject.width;
463         var height = wrapper.boxObject.height;
464
465         /*var lwidth = character_measure.width * t.value.length; // linux */
466         var lwidth = (character_measure.width*2+5) * t.value.length; // windows
467         var lheight = character_measure.height;
468
469         if (width == 0) { width = lwidth; }
470         var xrows = Math.ceil( lwidth / width );
471         if (xrows < 1) { xrows = 1; }
472         var xheight = (xrows * (lheight+5)); 
473
474         //mw.sdump('D_CAT',wrapper.parentNode.id + ' wrapper: ' + width + 'x' + height + ' label: ' + lwidth + 'x' + lheight + '\n');
475         wrapper.setAttribute('style','min-height: ' + xheight + 'px;');
476 }
477
478 function resizeAllWrappers(rows) {
479         mw.sdump('D_CAT','Entering resizeAllWrappers() : ' + timer_elapsed('cat') + '\n');
480         var p = document.getElementById(rows);
481         var c = p.childNodes;
482         for (var r in c) {
483                 if (typeof(c[r])=='object') {
484                         if (c[r].getAttribute('notempty')) {
485                                 resizeWrapper(c[r].lastChild.firstChild);
486                         } else {
487                                 p.removeChild(c[r]);
488                         }
489                 }
490         }
491         mw.sdump('D_CAT','Exiting resizeAllWrappers() : ' + timer_elapsed('cat') + '\n');
492 }
493
494 function find_element_with_id(ns_slice,id) {
495         // we might change this in the future to be a hash lookup
496         // { node id => [lvl 1 index, lvl 2 index, lvl 3 index]  }
497         // with the hash being populated when the tree is generated
498         // and updated when we go to insert nodes
499         //mw.sdump('D_CAT','Find ' + id + ' in ' + js2JSON(ns_slice) + '\n');
500         //mw.sdump('D_CAT','Find ' + id + '\n');
501         for (i in ns_slice) {
502                 if (ns_slice[i].intra_doc_id() == id) {
503                         //mw.sdump('D_CAT','Found at index ' + i + '\n');
504                         return i;
505                 }
506         }
507         mw.sdump('D_CAT',id + 'not found in' + js2JSON(ns_slice) + '\n');
508 }
509
510 function delete_children(branch) {
511         var children = branch.children();
512         for (var c in children) {
513                 children[c].isdeleted(1);
514                 mw.sdump('D_CAT', children[c].name() + ':' +
515                         children[c].id() + ':' +
516                         children[c].intra_doc_id() + '.is_deleted = 1\n');
517                 if (children[c].children()) {
518                         delete_children(children[c]);
519                 }
520         }
521 }
522
523 function submit_marc() {
524         // walk through the marc grid and compare with the tree
525         // 1) updates and deletes
526
527 mw.sdump('D_CAT','Updates and Deletes\n');
528         backup_tree = JSON2js( js2JSON( tree ) );
529
530         var tree_fields = tree.children(); // LEVEL 1
531         var ctrl_rows = document.getElementById('ctrl_rows').childNodes;
532         for (var r = 0; r < ctrl_rows.length ; r++) {
533                 //if (r == 0) { continue; } // skip leader for now
534                 //mw.sdump('D_CAT', r + '\n');
535                 var tag_node_id;
536                 try {
537                         tag_node_id = ctrl_rows[r].getAttribute('mynode');
538                 } catch(E) {
539                         mw.sdump('D_CAT','Could not find mynode in ctrl_rows[' + r + ']\n');
540                         continue;
541                 }
542                 //mw.sdump('D_CAT', r + ':' + ctrl_rows[r].tagName + ':' + tag_node_id + '\n' );
543                 if (tag_node_id) {
544 mw.sdump('D_CAT','Processing ctrl_rows[' + r + '], tag_node_id = ' + tag_node_id + '\n');
545                         if (tag_node_id < 0) { continue; } // new node, handle elsewhere
546 mw.sdump('D_CAT','1st find =========================================\n')
547                         var tree_pos = find_element_with_id(tree_fields,tag_node_id);
548                         if (tree_pos == null) { alert('tree_pos problem!'); }
549                         var tree_field = tree_fields[tree_pos];
550
551                         if (ctrl_rows[r].getAttribute('hidden') == 'true') {
552                                 tree_field.isdeleted(1);
553                                 mw.sdump('D_CAT', tree_field.name() + ':' +
554                                         tree_field.id() + ':' +
555                                         tree_field.intra_doc_id() + '.isdeleted = 1\n');
556                                 delete_children(tree_field);
557                                 continue;
558                         }
559
560                         var col1 = ctrl_rows[r].childNodes[0].firstChild;
561                         var col2 = ctrl_rows[r].childNodes[1].firstChild;
562                         var id1 = col1.getAttribute('mynode');
563                         var id2 = col2.getAttribute('mynode');
564                         mw.sdump('D_CAT','id1 = ' + id1 + ' col1.value = ' + col1.value + '  id2 = ' + id2 + ' col2.value = ' + col2.value + '\n');
565                         var tree_field_children = tree_field.children(); // LEVEL 2
566
567                         if (r == 0) { // leader is special.  Only one child
568                                 if (tree_field_children[0].value() != col2.value) {
569                                         tree_field_children[0].value(col2.value);
570                                         tree_field_children[0].ischanged(1);
571                                         mw.sdump('D_CAT', tree_field_children[0].name() + ':' +
572                                                 tree_field_children[0].id() + ':' +
573                                                 tree_field_children[0].intra_doc_id() +
574                                                 '.ischanged = 1\n');
575                                 }
576                                 continue;
577                         }
578
579 mw.sdump('D_CAT','2nd find =========================================\n')
580                         var tree_tag = find_element_with_id(tree_field_children,id1);
581 mw.sdump('D_CAT','3rd find =========================================\n')
582                         var tree_value = find_element_with_id(tree_field_children,id2);
583                         if (tree_tag == null) { alert('tree_tag problem!'); }
584                         if (tree_value == null) { alert('tree_value problem!'); }
585                         if (tree_field_children[tree_tag].value() != col1.value) {
586                                 tree_field_children[tree_tag].value(col1.value);
587                                 tree_field_children[tree_tag].ischanged(1);
588                                 mw.sdump('D_CAT', tree_field_children[tree_tag].name() + ':' +
589                                         tree_field_children[tree_tag].id() + ':' +
590                                         tree_field_children[tree_tag].intra_doc_id() +
591                                         '.ischanged = 1\n');
592                         }
593                         if (tree_field_children[tree_value].value() != col2.value) {
594                                 tree_field_children[tree_value].value(col2.value);
595                                 tree_field_children[tree_value].ischanged(1);
596                                 mw.sdump('D_CAT', tree_field_children[tree_value].name() + ':' +
597                                         tree_field_children[tree_value].id() + ':' +
598                                         tree_field_children[tree_value].intra_doc_id() +
599                                         '.ischanged = 1\n');
600                         }
601                 }
602         }
603         var data_rows = document.getElementById('data_rows').childNodes;
604         for (var r = 0; r < data_rows.length ; r++ ) {
605                 var tag_node_id;
606                 try {
607                         tag_node_id = data_rows[r].getAttribute('mynode');
608                 } catch(E) {
609                         continue;
610                 }
611                 //mw.sdump('D_CAT', r + ':' + data_rows[r].tagName + ':' + tag_node_id + '\n' );
612                 if (tag_node_id) {
613 mw.sdump('D_CAT','Processing data_rows[' + r + '], tag_node_id = ' + tag_node_id + '\n');
614                         if (tag_node_id < 0) { continue; } // new node, handle elsewhere
615 mw.sdump('D_CAT','4th find =========================================\n')
616                         var tree_pos = find_element_with_id(tree_fields,tag_node_id);
617                         if (tree_pos == null) { alert('tree_pos problem!'); }
618                         var tree_field = tree_fields[tree_pos];
619
620                         if (data_rows[r].getAttribute('hidden') == 'true') {
621                                 tree_field.isdeleted(1);
622                                 mw.sdump('D_CAT',tree_field.name() + ':' +
623                                         tree_field.id() + ':' +
624                                         tree_field.intra_doc_id() +
625                                         '.isdeleted = 1\n');
626                                 delete_children(tree_field);
627                                 continue;
628                         }
629
630                         var col1 = data_rows[r].childNodes[0].firstChild;
631                         var col2 = data_rows[r].childNodes[1].firstChild;
632                         var col3 = data_rows[r].childNodes[2].firstChild;
633                         var col4 = data_rows[r].childNodes[3].firstChild;
634                         var id1 = col1.getAttribute('mynode');
635                         var id2 = col2.getAttribute('mynode');
636                         var id3 = col3.getAttribute('mynode');
637                         var id4 = col4.getAttribute('mynode');
638                         var tree_field_children = tree_field.children(); // LEVEL 2
639 mw.sdump('D_CAT','5th find =========================================\n')
640                         var tree_tag = find_element_with_id(tree_field_children,id1);
641 mw.sdump('D_CAT','6th find =========================================\n')
642                         var tree_ind1 = find_element_with_id(tree_field_children,id2);
643 mw.sdump('D_CAT','7th find =========================================\n')
644                         var tree_ind2 = find_element_with_id(tree_field_children,id3);
645 mw.sdump('D_CAT','8th find =========================================\n')
646                         var tree_data = find_element_with_id(tree_field_children,id4);
647                         if (tree_tag == null) { alert('tree_tag problem!'); }
648                         if (tree_ind1 == null) { alert('tree_ind1 problem!'); }
649                         if (tree_ind2 == null) { alert('tree_ind2 problem!'); }
650                         if (tree_data == null) { alert('tree_data problem!'); }
651                         if (tree_field_children[tree_tag].value() != col1.value) {
652                                 tree_field_children[tree_tag].value(col1.value);
653                                 tree_field_children[tree_tag].ischanged(1);
654                                 mw.sdump('D_CAT', tree_field_children[tree_tag].name() + ':' +
655                                         tree_field_children[tree_tag].id() + ':' +
656                                         tree_field_children[tree_tag].intra_doc_id() +
657                                         '.is_changed = 1\n');
658                         }
659                         if (tree_field_children[tree_ind1].value() != col2.value) {
660                                 tree_field_children[tree_ind1].value(col2.value);
661                                 tree_field_children[tree_ind1].ischanged(1);
662                                 mw.sdump('D_CAT', tree_field_children[tree_ind1].name() + ':' +
663                                         tree_field_children[tree_ind1].id() + ':' +
664                                         tree_field_children[tree_ind1].intra_doc_id() +
665                                         '.is_changed = 1\n');
666                         }
667                         if (tree_field_children[tree_ind2].value() != col3.value) {
668                                 tree_field_children[tree_ind2].value(col3.value);
669                                 tree_field_children[tree_ind2].ischanged(1);
670                                 mw.sdump('D_CAT', tree_field_children[tree_ind2].name() + ':' +
671                                         tree_field_children[tree_ind2].id() + ':' +
672                                         tree_field_children[tree_ind2].intra_doc_id() +
673                                         '.is_changed = 1\n');
674                         }
675                         process_subfields(tree_field_children,col4.value); // LEVEL 3
676                 }
677         }
678
679
680         // 2) inserts
681 mw.sdump('D_CAT','Inserts\n');
682
683         for (var r = 0; r < ctrl_rows.length ; r++) {
684                 var newnode;
685                 try {
686                         newnode = ctrl_rows[r].getAttribute('newnode');
687                 } catch(E) {
688                         continue;
689                 }
690                 if (newnode=='true') {
691 mw.sdump('D_CAT','New node = ctrl_rows[' + r + ']');
692                         if (ctrl_rows[r].getAttribute('hidden')=='true') { continue; }
693                         var col1 = ctrl_rows[r].childNodes[0].firstChild.value;
694                         var col2 = ctrl_rows[r].childNodes[1].firstChild.value;
695                         var level1 = new brn(); 
696                                 populate_node( level1, 1, 'controlfield' );
697                         var level2a = new brn(); 
698                                 populate_node( level2a, 2, 'tag' );
699                                 level2a.value(col1);
700                         var level2b = new brn();
701                                 populate_node( level2b, 3, null );
702                                 level2b.value(col2);
703                         level1.children([ level2a, level2b ]);
704                         ctrl_rows[r].setAttribute('mynode', level1.intra_doc_id());
705 mw.sdump('D_CAT',' with intra_doc_id = ' + level1.intra_doc_id() + '\n');
706                         insert_into_tree(tree.children(),ctrl_rows[r],level1);
707                 }
708         }
709
710         for (var r = 0; r < data_rows.length ; r++) {
711                 var newnode;
712                 try {
713                         newnode = data_rows[r].getAttribute('newnode');
714                 } catch(E) {
715                         continue;
716                 }
717                 if (newnode=='true') {
718 mw.sdump('D_CAT','New node = data_rows[' + r + ']');
719                         if (data_rows[r].getAttribute('hidden')=='true') { continue; }
720                         var col1 = data_rows[r].childNodes[0].firstChild.value;
721                         var col2 = data_rows[r].childNodes[1].firstChild.value;
722                         var col3 = data_rows[r].childNodes[2].firstChild.value;
723                         var col4 = data_rows[r].childNodes[3].firstChild.value;
724                         var level1 = new brn(); 
725                                 populate_node( level1, 1, 'datafield' );
726                         var level2a = new brn(); 
727                                 populate_node( level2a, 2, 'tag' );
728                                 level2a.value(col1);
729                         var level2b = new brn();
730                                 populate_node( level2b, 2, 'ind1' );
731                                 level2b.value(col2);
732                         var level2c = new brn();
733                                 populate_node( level2c, 2, 'ind2' );
734                                 level2c.value(col3);
735                         level1.children([ level2a, level2b, level2c ]);
736                         process_subfields(level1.children(),col4);
737                         data_rows[r].setAttribute('mynode', level1.intra_doc_id());
738 mw.sdump('D_CAT',' with intra_doc_id = ' + level1.intra_doc_id() + '\n');
739                         insert_into_tree(tree.children(),data_rows[r],level1);
740                 }
741
742         }
743         //mw.sdump('D_CAT','******\nSending: ' + pretty_print(js2JSON(tree)) + '\n');
744         mw.sdump('D_CAT','Auth session: ' + mw.G['auth_ses'][0] + '\n');
745         try {
746                 if (params.import_tree) {
747                         tree = user_request(
748                                         'open-ils.cat',
749                                         'open-ils.cat.biblio.record.tree.import',
750                                         [ mw.G['auth_ses'][0], tree ]
751                         )[0];
752         
753                 } else {
754                         tree = user_request(
755                                         'open-ils.cat',
756                                         'open-ils.cat.biblio.record.tree.commit',
757                                         [ mw.G['auth_ses'][0], tree ]
758                         )[0];
759                 }
760                 if (typeof(tree) == 'object') {
761                         mw.sdump('D_CAT','\n\n\n\nnew tree = ' + js2JSON(tree) + '\n');
762                         params.import_tree = false;
763                         new_node_id = -1;
764                         empty_grid('ctrl_rows','data_rows');
765                         build_grid( 
766                                 document.getElementById('ctrl_rows'), 
767                                 document.getElementById('data_rows'), 
768                                 tree
769                         );
770                         handle_tag_change();
771                         my_resize_handler();
772                         alert('MARC record successfully updated.');
773                 } else {
774                         throw('result: ' + tree + '\n');
775                 }
776         } catch(E) {
777                 mw.sdump('D_CAT','backup_tree\n');
778                 tree = backup_tree;
779                 handle_tag_change();
780                 my_resize_handler();
781                 handle_error(E);
782         }
783 }
784
785 function insert_into_tree(branch,r,n) {
786         var s = nextSibling_not_hidden(r);
787         if (s) {
788                 mw.sdump('D_CAT','9th find =========================================\n')
789                 mw.sdump('D_CAT','s = ' + s + '\n');
790                 mw.sdump('D_CAT','s.getAttribute mynode = <' + s.getAttribute('mynode') + '>\n');
791                 var pos = find_element_with_id(branch,s.getAttribute('mynode'));
792                 branch.splice(pos,0,n);
793         } else {
794                 branch.push(n);
795         }
796 }
797
798 var new_node_id = -1;
799 function populate_node(node,ntype,name) {
800         node.intra_doc_id( new_node_id-- );
801         node.isnew( 1 );
802         node.node_type( ntype );
803         node.name( name );
804         mw.sdump('D_CAT', node.name() + ':' + node.intra_doc_id() + '.is_new = 1\n');
805 }
806
807 function process_subfields(tfc,datastring) {
808         mw.sdump('D_CAT','process_subfields: <' + tfc + '> <' + datastring + '>\n');
809         var orig_subfields = [];
810         //mw.sdump('D_CAT','\n');
811         for (var i in tfc) {
812                 mw.sdump('D_CAT',i + ' : ' + typeof(tfc[i]) + ' : ' + js2JSON(tfc[i]) + ' : node_type() = ' + tfc[i].node_type() + '\n');
813                 try {
814                         if (tfc[i].node_type() == 1) {
815                                 var orig_data = tfc[i].children()[1].value();
816                                 orig_data = orig_data.replace(/^\s+/,'').replace(/\s+$/,'');
817                                 orig_subfields.push( [ 
818                                         i, // subfield node index
819                                         tfc[i].children()[0].value(), // subf indicator
820                                         orig_data // data
821                                 ] );
822                         }
823
824                 } catch(E) {
825                         mw.sdump('D_CAT','\tan error? gasp: ' + js2JSON(E) + '\n');
826                         continue;
827                 }
828         }
829         datastring = datastring.replace(/^\s+/,'').replace(/\s+$/,'');
830         var local_subf_array = datastring.split(String.fromCharCode(8225));
831         // Our validation routines should assert that the beginning of
832         // a data string start with the subfield delimiter symbol.  We're
833         // passing the buck of the 'implicit' subfield-a check elsewhere.
834         local_subf_array.shift();
835         mw.sdump('D_CAT','orig_subfields = ' + js2JSON(orig_subfields) + '\n');
836         mw.sdump('D_CAT','local_subfields = ' + js2JSON(local_subf_array) + '\n');
837         for (var i in local_subf_array) {
838                 if ((local_subf_array[i]=='')||(local_subf_array==null)) { continue; }
839                 var s_ind = local_subf_array[i].substr(0,1);
840                 var s_data = local_subf_array[i].substr(1).replace(/^\s+/,'').replace(/\s+$/,'');
841                 mw.sdump('D_CAT','Processing code = ' + s_ind + ' and value = ' + s_data + '\n');
842                 if (!orig_subfields[i]) { // new subfield
843                         mw.sdump('D_CAT','making new subfield : i = ' + i + '\n');
844                         var level1 = new brn(); 
845                                 populate_node( level1, 1, 'subfield' );
846                         var level2a = new brn(); 
847                                 populate_node( level2a, 2, 'code' );
848                                 level2a.value(s_ind);
849                         var level2b = new brn();
850                                 populate_node( level2b, 3, null );
851                                 level2b.value(s_data);
852                         level1.children([ level2a, level2b ]);
853                         tfc.push(level1);
854                         mw.sdump('D_CAT','New node = ' + js2JSON(level1) + '\n');
855                 } else {
856                         var orig_node = orig_subfields[i][0];
857                         var orig_ind = orig_subfields[i][1];
858                         var orig_data = orig_subfields[i][2];
859                         if (orig_ind != s_ind) { // update subf indicator
860                                 tfc[orig_node].children()[0].value(s_ind);
861                                 tfc[orig_node].children()[0].ischanged(1);
862                                 mw.sdump('D_CAT', tfc[orig_node].children()[0].name() + ':' +
863                                         tfc[orig_node].children()[0].id() + ':' +
864                                         tfc[orig_node].children()[0].intra_doc_id() +
865                                         '.is_changed = 1\n');
866                         mw.sdump('D_CAT','Updated node = ' + js2JSON(tfc[orig_node].children()[0]) + '\n');
867                         }
868                         if (orig_data != s_data) { // update subf data
869                                 tfc[orig_node].children()[1].value(s_data);
870                                 tfc[orig_node].children()[1].ischanged(1);
871                                 mw.sdump('D_CAT', tfc[orig_node].children()[1].name() + ':' +
872                                         tfc[orig_node].children()[1].id() + ':' +
873                                         tfc[orig_node].children()[1].intra_doc_id() +
874                                         '.is_changed = 1\n');
875                         mw.sdump('D_CAT','Updated node = ' + js2JSON(tfc[orig_node].children()[1]) + '\n');
876                         }
877                 }
878         }
879         // delete any remaining
880         for (var i = local_subf_array.length; i < orig_subfields.length; i++) {
881                 var orig_node = orig_subfields[i][0];
882                 tfc[orig_node].isdeleted(1);
883                 mw.sdump('D_CAT', tfc[orig_node].name() + ':' +
884                         tfc[orig_node].id() + ':' +
885                         tfc[orig_node].intra_doc_id() + '.is_deleted = 1\n');
886                 delete_children(tfc[orig_node]);
887         }
888 }
889
890
891
892 function test_nodeset() {
893         return null;
894 }