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