]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/cat/z3950.js
refactoring.. moved some list print/clipboard functions into list.js
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / cat / z3950.js
1 dump('entering cat.z3950.js\n');
2
3 if (typeof cat == 'undefined') cat = {};
4 cat.z3950 = function (params) {
5         try {
6                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
7                 JSAN.use('util.error'); this.error = new util.error();
8                 JSAN.use('util.network'); this.network = new util.network();
9         } catch(E) {
10                 dump('cat.z3950: ' + E + '\n');
11         }
12 }
13
14 cat.z3950.prototype = {
15
16         'creds_version' : 1,
17
18     'number_of_result_sets' : 0,
19
20     'result_set' : [],
21
22         'init' : function( params ) {
23
24                 try {
25                         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
26                         JSAN.use('util.widgets');
27
28                         var obj = this;
29
30                         obj.load_creds();
31
32                         JSAN.use('circ.util');
33                         var columns = circ.util.columns(
34                                 {
35                                         'tcn' : { 'hidden' : false },
36                                         'isbn' : { 'hidden' : false },
37                                         'title' : { 'hidden' : false, 'flex' : '1' },
38                                         'author' : { 'hidden' : false },
39                                         'edition' : { 'hidden' : false },
40                                         'pubdate' : { 'hidden' : false },
41                                         'publisher' : { 'hidden' : false },
42                                 }
43                         );
44
45                         JSAN.use('util.list'); obj.list = new util.list('results');
46                         obj.list.init(
47                                 {
48                                         'columns' : columns,
49                                         'map_row_to_columns' : circ.util.std_map_row_to_columns(),
50                                         'on_select' : function(ev) {
51                                                 try {
52                                                         JSAN.use('util.functional');
53                                                         var sel = obj.list.retrieve_selection();
54                                                         document.getElementById('clip_button').disabled = sel.length < 1;
55                                                         var list = util.functional.map_list(
56                                                                 sel,
57                                                                 function(o) { return o.getAttribute('retrieve_id'); }
58                                                         );
59                                                         obj.error.sdump('D_TRACE','cat/z3950: selection list = ' + js2JSON(list) );
60                                                         obj.controller.view.marc_import.disabled = false;
61                                                         obj.controller.view.marc_import.setAttribute('retrieve_id',list[0]);
62                                                         obj.controller.view.marc_import_overlay.disabled = false;
63                                                         obj.controller.view.marc_import_overlay.setAttribute('retrieve_id',list[0]);
64                                                         obj.controller.view.marc_view.disabled = false;
65                                                         obj.controller.view.marc_view.setAttribute('retrieve_id',list[0]);
66                                                 } catch(E) {
67                                                         obj.error.standard_unexpected_error_alert('Failure during list construction.',E);
68                                                 }
69                                         },
70                                 }
71                         );
72
73                         JSAN.use('util.controller'); obj.controller = new util.controller();
74                         obj.controller.init(
75                                 {
76                                         control_map : {
77                                                 'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
78                                                 'sel_clip' : [
79                                                         ['command'],
80                                                         function() { obj.list.clipboard(); }
81                                                 ],
82                                                 'cmd_export' : [
83                                                         ['command'],
84                                                         function() {
85                                                                 obj.list.dump_csv_to_clipboard();
86                                                         }
87                                                 ],
88                                                 'cmd_broken' : [
89                                                         ['command'],
90                                                         function() { alert('Not Yet Implemented'); }
91                                                 ],
92                                                 'result_message' : [['render'],function(e){return function(){};}],
93                                                 'clear' : [
94                                                         ['command'],
95                                                         function() {
96                                                                 obj.clear();
97                                                         }
98                                                 ],
99                                                 'save_creds' : [
100                                                         ['command'],
101                                                         function() {
102                                                                 obj.save_creds();
103                                                         }
104                                                 ],
105                                                 'marc_view' : [
106                                                         ['command'],
107                                                         function(ev) {
108                                                                 try {
109                                                                         var n = obj.controller.view.marc_view;
110                                                                         if (n.getAttribute('toggle') == '1') {
111                                                                                 document.getElementById('deck').selectedIndex = 0;
112                                                                                 n.setAttribute('toggle','0');
113                                                                                 n.setAttribute('label','MARC View');
114                                                                                 document.getElementById('results').focus();
115                                                                         } else {
116                                                                                 document.getElementById('deck').selectedIndex = 1;
117                                                                                 n.setAttribute('toggle','1');
118                                                                                 n.setAttribute('label','Results View');
119                                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
120                                                                                 var f = get_contentWindow(document.getElementById('marc_frame'));
121                                         var retrieve_id = n.getAttribute('retrieve_id');
122                                         var result_idx = retrieve_id.split('-')[0];
123                                         var record_idx = retrieve_id.split('-')[1];
124                                                                                 f.xulG = { 'marcxml' : obj.result_set[result_idx].records[ record_idx ].marcxml };
125                                                                                 f.my_init();
126                                                                                 f.document.body.firstChild.focus();
127                                                                         }
128                                                                 } catch(E) {
129                                                 obj.error.standard_unexpected_error_alert('Failure during marc view.',E);
130                                                                 }
131                                                         },
132                                                 ],
133                                                 'marc_import' : [
134                                                         ['command'],
135                                                         function() {
136                                 try {
137                                     var retrieve_id = obj.controller.view.marc_import.getAttribute('retrieve_id');
138                                     var result_idx = retrieve_id.split('-')[0];
139                                     var record_idx = retrieve_id.split('-')[1];
140                                     obj.spawn_marc_editor( obj.result_set[ result_idx ].records[ record_idx ].marcxml);
141                                 } catch(E) {
142                                                 obj.error.standard_unexpected_error_alert('Failure during marc import.',E);
143                                 }
144                                                         },
145                                                 ],
146                                                 'marc_import_overlay' : [ 
147                                                         ['command'],
148                                                         function() {
149                                                                 try {
150                                     var retrieve_id = obj.controller.view.marc_import_overlay.getAttribute('retrieve_id');
151                                     var result_idx = retrieve_id.split('-')[0];
152                                     var record_idx = retrieve_id.split('-')[1];
153                                     obj.spawn_marc_editor_for_overlay( obj.result_set[ result_idx ].records[ record_idx ].marcxml);
154                                                                 } catch(E) {
155                                                 obj.error.standard_unexpected_error_alert('Failure during marc import overlay.',E);
156                                                                 }
157                                                         },
158                                                 ],
159                                                 'search' : [
160                                                         ['command'],
161                                                         function() {
162                                                                 obj.initial_search();
163                                                         },
164                                                 ],
165                                                 'page_next' : [
166                                                         ['command'],
167                                                         function() {
168                                                                 obj.page_next();
169                                                         },
170                                                 ],
171                                                 'raw_search' : [
172                                                         ['command'],
173                                                         function() {
174                                                                 var raw = window.prompt('WARNING: This is not a simple keyword search.  Enter raw z39.50 PQN search string: ','','Raw Z39.50 PQN Search');
175                                                                 if (raw) obj.initial_raw_search(raw);
176                                                         },
177                                                 ],
178                                                 'menu_placeholder' : [
179                                                         ['render'],
180                                                         function(e) {
181                                                                 return function() {
182                                                                         try {
183
184                                                                                 function handle_switch(node) {
185                                                                                         var service = obj.controller.view.service_menu.value;
186                                                                                         obj.current_service = service;
187                                                                                         var nl = document.getElementsByAttribute('mytype','search_class');
188                                                                                         for (var i = 0; i < nl.length; i++) { nl[i].disabled = true; }
189                                                                                         for (var i in obj.services[service].attrs) {
190                                                                                                 var x = document.getElementById(i + '_input');
191                                                                                                 if (x) {
192                                                                                                         x.disabled = false;
193                                                                                                 } else {
194                                                                                                         var rows = document.getElementById('query_inputs');
195                                                                                                         var row = document.createElement('row'); rows.appendChild(row);
196                                                                                                         var label = document.createElement('label');
197                                                                                                         label.setAttribute('control',i+'_input');
198                                                                                                         label.setAttribute('search_class',i);
199                                                                                                         label.setAttribute('style','-moz-user-focus: ignore');
200                                                                                                         if (entities['staff.z39_50.search_class.'+i]) {
201                                                                                                                 label.setAttribute('value',entities['staff.z39_50.search_class.'+i]);
202                                                                                                         } else {
203                                                                                                                 label.setAttribute('value',i);
204                                                                                                         }
205                                                                                                         row.appendChild(label);
206                                                                                                         label.addEventListener('click',function(ev){
207                                                                                                                         var a = ev.target.getAttribute('search_class');
208                                                                                                                         if (a) obj.default_attr = a;
209                                                                                                                 },false
210                                                                                                         );
211                                                                                                         var tb = document.createElement('textbox');
212                                                                                                         tb.setAttribute('id',i+'_input');
213                                                                                                         tb.setAttribute('mytype','search_class');
214                                                                                                         tb.setAttribute('search_class',i);
215                                                                                                         row.appendChild(tb);
216                                                                                                         tb.addEventListener('keypress',obj.handle_enter,false);
217                                                                                                 }
218                                                                                         }
219                                                                                         if (obj.creds.services[ service ]) {
220                                                                                                 document.getElementById('username').setAttribute('value',
221                                                                                                         obj.creds.services[service].username
222                                                                                                 );
223                                                                                                 document.getElementById('password').setAttribute('value',
224                                                                                                         obj.creds.services[service].password
225                                                                                                 );
226                                                                                                 try { g.service = service; } catch(E) {}
227                                                                                                 obj.focus(service);
228                                                                                         } else {
229                                                                                                 document.getElementById('username').focus();
230                                                                                         }
231                                                                                 }
232
233                                                                                 var robj = obj.network.simple_request(
234                                                                                         'RETRIEVE_Z3950_SERVICES',
235                                                                                         [ ses() ]
236                                                                                 );
237                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
238                                                                                 obj.services = robj;
239                                                                                 var list = [];
240                                                                                 for (var i in robj) {
241                                                                                         list.push(
242                                                                                                 [
243                                                                                                         i + ' : ' + robj[i].db + '@' + robj[i].host + ':' + robj[i].port,
244                                                                                                         i
245                                                                                                 ]
246                                                                                         );
247                                                                                 }
248                                                                                 util.widgets.remove_children(e);
249                                                                                 var ml = util.widgets.make_menulist( list );
250                                                                                 ml.setAttribute('flex','1');
251                                                                                 e.appendChild(ml);
252                                                                                 ml.addEventListener(
253                                                                                         'command',
254                                                                                         function(ev) { handle_switch(ev.target); },
255                                                                                         false
256                                                                                 );
257                                                                                 obj.controller.view.service_menu = ml;
258                                                                                 setTimeout(
259                                                                                         function() { 
260                                                                                                 if (obj.creds.default_service) ml.value = obj.creds.default_service;
261                                                                                                 handle_switch(ml); 
262                                                                                         },0
263                                                                                 );
264                                                                         } catch(E) {
265                                                                                 obj.error.standard_unexpected_error_alert('Z39.50 services not likely retrieved.',E);
266                                                                         }
267                                                                 }
268                                                         }
269                                                 ],
270                                         }
271                                 }
272                         );
273
274                         obj.controller.render();
275
276                         obj.controller.view.username = document.getElementById('username');
277                         obj.controller.view.password = document.getElementById('password');
278
279                 } catch(E) {
280                         this.error.sdump('D_ERROR','cat.z3950.init: ' + E + '\n');
281                 }
282         },
283
284         'focus' : function(service) {
285                 var obj = this;
286                 var x = obj.creds.services[service].default_attr;
287                 if (x) {
288                         var xx = document.getElementById(x+'_input'); if (xx) xx.focus();
289                 } else {
290                         var y;
291                         for (var i in obj.services[service].attr) { y = i; }
292                         var xx = document.getElementById(y+'_input'); if (xx) xx.focus();
293                 }
294         },
295
296         'clear' : function() {
297                 var obj = this;
298                 var nl = document.getElementsByAttribute('mytype','search_class');
299                 for (var i = 0; i < nl.length; i++) { nl[i].value = ''; nl[i].setAttribute('value',''); }
300                 obj.focus(obj.controller.view.service_menu.value);
301         },
302
303         'search_params' : {},
304
305         'initial_search' : function() {
306                 try {
307                         var obj = this;
308             obj.result_set = []; obj.number_of_result_sets = 0;
309                         JSAN.use('util.widgets');
310                         util.widgets.remove_children( obj.controller.view.result_message );
311                         var x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
312                         x.appendChild( document.createTextNode( 'Searching...' ));
313                         obj.search_params = {}; obj.list.clear();
314                         obj.controller.view.page_next.disabled = true;
315
316                         obj.search_params.service = obj.controller.view.service_menu.value;
317                         obj.search_params.username = obj.controller.view.username.value;
318                         obj.search_params.password = obj.controller.view.password.value;
319                         obj.search_params.limit = 10;
320                         obj.search_params.offset = 0;
321
322                         obj.search_params.search = {};
323                         var nl = document.getElementsByAttribute('mytype','search_class');
324                         var count = 0;
325                         for (var i = 0; i < nl.length; i++) {
326                                 if (nl[i].disabled) continue;
327                                 if (nl[i].value == '') continue;
328                                 count++;
329                                 obj.search_params.search[ nl[i].getAttribute('search_class') ] = nl[i].value;
330                         }
331                         if (count>0) {
332                                 obj.search();
333                         } else {
334                                 util.widgets.remove_children( obj.controller.view.result_message );
335                         }
336                 } catch(E) {
337                         this.error.standard_unexpected_error_alert('Failure during initial search.',E);
338                 }
339         },
340
341         'initial_raw_search' : function(raw) {
342                 try {
343                         var obj = this;
344             obj.result_set = []; obj.number_of_result_sets = 0;
345                         JSAN.use('util.widgets');
346                         util.widgets.remove_children( obj.controller.view.result_message );
347                         var x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
348                         x.appendChild( document.createTextNode( 'Searching...' ) );
349                         obj.search_params = {}; obj.result_count = 0; obj.list.clear();
350                         obj.controller.view.page_next.disabled = true;
351
352                         obj.search_params.service = obj.controller.view.service_menu.value;
353                         obj.search_params.username = obj.controller.view.username.value;
354                         obj.search_params.password = obj.controller.view.password.value;
355                         obj.search_params.limit = 10;
356                         obj.search_params.offset = 0;
357
358                         obj.search_params.query = raw;
359
360                         obj.search();
361                 } catch(E) {
362                         this.error.standard_unexpected_error_alert('Failure during initial raw search.',E);
363                 }
364         },
365
366         'page_next' : function() {
367                 try {
368                         var obj = this;
369                         JSAN.use('util.widgets');
370                         util.widgets.remove_children( obj.controller.view.result_message );
371                         var x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
372                         x.appendChild( document.createTextNode( 'Retrieving more results...' ));
373                         obj.search_params.offset += obj.search_params.limit;
374                         obj.search();
375                 } catch(E) {
376                         this.error.standard_unexpected_error_alert('Failure during subsequent search.',E);
377                 }
378         },
379
380         'search' : function() {
381                 try {
382                         var obj = this;
383                         var method;
384                         if (typeof obj.search_params.query == 'undefined') {
385                                 method = 'FM_BLOB_RETRIEVE_VIA_Z3950_SEARCH';
386                         } else {
387                                 method = 'FM_BLOB_RETRIEVE_VIA_Z3950_RAW_SEARCH';
388                         }
389                         obj.network.simple_request(
390                                 method,
391                                 [ ses(), obj.search_params ],
392                                 function(req) {
393                                         obj.handle_results(req.getResultObject())
394                                 }
395                         );
396                         document.getElementById('deck').selectedIndex = 0;
397                 } catch(E) {
398                         this.error.standard_unexpected_error_alert('Failure during actual search.',E);
399                 }
400         },
401
402         'handle_results' : function(results) {
403                 var obj = this;
404                 try {
405                         JSAN.use('util.widgets');
406                         util.widgets.remove_children( obj.controller.view.result_message ); var x;
407                         if (results == null) {
408                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
409                                 x.appendChild( document.createTextNode( 'Server Error: request returned null' ));
410                                 return;
411                         }
412                         if (typeof results.ilsevent != 'undefined') {
413                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
414                                 x.appendChild( document.createTextNode( 'Server Error: ' + results.textcode + ' : ' + results.desc ));
415                                 return;
416                         }
417                         if (results.query) {
418                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
419                                 x.appendChild( document.createTextNode( 'Raw query: ' + results.query ));
420                         }
421                         if (results.count) {
422                                 if (results.records) {
423                                         x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
424                                         x.appendChild(
425                                                 document.createTextNode( 'Showing ' + (obj.search_params.offset + results.records.length) + ' of ' + results.count)
426                                         );
427                                 }
428                                 if (obj.search_params.offset + obj.search_params.limit <= results.count) {
429                                         obj.controller.view.page_next.disabled = false;
430                                 }
431                         } else {
432                                         x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
433                                         x.appendChild(
434                                                 document.createTextNode( results.count + ' records found')
435                                         );
436                         }
437                         if (results.records) {
438                                 obj.result_set[ ++obj.number_of_result_sets ] = results;
439                                 obj.controller.view.marc_import.disabled = true;
440                                 obj.controller.view.marc_import_overlay.disabled = true;
441                                 var x = obj.controller.view.marc_view;
442                                 if (x.getAttribute('toggle') == '0') x.disabled = true;
443                                 for (var i = 0; i < obj.result_set[ obj.number_of_result_sets ].records.length; i++) {
444                                         obj.list.append(
445                                                 {
446                                                         'retrieve_id' : String( obj.number_of_result_sets ) + '-' + String( i ),
447                                                         'row' : {
448                                                                 'my' : {
449                                                                         'mvr' : function(a){return a;}(obj.result_set[ obj.number_of_result_sets ].records[i].mvr),
450                                                                 }
451                                                         }
452                                                 }
453                                         );
454                                 }
455                         } else {
456                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
457                                 x.appendChild(
458                                         document.createTextNode( 'Error retrieving results.')
459                                 );
460                         }
461                 } catch(E) {
462                         this.error.standard_unexpected_error_alert('Failure during search result handling.',E);
463                 }
464         },
465
466         'replace_tab_with_opac' : function(doc_id) {
467                 var opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + doc_id;
468                 var content_params = { 
469                         'session' : ses(),
470                         'authtime' : ses('authtime'),
471                         'opac_url' : opac_url,
472                 };
473                 xulG.set_tab(
474                         xulG.url_prefix(urls.XUL_OPAC_WRAPPER), 
475                         {'tab_name':'Retrieving title...'}, 
476                         content_params
477                 );
478         },
479
480         'spawn_marc_editor' : function(my_marcxml) {
481                 var obj = this;
482                 xulG.new_tab(
483                         xulG.url_prefix(urls.XUL_MARC_EDIT), 
484                         { 'tab_name' : 'MARC Editor' }, 
485                         { 
486                                 'record' : { 'marc' : my_marcxml },
487                                 'save' : {
488                                         'label' : 'Import Record',
489                                         'func' : function (new_marcxml) {
490                                                 try {
491                                                         var r = obj.network.simple_request('MARC_XML_RECORD_IMPORT', [ ses(), new_marcxml, obj.current_service ]);
492                                                         if (typeof r.ilsevent != 'undefined') {
493                                                                 switch(r.ilsevent) {
494                                                                         case 1704 /* TCN_EXISTS */ :
495                                                                                 var msg = 'A record with TCN ' + r.payload.tcn + ' already exists.\nFIXME: add record summary here';
496                                                                                 var title = 'Import Collision';
497                                                                                 var btn1 = 'Overlay';
498                                                                                 var btn2 = typeof r.payload.new_tcn == 'undefined' ? null : 'Import with alternate TCN ' + r.payload.new_tcn;
499                                                                                 if (btn2) {
500                                                                                         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
501                                                                                         var robj = obj.network.simple_request(
502                                                                                                 'PERM_CHECK',[
503                                                                                                         ses(),
504                                                                                                         data.list.au[0].id(),
505                                                                                                         data.list.au[0].ws_ou(),
506                                                                                                         [ 'ALLOW_ALT_TCN' ]
507                                                                                                 ]
508                                                                                         );
509                                                                                         if (typeof robj.ilsevent != 'undefined') {
510                                                                                                 obj.error.standard_unexpected_error_alert('check permission',E);
511                                                                                         }
512                                                                                         if (robj.length != 0) btn2 = null;
513                                                                                 }
514                                                                                 var btn3 = 'Cancel Import';
515                                                                                 var p = obj.error.yns_alert(msg,title,btn1,btn2,btn3,'Check here to confirm this action');
516                                                                                 obj.error.sdump('D_ERROR','option ' + p + 'chosen');
517                                                                                 switch(p) {
518                                                                                         case 0:
519                                                                                                 var r3 = obj.network.simple_request('MARC_XML_RECORD_UPDATE', [ ses(), r.payload.dup_record, new_marcxml, obj.current_service ]);
520                                                                                                 if (typeof r3.ilsevent != 'undefined') {
521                                                                                                         throw(r3);
522                                                                                                 } else {
523                                                                                                         alert('Record successfully overlayed.');
524                                                                                                         obj.replace_tab_with_opac(r3.id());
525                                                                                                 }
526                                                                                         break;
527                                                                                         case 1:
528                                                                                                 var r2 = obj.network.request(
529                                                                                                         api.MARC_XML_RECORD_IMPORT.app,
530                                                                                                         api.MARC_XML_RECORD_IMPORT.method + '.override',
531                                                                                                         [ ses(), new_marcxml, obj.current_service ]
532                                                                                                 );
533                                                                                                 if (typeof r2.ilsevent != 'undefined') {
534                                                                                                         throw(r2);
535                                                                                                 } else {
536                                                                                                         alert('Record successfully imported with alternate TCN.');
537                                                                                                         obj.replace_tab_with_opac(r2.id());
538                                                                                                 }
539                                                                                         break;
540                                                                                         case 2:
541                                                                                         default:
542                                                                                                 alert('Record import cancelled');
543                                                                                         break;
544                                                                                 }
545                                                                         break;
546                                                                         default:
547                                                                                 throw(r);
548                                                                         break;
549                                                                 }
550                                                         } else {
551                                                                 alert('Record successfully imported.');
552                                                                 obj.replace_tab_with_opac(r.id());
553                                                         }
554                                                 } catch(E) {
555                                                         obj.error.standard_unexpected_error_alert('Record not likely imported.',E);
556                                                 }
557                                         }
558                                 }
559                         } 
560                 );
561         },
562
563         'confirm_overlay' : function(record_ids) {
564                 var obj = this; // JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
565                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
566                 var top_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" >';
567                 top_xml += '<description>Overlay this record?</description>';
568                 top_xml += '<hbox><button id="lead" disabled="false" label="Overlay" name="fancy_submit" accesskey="O"/><button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox></vbox>';
569
570                 var xml = '<form xmlns="http://www.w3.org/1999/xhtml">';
571                 xml += '<table width="100%"><tr valign="top">';
572                 for (var i = 0; i < record_ids.length; i++) {
573                         xml += '<td nowrap="nowrap"><iframe src="' + urls.XUL_BIB_BRIEF; 
574                         xml += '?docid=' + record_ids[i] + '"/></td>';
575                 }
576                 xml += '</tr><tr valign="top">';
577                 for (var i = 0; i < record_ids.length; i++) {
578                         html = obj.network.simple_request('MARC_HTML_RETRIEVE',[ record_ids[i] ]);
579                         xml += '<td nowrap="nowrap"><iframe style="min-height: 1000px; min-width: 300px;" flex="1" src="data:text/html,' + window.escape(html) + '"/></td>';
580                 }
581                 xml += '</tr></table></form>';
582                 // data.temp_merge_top = top_xml; data.stash('temp_merge_top');
583                 // data.temp_merge_mid = xml; data.stash('temp_merge_mid');
584                 JSAN.use('util.window'); var win = new util.window();
585                 var fancy_prompt_data = win.open(
586                         urls.XUL_FANCY_PROMPT,
587                         // + '?xml_in_stash=temp_merge_mid'
588                         // + '&top_xml_in_stash=temp_merge_top'
589                         // + '&title=' + window.escape('Record Overlay'),
590                         'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
591                         { 'top_xml' : top_xml, 'xml' : xml, 'title' : 'Record Overlay' }
592                 );
593                 //data.stash_retrieve();
594                 if (fancy_prompt_data.fancy_status == 'incomplete') { alert('Overlay Aborted'); return false; }
595                 return true;
596         },
597
598         'spawn_marc_editor_for_overlay' : function(my_marcxml) {
599                 var obj = this;
600                 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
601                 if (!data.marked_record) {
602                         alert('Please mark a record for overlay from within the catalog and try this again.');
603                         return;
604                 }
605
606                 xulG.new_tab(
607                         xulG.url_prefix(urls.XUL_MARC_EDIT), 
608                         { 'tab_name' : 'MARC Editor' }, 
609                         { 
610                                 'record' : { 'marc' : my_marcxml },
611                                 'save' : {
612                                         'label' : 'Overlay Record',
613                                         'func' : function (new_marcxml) {
614                                                 try {
615                                                         if (! obj.confirm_overlay( [ data.marked_record ] ) ) { return; }
616                                                         var r = obj.network.simple_request('MARC_XML_RECORD_REPLACE', [ ses(), data.marked_record, new_marcxml, obj.current_service ]);
617                                                         if (typeof r.ilsevent != 'undefined') {
618                                                                 switch(r.ilsevent) {
619                                                                         case 1704 /* TCN_EXISTS */ :
620                                                                                 var msg = 'A record with TCN ' + r.payload.tcn + ' already exists.\nFIXME: add record summary here';
621                                                                                 var title = 'Import Collision';
622                                                                                 var btn1 = typeof r.payload.new_tcn == 'undefined' ? null : 'Overlay with alternate TCN ' + r.payload.new_tcn;
623                                                                                 if (btn1) {
624                                                                                         var robj = obj.network.simple_request(
625                                                                                                 'PERM_CHECK',[
626                                                                                                         ses(),
627                                                                                                         data.list.au[0].id(),
628                                                                                                         data.list.au[0].ws_ou(),
629                                                                                                         [ 'ALLOW_ALT_TCN' ]
630                                                                                                 ]
631                                                                                         );
632                                                                                         if (typeof robj.ilsevent != 'undefined') {
633                                                                                                 obj.error.standard_unexpected_error_alert('check permission',E);
634                                                                                         }
635                                                                                         if (robj.length != 0) btn1 = null;
636                                                                                 }
637                                                                                 var btn2 = 'Cancel Import';
638                                                                                 var p = obj.error.yns_alert(msg,title,btn1,btn2,null,'Check here to confirm this action');
639                                                                                 obj.error.sdump('D_ERROR','option ' + p + 'chosen');
640                                                                                 switch(p) {
641                                                                                         case 0:
642                                                                                                 var r2 = obj.network.request(
643                                                                                                         api.MARC_XML_RECORD_REPLACE.app,
644                                                                                                         api.MARC_XML_RECORD_REPLACE.method + '.override',
645                                                                                                         [ ses(), data.marked_record, new_marcxml, obj.current_service ]
646                                                                                                 );
647                                                                                                 if (typeof r2.ilsevent != 'undefined') {
648                                                                                                         throw(r2);
649                                                                                                 } else {
650                                                                                                         alert('Record successfully overlayed with alternate TCN.');
651                                                                                                         obj.replace_tab_with_opac(r2.id());
652                                                                                                 }
653                                                                                         break;
654                                                                                         case 1:
655                                                                                         default:
656                                                                                                 alert('Record overlay cancelled');
657                                                                                         break;
658                                                                                 }
659                                                                         break;
660                                                                         default:
661                                                                                 throw(r);
662                                                                         break;
663                                                                 }
664                                                         } else {
665                                                                 alert('Record successfully overlayed.');
666                                                                 obj.replace_tab_with_opac(r.id());
667                                                         }
668                                                 } catch(E) {
669                                                         obj.error.standard_unexpected_error_alert('Record not likely overlayed.',E);
670                                                 }
671                                         }
672                                 }
673                         } 
674                 );
675         },
676
677
678         'load_creds' : function() {
679                 var obj = this;
680                 try {
681                         obj.creds = { 'version' : g.save_version, 'services' : {} };
682                         /*
683                                 {
684                                         'version' : xx,
685                                         'default_service' : xx,
686                                         'services' : {
687
688                                                 'xx' : {
689                                                         'username' : xx,
690                                                         'password' : xx,
691                                                         'default_attr' : xx,
692                                                 },
693
694                                                 'xx' : {
695                                                         'username' : xx,
696                                                         'password' : xx,
697                                                         'default_attr' : xx,
698                                                 },
699                                         },
700                                 }
701                         */
702                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
703                         JSAN.use('util.file'); var file = new util.file('z3950_store');
704                         if (file._file.exists()) {
705                                 var creds = file.get_object(); file.close();
706                                 if (typeof creds.version != 'undefined') {
707                                         if (creds.version >= obj.creds_version) {
708                                                 obj.creds = creds;
709                                         }
710                                 }
711                         }
712                 } catch(E) {
713                         obj.error.standard_unexpected_error_alert('Error retrieving stored z39.50 credentials',E);
714                 }
715         },
716
717         'save_creds' : function () {
718                 try {
719                         var obj = this;
720                         obj.creds.default_service = obj.controller.view.service_menu.value;
721                         if (typeof obj.creds.services[ obj.creds.default_service ] == 'undefined') {
722                                 obj.creds.services[ obj.creds.default_service ] = {}
723                         }
724                         obj.creds.services[obj.creds.default_service].username = document.getElementById('username').value;
725                         obj.creds.services[obj.creds.default_service].password = document.getElementById('password').value;
726                         if (obj.default_attr) {
727                                 obj.creds.services[obj.creds.default_service].default_attr = obj.default_attr;
728                         }
729                         obj.creds.version = obj.creds_version;
730                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
731                         JSAN.use('util.file'); var file = new util.file('z3950_store');
732                         file.set_object(obj.creds);
733                         file.close();
734                 } catch(E) {
735                         obj.error.standard_unexpected_error_alert('Problem storing z39.50 credentials.',E);
736                 }
737         },
738
739         'handle_enter' : function(ev) {
740                 var obj = this;
741                 if (ev.target.tagName != 'textbox') return;
742                 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* enter on a mac */) setTimeout( function() { obj.initial_search(); }, 0);
743         },
744 }
745
746 dump('exiting cat.z3950.js\n');