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