]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/cat/z3950.js
focus tweaks
[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         'init' : function( params ) {
19
20                 try {
21                         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
22                         JSAN.use('util.widgets');
23
24                         var obj = this;
25
26                         obj.load_creds();
27
28                         JSAN.use('circ.util');
29                         var columns = circ.util.columns(
30                                 {
31                                         'tcn' : { 'hidden' : false },
32                                         'isbn' : { 'hidden' : false },
33                                         'title' : { 'hidden' : false, 'flex' : '1' },
34                                         'author' : { 'hidden' : false },
35                                         'edition' : { 'hidden' : false },
36                                         'pubdate' : { 'hidden' : false },
37                                         'publisher' : { 'hidden' : false },
38                                 }
39                         );
40
41                         JSAN.use('util.list'); obj.list = new util.list('results');
42                         obj.list.init(
43                                 {
44                                         'columns' : columns,
45                                         'map_row_to_column' : circ.util.std_map_row_to_column(),
46                                         'on_select' : function(ev) {
47                                                 try {
48                                                         JSAN.use('util.functional');
49                                                         var sel = obj.list.retrieve_selection();
50                                                         var list = util.functional.map_list(
51                                                                 sel,
52                                                                 function(o) { return o.getAttribute('retrieve_id'); }
53                                                         );
54                                                         obj.error.sdump('D_TRACE','cat/z3950: selection list = ' + js2JSON(list) );
55                                                         obj.controller.view.marc_import.disabled = false;
56                                                         obj.controller.view.marc_import.setAttribute('retrieve_id',list[0]);
57                                                         obj.controller.view.marc_view.disabled = false;
58                                                         obj.controller.view.marc_view.setAttribute('retrieve_id',list[0]);
59                                                 } catch(E) {
60                                                         obj.error.standard_unexpected_error_alert('Failure during list construction.',E);
61                                                 }
62                                         },
63                                 }
64                         );
65
66                         JSAN.use('util.controller'); obj.controller = new util.controller();
67                         obj.controller.init(
68                                 {
69                                         control_map : {
70                                                 'cmd_broken' : [
71                                                         ['command'],
72                                                         function() { alert('Not Yet Implemented'); }
73                                                 ],
74                                                 'result_message' : [['render'],function(e){return function(){};}],
75                                                 'clear' : [
76                                                         ['command'],
77                                                         function() {
78                                                                 obj.clear();
79                                                         }
80                                                 ],
81                                                 'save_creds' : [
82                                                         ['command'],
83                                                         function() {
84                                                                 obj.save_creds();
85                                                         }
86                                                 ],
87                                                 'marc_view' : [
88                                                         ['command'],
89                                                         function(ev) {
90                                                                 try {
91                                                                         var n = obj.controller.view.marc_view;
92                                                                         if (n.getAttribute('toggle') == '1') {
93                                                                                 document.getElementById('deck').selectedIndex = 0;
94                                                                                 n.setAttribute('toggle','0');
95                                                                                 n.setAttribute('label','MARC View');
96                                                                                 document.getElementById('results').focus();
97                                                                         } else {
98                                                                                 document.getElementById('deck').selectedIndex = 1;
99                                                                                 n.setAttribute('toggle','1');
100                                                                                 n.setAttribute('label','Results View');
101                                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
102                                                                                 var f = document.getElementById('marc_frame').contentWindow;
103                                                                                 f.xulG = { 'marcxml' : obj.results.records[ n.getAttribute('retrieve_id') ].marcxml };
104                                                                                 f.my_init();
105                                                                                 f.document.body.firstChild.focus();
106                                                                         }
107                                                                 } catch(E) {
108                                                                         alert(E);
109                                                                 }
110                                                         },
111                                                 ],
112                                                 'marc_import' : [
113                                                         ['command'],
114                                                         function() {
115                                                                 obj.spawn_marc_editor(
116                                                                         obj.results.records[
117                                                                                 obj.controller.view.marc_import.getAttribute('retrieve_id')
118                                                                         ].marcxml
119                                                                 );
120                                                         },
121                                                 ],
122                                                 'search' : [
123                                                         ['command'],
124                                                         function() {
125                                                                 obj.initial_search();
126                                                         },
127                                                 ],
128                                                 'page_next' : [
129                                                         ['command'],
130                                                         function() {
131                                                                 obj.page_next();
132                                                         },
133                                                 ],
134                                                 'raw_search' : [
135                                                         ['command'],
136                                                         function() {
137                                                                 var raw = window.prompt('WARNING: This is not a simple keyword search.  Enter raw z39.50 PQN search string: ','','Raw Z39.50 PQN Search');
138                                                                 if (raw) obj.initial_raw_search(raw);
139                                                         },
140                                                 ],
141                                                 'menu_placeholder' : [
142                                                         ['render'],
143                                                         function(e) {
144                                                                 return function() {
145                                                                         try {
146
147                                                                                 function handle_switch(node) {
148                                                                                         var service = obj.controller.view.service_menu.value;
149                                                                                         var nl = document.getElementsByAttribute('mytype','search_class');
150                                                                                         for (var i = 0; i < nl.length; i++) { nl[i].disabled = true; }
151                                                                                         for (var i in obj.services[service].attrs) {
152                                                                                                 var x = document.getElementById(i + '_input');
153                                                                                                 if (x) {
154                                                                                                         x.disabled = false;
155                                                                                                 } else {
156                                                                                                         var rows = document.getElementById('query_inputs');
157                                                                                                         var row = document.createElement('row'); rows.appendChild(row);
158                                                                                                         var label = document.createElement('label');
159                                                                                                         label.setAttribute('control',i+'_input');
160                                                                                                         label.setAttribute('search_class',i);
161                                                                                                         label.setAttribute('style','-moz-user-focus: ignore');
162                                                                                                         if (entities['staff.z39_50.search_class.'+i]) {
163                                                                                                                 label.setAttribute('value',entities['staff.z39_50.search_class.'+i]);
164                                                                                                         } else {
165                                                                                                                 label.setAttribute('value',i);
166                                                                                                         }
167                                                                                                         row.appendChild(label);
168                                                                                                         label.addEventListener('click',function(ev){
169                                                                                                                         var a = ev.target.getAttribute('search_class');
170                                                                                                                         if (a) obj.default_attr = a;
171                                                                                                                 },false
172                                                                                                         );
173                                                                                                         var tb = document.createElement('textbox');
174                                                                                                         tb.setAttribute('id',i+'_input');
175                                                                                                         tb.setAttribute('mytype','search_class');
176                                                                                                         tb.setAttribute('search_class',i);
177                                                                                                         row.appendChild(tb);
178                                                                                                         tb.addEventListener('keypress',obj.handle_enter,false);
179                                                                                                 }
180                                                                                         }
181                                                                                         if (obj.creds.services[ service ]) {
182                                                                                                 document.getElementById('username').setAttribute('value',
183                                                                                                         obj.creds.services[service].username
184                                                                                                 );
185                                                                                                 document.getElementById('password').setAttribute('value',
186                                                                                                         obj.creds.services[service].password
187                                                                                                 );
188                                                                                                 obj.focus(service);
189                                                                                         } else {
190                                                                                                 document.getElementById('username').focus();
191                                                                                         }
192                                                                                 }
193
194                                                                                 var robj = obj.network.simple_request(
195                                                                                         'RETRIEVE_Z3950_SERVICES',
196                                                                                         [ ses() ]
197                                                                                 );
198                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
199                                                                                 obj.services = robj;
200                                                                                 var list = [];
201                                                                                 for (var i in robj) {
202                                                                                         list.push(
203                                                                                                 [
204                                                                                                         i + ' : ' + robj[i].db + '@' + robj[i].host + ':' + robj[i].port,
205                                                                                                         i
206                                                                                                 ]
207                                                                                         );
208                                                                                 }
209                                                                                 util.widgets.remove_children(e);
210                                                                                 var ml = util.widgets.make_menulist( list );
211                                                                                 ml.setAttribute('flex','1');
212                                                                                 e.appendChild(ml);
213                                                                                 ml.addEventListener(
214                                                                                         'command',
215                                                                                         function(ev) { handle_switch(ev.target); },
216                                                                                         false
217                                                                                 );
218                                                                                 obj.controller.view.service_menu = ml;
219                                                                                 setTimeout(
220                                                                                         function() { 
221                                                                                                 if (obj.creds.default_service) ml.value = obj.creds.default_service;
222                                                                                                 handle_switch(ml); 
223                                                                                         },0
224                                                                                 );
225                                                                         } catch(E) {
226                                                                                 alert(E);
227                                                                                 obj.error.standard_unexpected_error_alert('Z39.50 services not likely retrieved.',E);
228                                                                         }
229                                                                 }
230                                                         }
231                                                 ],
232                                         }
233                                 }
234                         );
235
236                         obj.controller.render();
237
238                         obj.controller.view.username = document.getElementById('username');
239                         obj.controller.view.password = document.getElementById('password');
240
241                 } catch(E) {
242                         this.error.sdump('D_ERROR','cat.z3950.init: ' + E + '\n');
243                 }
244         },
245
246         'focus' : function(service) {
247                 var obj = this;
248                 var x = obj.creds.services[service].default_attr;
249                 if (x) {
250                         document.getElementById(x+'_input').focus();
251                 } else {
252                         var y;
253                         for (var i in obj.services[service].attr) { y = i; }
254                         document.getElementById(y+'_input').focus();
255                 }
256         },
257
258         'clear' : function() {
259                 var obj = this;
260                 var nl = document.getElementsByAttribute('mytype','search_class');
261                 for (var i = 0; i < nl.length; i++) { nl[i].value = ''; nl[i].setAttribute('value',''); }
262                 obj.focus(obj.controller.view.service_menu.value);
263         },
264
265         'search_params' : {},
266
267         'initial_search' : function() {
268                 try {
269                         var obj = this;
270                         JSAN.use('util.widgets');
271                         util.widgets.remove_children( obj.controller.view.result_message );
272                         var x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
273                         x.appendChild( document.createTextNode( 'Searching...' ));
274                         obj.search_params = {}; obj.list.clear();
275                         obj.controller.view.page_next.disabled = true;
276
277                         obj.search_params.service = obj.controller.view.service_menu.value;
278                         obj.search_params.username = obj.controller.view.username.value;
279                         obj.search_params.password = obj.controller.view.password.value;
280                         obj.search_params.limit = 10;
281                         obj.search_params.offset = 0;
282
283                         obj.search_params.search = {};
284                         var nl = document.getElementsByAttribute('mytype','search_class');
285                         var count = 0;
286                         for (var i = 0; i < nl.length; i++) {
287                                 if (nl[i].disabled) continue;
288                                 if (nl[i].value == '') continue;
289                                 count++;
290                                 obj.search_params.search[ nl[i].getAttribute('search_class') ] = nl[i].value;
291                         }
292                         if (count>0) {
293                                 obj.search();
294                         } else {
295                                 util.widgets.remove_children( obj.controller.view.result_message );
296                         }
297                 } catch(E) {
298                         this.error.standard_unexpected_error_alert('Failure during initial search.',E);
299                 }
300         },
301
302         'initial_raw_search' : function(raw) {
303                 try {
304                         var obj = this;
305                         JSAN.use('util.widgets');
306                         util.widgets.remove_children( obj.controller.view.result_message );
307                         var x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
308                         x.appendChild( document.createTextNode( 'Searching...' ) );
309                         obj.search_params = {}; obj.result_count = 0; obj.list.clear();
310                         obj.controller.view.page_next.disabled = true;
311
312                         obj.search_params.service = obj.controller.view.service_menu.value;
313                         obj.search_params.username = obj.controller.view.username.value;
314                         obj.search_params.password = obj.controller.view.password.value;
315                         obj.search_params.limit = 10;
316                         obj.search_params.offset = 0;
317
318                         obj.search_params.query = raw;
319
320                         obj.search();
321                 } catch(E) {
322                         this.error.standard_unexpected_error_alert('Failure during initial raw search.',E);
323                 }
324         },
325
326         'page_next' : function() {
327                 try {
328                         var obj = this;
329                         JSAN.use('util.widgets');
330                         util.widgets.remove_children( obj.controller.view.result_message );
331                         var x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
332                         x.appendChild( document.createTextNode( 'Retrieving more results...' ));
333                         obj.search_params.offset += obj.search_params.limit;
334                         obj.search();
335                 } catch(E) {
336                         this.error.standard_unexpected_error_alert('Failure during subsequent search.',E);
337                 }
338         },
339
340         'search' : function() {
341                 try {
342                         var obj = this;
343                         var method;
344                         if (typeof obj.search_params.query == 'undefined') {
345                                 method = 'FM_BLOB_RETRIEVE_VIA_Z3950_SEARCH';
346                         } else {
347                                 method = 'FM_BLOB_RETRIEVE_VIA_Z3950_RAW_SEARCH';
348                         }
349                         obj.network.simple_request(
350                                 method,
351                                 [ ses(), obj.search_params ],
352                                 function(req) {
353                                         obj.handle_results(req.getResultObject())
354                                 }
355                         );
356                         document.getElementById('deck').selectedIndex = 0;
357                 } catch(E) {
358                         this.error.standard_unexpected_error_alert('Failure during actual search.',E);
359                 }
360         },
361
362         'handle_results' : function(results) {
363                 var obj = this;
364                 try {
365                         JSAN.use('util.widgets');
366                         util.widgets.remove_children( obj.controller.view.result_message ); var x;
367                         if (results == null) {
368                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
369                                 x.appendChild( document.createTextNode( 'Server Error: request returned null' ));
370                                 return;
371                         }
372                         if (typeof results.ilsevent != 'undefined') {
373                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
374                                 x.appendChild( document.createTextNode( 'Server Error: ' + results.textcode + ' : ' + results.desc ));
375                                 return;
376                         }
377                         if (results.query) {
378                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
379                                 x.appendChild( document.createTextNode( 'Raw query: ' + results.query ));
380                         }
381                         if (results.count) {
382                                 if (results.records) {
383                                         x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
384                                         x.appendChild(
385                                                 document.createTextNode( 'Showing ' + (obj.search_params.offset + results.records.length) + ' of ' + results.count)
386                                         );
387                                 }
388                                 if (obj.search_params.offset + obj.search_params.limit <= results.count) {
389                                         obj.controller.view.page_next.disabled = false;
390                                 }
391                         } else {
392                                         x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
393                                         x.appendChild(
394                                                 document.createTextNode( results.count + ' records found')
395                                         );
396                         }
397                         if (results.records) {
398                                 obj.results = results;
399                                 obj.controller.view.marc_import.disabled = true;
400                                 var x = obj.controller.view.marc_view;
401                                 if (x.getAttribute('toggle') == '0') x.disabled = true;
402                                 for (var i = 0; i < obj.results.records.length; i++) {
403                                         obj.list.append(
404                                                 {
405                                                         'retrieve_id' : i,
406                                                         'row' : {
407                                                                 'my' : {
408                                                                         'mvr' : function(a){return a;}(obj.results.records[i].mvr),
409                                                                 }
410                                                         }
411                                                 }
412                                         );
413                                 }
414                         } else {
415                                 x = document.createElement('description'); obj.controller.view.result_message.appendChild(x);
416                                 x.appendChild(
417                                         document.createTextNode( 'Error retrieving results.')
418                                 );
419                         }
420                 } catch(E) {
421                         this.error.standard_unexpected_error_alert('Failure during search result handling.',E);
422                 }
423         },
424
425         'replace_tab_with_opac' : function(doc_id) {
426                 var opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + doc_id;
427                 var content_params = { 
428                         'session' : ses(),
429                         'authtime' : ses('authtime'),
430                         'opac_url' : opac_url,
431                 };
432                 xulG.set_tab(
433                         xulG.url_prefix(urls.XUL_OPAC_WRAPPER), 
434                         {'tab_name':'Retrieving title...'}, 
435                         content_params
436                 );
437         },
438
439         'spawn_marc_editor' : function(my_marcxml) {
440                 var obj = this;
441                 xulG.new_tab(
442                         xulG.url_prefix(urls.XUL_MARC_EDIT), 
443                         { 'tab_name' : 'MARC Editor' }, 
444                         { 
445                                 'record' : { 'marc' : my_marcxml },
446                                 'save' : {
447                                         'label' : 'Import Record',
448                                         'func' : function (new_marcxml) {
449                                                 try {
450                                                         var r = obj.network.simple_request('MARC_XML_RECORD_IMPORT', [ ses(), new_marcxml ]);
451                                                         if (typeof r.ilsevent != 'undefined') {
452                                                                 switch(r.ilsevent) {
453                                                                         case 1704 /* TCN_EXISTS */ :
454                                                                                 var msg = 'A record with with TCN ' + r.payload.tcn + ' already exists.\nFIXME: add record summary here';
455                                                                                 var title = 'Import Collision';
456                                                                                 var btn1 = 'Overlay';
457                                                                                 var btn2 = typeof r.payload.new_tcn == 'undefined' ? null : 'Import with alternate TCN ' + r.payload.new_tcn;
458                                                                                 var btn3 = 'Cancel Import';
459                                                                                 var p = obj.error.yns_alert(msg,title,btn1,btn2,btn3,'Check here to confirm this action');
460                                                                                 obj.error.sdump('D_ERROR','option ' + p + 'chosen');
461                                                                                 switch(p) {
462                                                                                         case 0:
463                                                                                                 var r3 = obj.network.simple_request('MARC_XML_RECORD_UPDATE', [ ses(), r.payload.dup_record, new_marcxml ]);
464                                                                                                 if (typeof r3.ilsevent != 'undefined') {
465                                                                                                         throw(r3);
466                                                                                                 } else {
467                                                                                                         alert('Record successfully overlayed.');
468                                                                                                         obj.replace_tab_with_opac(r3.id());
469                                                                                                 }
470                                                                                         break;
471                                                                                         case 1:
472                                                                                                 var r2 = obj.network.request(
473                                                                                                         api.MARC_XML_RECORD_IMPORT.app,
474                                                                                                         api.MARC_XML_RECORD_IMPORT.method + '.override',
475                                                                                                         [ ses(), new_marcxml ]
476                                                                                                 );
477                                                                                                 if (typeof r2.ilsevent != 'undefined') {
478                                                                                                         throw(r2);
479                                                                                                 } else {
480                                                                                                         alert('Record successfully imported with alternate TCN.');
481                                                                                                         obj.replace_tab_with_opac(r2.id());
482                                                                                                 }
483                                                                                         break;
484                                                                                         case 2:
485                                                                                         default:
486                                                                                                 alert('Record import cancelled');
487                                                                                         break;
488                                                                                 }
489                                                                         break;
490                                                                         default:
491                                                                                 throw(r);
492                                                                         break;
493                                                                 }
494                                                         } else {
495                                                                 alert('Record successfully imported.');
496                                                                 obj.replace_tab_with_opac(r.id());
497                                                         }
498                                                 } catch(E) {
499                                                         obj.error.standard_unexpected_error_alert('Record not likely imported.',E);
500                                                 }
501                                         }
502                                 }
503                         } 
504                 );
505         },
506
507         'load_creds' : function() {
508                 var obj = this;
509                 try {
510                         obj.creds = { 'version' : g.save_version, 'services' : {} };
511                         /*
512                                 {
513                                         'version' : xx,
514                                         'default_service' : xx,
515                                         'services' : {
516
517                                                 'xx' : {
518                                                         'username' : xx,
519                                                         'password' : xx,
520                                                         'default_attr' : xx,
521                                                 },
522
523                                                 'xx' : {
524                                                         'username' : xx,
525                                                         'password' : xx,
526                                                         'default_attr' : xx,
527                                                 },
528                                         },
529                                 }
530                         */
531                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
532                         JSAN.use('util.file'); var file = new util.file('z3950_store');
533                         if (file._file.exists()) {
534                                 var creds = file.get_object(); file.close();
535                                 if (typeof creds.version != 'undefined') {
536                                         if (creds.version >= obj.creds_version) {
537                                                 obj.creds = creds;
538                                         }
539                                 }
540                         }
541                 } catch(E) {
542                         obj.error.standard_unexpected_error_dialog('Error retrieving stored z39.50 credentials',E);
543                 }
544         },
545
546         'save_creds' : function () {
547                 try {
548                         var obj = this;
549                         obj.creds.default_service = obj.controller.view.service_menu.value;
550                         if (typeof obj.creds.services[ obj.creds.default_service ] == 'undefined') {
551                                 obj.creds.services[ obj.creds.default_service ] = {}
552                         }
553                         obj.creds.services[obj.creds.default_service].username = document.getElementById('username').value;
554                         obj.creds.services[obj.creds.default_service].password = document.getElementById('password').value;
555                         if (obj.default_attr) {
556                                 obj.creds.services[obj.creds.default_service].default_attr = obj.default_attr;
557                         }
558                         obj.creds.version = obj.creds_version;
559                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
560                         JSAN.use('util.file'); var file = new util.file('z3950_store');
561                         file.set_object(obj.creds);
562                         file.close();
563                 } catch(E) {
564                         obj.error.standard_unexpected_error_alert('Problem storing z39.50 credentials.',E);
565                 }
566         },
567
568         'handle_enter' : function(ev) {
569                 var obj = this;
570                 if (ev.target.tagName != 'textbox') return;
571                 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* enter on a mac */) setTimeout( function() { obj.initial_search(); }, 0);
572         },
573 }
574
575 dump('exiting cat.z3950.js\n');