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