Line 0
Link Here
|
|
|
1 |
<script src="/intranet-tmpl/lib/codemirror/codemirror-compressed.js"></script> |
2 |
<script src="/intranet-tmpl/lib/filesaver.js"></script> |
3 |
<script src="/intranet-tmpl/lib/koha/cateditor/marc-mode.js"></script> |
4 |
<script src="/intranet-tmpl/lib/require.js"></script> |
5 |
<script> |
6 |
require.config( { |
7 |
baseUrl: '/intranet-tmpl/lib/koha/cateditor/', |
8 |
config: { |
9 |
resources: { |
10 |
themelang: '[% themelang %]', |
11 |
}, |
12 |
}, |
13 |
waitSeconds: 30, |
14 |
} ); |
15 |
</script> |
16 |
|
17 |
[% IF marcflavour == 'MARC21' %] |
18 |
[% PROCESS 'cateditor-widgets-marc21.inc' %] |
19 |
[% ELSE %] |
20 |
<script>var editorWidgets = {};</script> |
21 |
[% END %] |
22 |
|
23 |
<script> |
24 |
require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'preferences', 'resources', 'text-marc', 'widget' ], function( KohaBackend, Search, Macros, MARCEditor, MARC, Preferences, Resources, TextMARC, Widget ) { |
25 |
var z3950Servers = { |
26 |
'koha:biblioserver': { |
27 |
name: _("Local catalog"), |
28 |
recordtype: 'biblio', |
29 |
checked: false, |
30 |
}, |
31 |
[%- FOREACH server = z3950_servers -%] |
32 |
[% server.id %]: { |
33 |
name: '[% server.servername %]', |
34 |
recordtype: '[% server.recordtype %]', |
35 |
checked: [% server.checked ? 'true' : 'false' %], |
36 |
}, |
37 |
[%- END -%] |
38 |
}; |
39 |
|
40 |
// The columns that should show up in a search, in order, and keyed by the corresponding <metadata> tag in the XSL and Pazpar2 config |
41 |
var z3950Labels = [ |
42 |
[ "local_number", _("Local number") ], |
43 |
[ "title", _("Title") ], |
44 |
[ "series", _("Series title") ], |
45 |
[ "author", _("Author") ], |
46 |
[ "lccn", _("LCCN") ], |
47 |
[ "isbn", _("ISBN") ], |
48 |
[ "issn", _("ISSN") ], |
49 |
[ "medium", _("Medium") ], |
50 |
[ "edition", _("Edition") ], |
51 |
[ "notes", _("Notes") ], |
52 |
]; |
53 |
|
54 |
var state = { |
55 |
backend: '', |
56 |
saveBackend: 'catalog', |
57 |
recordID: undefined |
58 |
}; |
59 |
|
60 |
var editor; |
61 |
var macroEditor; |
62 |
|
63 |
function makeAuthorisedValueWidgets( frameworkCode ) { |
64 |
$.each( KohaBackend.GetAllTagsInfo( frameworkCode ), function( tag, tagInfo ) { |
65 |
$.each( tagInfo.subfields, function( subfield, subfieldInfo ) { |
66 |
if ( !subfieldInfo.authorised_value ) return; |
67 |
var authvals = KohaBackend.GetAuthorisedValues( subfieldInfo.authorised_value ); |
68 |
if ( !authvals ) return; |
69 |
|
70 |
var defaultvalue = subfield.defaultvalue || authvals[0].value; |
71 |
|
72 |
Widget.Register( tag + subfield, { |
73 |
init: function() { |
74 |
var $result = $( '<span class="subfield-widget"></span>' ); |
75 |
|
76 |
return $result[0]; |
77 |
}, |
78 |
postCreate: function() { |
79 |
this.setText( defaultvalue ); |
80 |
|
81 |
$( '<select></select>' ).appendTo( this.node ); |
82 |
var $node = $( this.node ).find( 'select' ); |
83 |
$.each( authvals, function( undef, authval ) { |
84 |
$node.append( '<option value="' + authval.value + '"' + (authval.value == defaultvalue ? ' selected="selected"' : '') + '>' + authval.lib + '</option>' ); |
85 |
} ); |
86 |
$node.val( this.text ); |
87 |
|
88 |
$node.change( $.proxy( function() { |
89 |
this.setText( $node.val() ); |
90 |
}, this ) ); |
91 |
}, |
92 |
makeTemplate: function() { |
93 |
return defaultvalue; |
94 |
}, |
95 |
} ); |
96 |
} ); |
97 |
} ); |
98 |
} |
99 |
|
100 |
function bindGlobalKeys() { |
101 |
shortcut.add( 'ctrl+s', function(event) { |
102 |
$( '#save-record' ).click(); |
103 |
|
104 |
event.preventDefault(); |
105 |
} ); |
106 |
|
107 |
shortcut.add( 'alt+ctrl+k', function(event) { |
108 |
if ( Search.IsAvailable() ) $( '#search-by-keywords' ).focus(); |
109 |
|
110 |
return false; |
111 |
} ); |
112 |
|
113 |
shortcut.add( 'alt+ctrl+a', function(event) { |
114 |
if ( Search.IsAvailable() ) $( '#search-by-author' ).focus(); |
115 |
|
116 |
return false; |
117 |
} ); |
118 |
|
119 |
shortcut.add( 'alt+ctrl+i', function(event) { |
120 |
if ( Search.IsAvailable() ) $( '#search-by-isbn' ).focus(); |
121 |
|
122 |
return false; |
123 |
} ); |
124 |
|
125 |
shortcut.add( 'alt+ctrl+t', function(event) { |
126 |
if ( Search.IsAvailable() ) $( '#search-by-title' ).focus(); |
127 |
|
128 |
return false; |
129 |
} ); |
130 |
|
131 |
shortcut.add( 'ctrl+h', function() { |
132 |
var field = editor.getCurrentField(); |
133 |
|
134 |
if ( !field ) return; |
135 |
|
136 |
window.open( getFieldHelpURL( field.tag ) ); |
137 |
} ); |
138 |
|
139 |
$('#quicksearch .search-box').each( function() { |
140 |
shortcut.add( 'enter', $.proxy( function() { |
141 |
var terms = []; |
142 |
|
143 |
$('#quicksearch .search-box').each( function() { |
144 |
if ( !this.value ) return; |
145 |
|
146 |
terms.push( [ $(this).data('qualifier'), this.value ] ); |
147 |
} ); |
148 |
|
149 |
if ( !terms.length ) return; |
150 |
|
151 |
if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) { |
152 |
$("#search-overlay").show(); |
153 |
showResultsBox(); |
154 |
} |
155 |
|
156 |
return false; |
157 |
}, this), { target: this, type: 'keypress' } ); |
158 |
} ); |
159 |
} |
160 |
|
161 |
function getFieldHelpURL( tag ) { |
162 |
[% IF ( marcflavour == 'MARC21' ) %] |
163 |
if ( tag == '000' ) { |
164 |
return "http://www.loc.gov/marc/bibliographic/bdleader.html"; |
165 |
} else if ( tag < '900' ) { |
166 |
return "http://www.loc.gov/marc/bibliographic/bd" + tag + ".html"; |
167 |
} else { |
168 |
return "http://www.loc.gov/marc/bibliographic/bd9xx.html"; |
169 |
} |
170 |
[% ELSIF ( marcflavour == 'UNIMARC' ) %] |
171 |
/* http://archive.ifla.org/VI/3/p1996-1/ is an outdated version of UNIMARC, but |
172 |
seems to be the only version available that can be linked to per tag. More recent |
173 |
versions of the UNIMARC standard are available on the IFLA website only as |
174 |
PDFs! |
175 |
*/ |
176 |
if ( tag == '000' ) { |
177 |
return "http://archive.ifla.org/VI/3/p1996-1/uni.htm"; |
178 |
} else { |
179 |
var first = tag[0]; |
180 |
var url = "http://archive.ifla.org/VI/3/p1996-1/uni" + first + ".htm#"; |
181 |
if ( first == '0' ) url += "b"; |
182 |
if ( first != '9' ) url += field; |
183 |
|
184 |
return url; |
185 |
} |
186 |
[% END %] |
187 |
} |
188 |
|
189 |
// Record loading |
190 |
var backends = { |
191 |
'new': { |
192 |
titleForRecord: _("Editing new record"), |
193 |
get: function( id, callback ) { |
194 |
record = new MARC.Record(); |
195 |
KohaBackend.FillRecord( '', record ); |
196 |
|
197 |
callback( record ); |
198 |
}, |
199 |
}, |
200 |
'new-full': { |
201 |
titleForRecord: _("Editing new full record"), |
202 |
get: function( id, callback ) { |
203 |
record = new MARC.Record(); |
204 |
KohaBackend.FillRecord( '', record, true ); |
205 |
|
206 |
callback( record ); |
207 |
}, |
208 |
}, |
209 |
'catalog': { |
210 |
titleForRecord: _("Editing catalog record #{ID}"), |
211 |
links: [ |
212 |
{ title: _("view"), href: "/cgi-bin/koha/catalogue/detail.pl?biblionumber={ID}" }, |
213 |
{ title: _("edit items"), href: "/cgi-bin/koha/cataloguing/additem.pl?biblionumber={ID}" }, |
214 |
], |
215 |
saveLabel: _("Save to catalog"), |
216 |
get: function( id, callback ) { |
217 |
if ( !id ) return false; |
218 |
|
219 |
KohaBackend.GetRecord( id, callback ); |
220 |
}, |
221 |
save: function( id, record, done ) { |
222 |
function finishCb( data ) { |
223 |
done( { error: data.error, newRecord: data.marcxml && data.marcxml[0], newId: data.biblionumber && [ 'catalog', data.biblionumber ] } ); |
224 |
} |
225 |
|
226 |
if ( id ) { |
227 |
KohaBackend.SaveRecord( id, record, finishCb ); |
228 |
} else { |
229 |
KohaBackend.CreateRecord( record, finishCb ); |
230 |
} |
231 |
} |
232 |
}, |
233 |
'iso2709': { |
234 |
saveLabel: _("Save as ISO2709 (.mrc) file"), |
235 |
save: function( id, record, done ) { |
236 |
saveAs( new Blob( [record.toISO2709()], { 'type': 'application/octet-stream;charset=utf-8' } ), 'record.mrc' ); |
237 |
|
238 |
done( {} ); |
239 |
} |
240 |
}, |
241 |
'marcxml': { |
242 |
saveLabel: _("Save as MARCXML (.xml) file"), |
243 |
save: function( id, record, done ) { |
244 |
saveAs( new Blob( [record.toXML()], { 'type': 'application/octet-stream;charset=utf-8' } ), 'record.xml' ); |
245 |
|
246 |
done( {} ); |
247 |
} |
248 |
}, |
249 |
'search': { |
250 |
titleForRecord: _("Editing search result"), |
251 |
get: function( id, callback ) { |
252 |
if ( !id ) return false; |
253 |
if ( !backends.search.records[ id ] ) { |
254 |
callback( { error: _( "Invalid record" ) } ); |
255 |
return false; |
256 |
} |
257 |
|
258 |
callback( backends.search.records[ id ] ); |
259 |
}, |
260 |
records: {}, |
261 |
}, |
262 |
}; |
263 |
|
264 |
function setSource(parts) { |
265 |
state.backend = parts[0]; |
266 |
state.recordID = parts[1]; |
267 |
state.canSave = backends[ state.backend ].save != null; |
268 |
state.saveBackend = state.canSave ? state.backend : 'catalog'; |
269 |
|
270 |
var backend = backends[state.backend]; |
271 |
|
272 |
document.location.hash = '#' + parts[0] + '/' + parts[1]; |
273 |
|
274 |
$('#title').text( backend.titleForRecord.replace( '{ID}', parts[1] ) ); |
275 |
|
276 |
$.each( backend.links || [], function( i, link ) { |
277 |
$('#title').append(' <a target="_blank" href="' + link.href.replace( '{ID}', parts[1] ) + '">(' + link.title + ')</a>' ); |
278 |
} ); |
279 |
$( 'title', document.head ).html( _("Koha › Cataloging › ") + backend.titleForRecord.replace( '{ID}', parts[1] ) ); |
280 |
$('#save-record span').text( backends[ state.saveBackend ].saveLabel ); |
281 |
} |
282 |
|
283 |
function saveRecord( recid, editor, callback ) { |
284 |
var parts = recid.split('/'); |
285 |
if ( parts.length != 2 ) return false; |
286 |
|
287 |
if ( !backends[ parts[0] ] || !backends[ parts[0] ].save ) return false; |
288 |
|
289 |
editor.removeErrors(); |
290 |
var record = editor.getRecord(); |
291 |
|
292 |
if ( record.errors ) { |
293 |
state.saving = false; |
294 |
callback( { error: 'syntax', errors: record.errors } ); |
295 |
return; |
296 |
} |
297 |
|
298 |
var errors = KohaBackend.ValidateRecord( '', record ); |
299 |
if ( errors.length ) { |
300 |
state.saving = false; |
301 |
callback( { error: 'invalid', errors: errors } ); |
302 |
return; |
303 |
} |
304 |
|
305 |
backends[ parts[0] ].save( parts[1], record, function(data) { |
306 |
state.saving = false; |
307 |
|
308 |
if (data.newRecord) { |
309 |
var record = new MARC.Record(); |
310 |
record.loadMARCXML(data.newRecord); |
311 |
editor.displayRecord( record ); |
312 |
} |
313 |
|
314 |
if (data.newId) { |
315 |
setSource(data.newId); |
316 |
} else { |
317 |
setSource( [ state.backend, state.recordID ] ); |
318 |
} |
319 |
|
320 |
if (callback) callback( data ); |
321 |
} ); |
322 |
} |
323 |
|
324 |
function loadRecord( recid, editor, callback ) { |
325 |
var parts = recid.split('/'); |
326 |
if ( parts.length != 2 ) return false; |
327 |
|
328 |
if ( !backends[ parts[0] ] || !backends[ parts[0] ].get ) return false; |
329 |
|
330 |
backends[ parts[0] ].get( parts[1], function( record ) { |
331 |
if ( !record.error ) { |
332 |
editor.displayRecord( record ); |
333 |
editor.focus(); |
334 |
} |
335 |
|
336 |
if (callback) callback(record); |
337 |
} ); |
338 |
|
339 |
return true; |
340 |
} |
341 |
|
342 |
function openRecord( recid, editor, callback ) { |
343 |
return loadRecord( recid, editor, function ( record ) { |
344 |
setSource( recid.split('/') ); |
345 |
|
346 |
if (callback) callback( record ); |
347 |
} ); |
348 |
} |
349 |
|
350 |
// Search functions |
351 |
function showAdvancedSearch() { |
352 |
$('#advanced-search-servers').empty(); |
353 |
$.each( z3950Servers, function( server_id, server ) { |
354 |
$('#advanced-search-servers').append( '<li data-server-id="' + server_id + '"><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + '</li>' ); |
355 |
} ); |
356 |
$('#advanced-search-ui').modal('show'); |
357 |
} |
358 |
|
359 |
function startAdvancedSearch() { |
360 |
var terms = []; |
361 |
|
362 |
$('#advanced-search-ui .search-box').each( function() { |
363 |
if ( !this.value ) return; |
364 |
|
365 |
terms.push( [ $(this).data('qualifier'), this.value ] ); |
366 |
} ); |
367 |
|
368 |
if ( !terms.length ) return; |
369 |
|
370 |
if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) { |
371 |
$('#advanced-search-ui').modal('hide'); |
372 |
$("#search-overlay").show(); |
373 |
showResultsBox(); |
374 |
} |
375 |
} |
376 |
|
377 |
function showResultsBox(data) { |
378 |
$('#search-top-pages, #search-bottom-pages').find('.pagination').empty(); |
379 |
$('#searchresults thead tr').empty(); |
380 |
$('#searchresults tbody').empty(); |
381 |
$('#search-serversinfo').empty().append('<li>' + _("Loading...") + '</li>'); |
382 |
$('#search-results-ui').modal('show'); |
383 |
} |
384 |
|
385 |
function showSearchSorting( sort_key, sort_direction ) { |
386 |
var $th = $('#searchresults thead tr th[data-sort-label="' + sort_key + '"]'); |
387 |
$th.parent().find( 'th[data-sort-label]' ).attr( 'class', 'sorting' ); |
388 |
|
389 |
if ( sort_direction == 'asc' ) { |
390 |
direction = 'asc'; |
391 |
$th.attr( 'class', 'sorting_asc' ); |
392 |
} else { |
393 |
direction = 'desc'; |
394 |
$th.attr( 'class', 'sorting_desc' ); |
395 |
} |
396 |
} |
397 |
|
398 |
function showSearchResults( editor, data ) { |
399 |
backends.search.records = {}; |
400 |
|
401 |
$('#searchresults thead tr').empty(); |
402 |
$('#searchresults tbody').empty(); |
403 |
$('#search-serversinfo').empty(); |
404 |
|
405 |
$.each( z3950Servers, function( server_id, server ) { |
406 |
var num_fetched = data.num_fetched[server_id]; |
407 |
|
408 |
if ( data.errors[server_id] ) { |
409 |
num_fetched = data.errors[server_id]; |
410 |
} else if ( num_fetched == null ) { |
411 |
num_fetched = '-'; |
412 |
} else if ( num_fetched < data.num_hits[server_id] ) { |
413 |
num_fetched += '+'; |
414 |
} |
415 |
|
416 |
$('#search-serversinfo').append( '<li data-server-id="' + server_id + '"><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + ' (' + num_fetched + ')' + '</li>' ); |
417 |
} ); |
418 |
|
419 |
var seenColumns = {}; |
420 |
|
421 |
$.each( data.hits, function( undef, hit ) { |
422 |
$.each( hit.metadata, function(key) { |
423 |
seenColumns[key] = true; |
424 |
} ); |
425 |
} ); |
426 |
|
427 |
$('#searchresults thead tr').append('<th>' + _("Source") + '</th>'); |
428 |
|
429 |
$.each( z3950Labels, function( undef, label ) { |
430 |
if ( seenColumns[ label[0] ] ) { |
431 |
$('#searchresults thead tr').append( '<th class="sorting" data-sort-label="' + label[0] + '">' + label[1] + '</th>' ); |
432 |
} |
433 |
} ); |
434 |
|
435 |
showSearchSorting( data.sort_key, data.sort_direction ); |
436 |
|
437 |
$('#searchresults thead tr').append('<th>' + _("Tools") + '</th>'); |
438 |
|
439 |
$.each( data.hits, function( undef, hit ) { |
440 |
backends.search.records[ hit.server + ':' + hit.index ] = hit.record; |
441 |
hit.id = 'search/' + hit.server + ':' + hit.index; |
442 |
|
443 |
var result = '<tr>'; |
444 |
result += '<td class="sourcecol">' + z3950Servers[ hit.server ].name + '</td>'; |
445 |
|
446 |
$.each( z3950Labels, function( undef, label ) { |
447 |
if ( !seenColumns[ label[0] ] ) return; |
448 |
|
449 |
if ( hit.metadata[ label[0] ] ) { |
450 |
result += '<td class="infocol">' + hit.metadata[ label[0] ] + '</td>'; |
451 |
} else { |
452 |
result += '<td class="infocol"> </td>'; |
453 |
} |
454 |
} ); |
455 |
|
456 |
result += '<td class="toolscol"><ul><li><a href="#" class="marc-link">' + _("View MARC") + '</a></li>'; |
457 |
result += '<li><a href="#" class="open-link">' + _("Import") + '</a></li>'; |
458 |
if ( state.canSave ) result += '<li><a href="#" class="substitute-link" title="' + _("Replace the current record's contents") + '">' + _("Substitute") + '</a></li>'; |
459 |
result += '</ul></td></tr>'; |
460 |
|
461 |
var $tr = $( result ); |
462 |
$tr.find( '.marc-link' ).click( function() { |
463 |
var $info_columns = $tr.find( '.infocol' ); |
464 |
var $marc_column = $tr.find( '.marccol' ); |
465 |
|
466 |
if ( !$marc_column.length ) { |
467 |
$marc_column = $( '<td class="marccol" colspan="' + $info_columns.length + '"></td>' ).insertAfter( $info_columns.eq(-1) ).hide(); |
468 |
CodeMirror.runMode( TextMARC.RecordToText( hit.record ), 'marc', $marc_column[0] ); |
469 |
} |
470 |
|
471 |
if ( $marc_column.is(':visible') ) { |
472 |
$tr.find('.marc-link').text( _("View MARC") ); |
473 |
$info_columns.show(); |
474 |
$marc_column.hide(); |
475 |
} else { |
476 |
$tr.find('.marc-link').text( _("Hide MARC") ); |
477 |
$marc_column.show(); |
478 |
$info_columns.hide(); |
479 |
} |
480 |
|
481 |
return false; |
482 |
} ); |
483 |
$tr.find( '.open-link' ).click( function() { |
484 |
$( '#search-results-ui' ).modal('hide'); |
485 |
openRecord( hit.id, editor ); |
486 |
|
487 |
return false; |
488 |
} ); |
489 |
$tr.find( '.substitute-link' ).click( function() { |
490 |
$( '#search-results-ui' ).modal('hide'); |
491 |
loadRecord( hit.id, editor ); |
492 |
|
493 |
return false; |
494 |
} ); |
495 |
$('#searchresults tbody').append( $tr ); |
496 |
} ); |
497 |
|
498 |
var pages = []; |
499 |
var cur_page = data.offset / data.page_size; |
500 |
var max_page = Math.ceil( data.total_fetched / data.page_size ) - 1; |
501 |
|
502 |
if ( cur_page != 0 ) { |
503 |
pages.push( '<li><a class="search-nav" href="#" data-offset="' + (data.offset - data.page_size) + '">« ' + _("Previous") + '</a></li>' ); |
504 |
} |
505 |
|
506 |
for ( var page = Math.max( 0, cur_page - 9 ); page <= Math.min( max_page, cur_page + 9 ); page++ ) { |
507 |
if ( page == cur_page ) { |
508 |
pages.push( ' <li class="active"><a href="#">' + ( page + 1 ) + '</a></li>' ); |
509 |
} else { |
510 |
pages.push( ' <li><a class="search-nav" href="#" data-offset="' + ( page * data.page_size ) + '">' + ( page + 1 ) + '</a></li>' ); |
511 |
} |
512 |
} |
513 |
|
514 |
if ( cur_page < max_page ) { |
515 |
pages.push( ' <li><a class="search-nav" href="#" data-offset="' + (data.offset + data.page_size) + '">' + _("Next") + ' »</a></li>' ); |
516 |
} |
517 |
|
518 |
if ( pages.length > 1 ) $( '#search-top-pages, #search-bottom-pages' ).find( '.pagination' ).html( '<ul>' + pages.join( '' ) + '</ul>'); |
519 |
|
520 |
var $overlay = $('#search-overlay'); |
521 |
$overlay.find('span').text(_("Loading")); |
522 |
$overlay.find('.bar').css( { display: 'block', width: 100 * ( 1 - data.activeclients / Search.includedServers.length ) + '%' } ); |
523 |
|
524 |
if ( data.activeclients ) { |
525 |
$overlay.find('.bar').css( { display: 'block', width: 100 * ( 1 - data.activeclients / Search.includedServers.length ) + '%' } ); |
526 |
$overlay.show(); |
527 |
} else { |
528 |
$overlay.find('.bar').css( { display: 'block', width: '100%' } ); |
529 |
$overlay.fadeOut(); |
530 |
} |
531 |
} |
532 |
|
533 |
function invalidateSearchResults() { |
534 |
var $overlay = $('#search-overlay'); |
535 |
$overlay.find('span').text(_("Search expired, please try again")); |
536 |
$overlay.find('.bar').css( { display: 'none' } ); |
537 |
$overlay.show(); |
538 |
} |
539 |
|
540 |
function handleSearchError(error) { |
541 |
if (error.code == 1) { |
542 |
invalidateSearchResults(); |
543 |
Search.Reconnect(); |
544 |
} else { |
545 |
humanMsg.displayMsg( _("<h3>Internal search error</h3>") + '<p>' + error + '</p>' + _("<p>Please <b>refresh</b> the page and try again."), { className: 'humanError' } ); |
546 |
} |
547 |
} |
548 |
|
549 |
function handleSearchInitError(error) { |
550 |
$('#quicksearch-overlay').fadeIn().find('p').text(error); |
551 |
} |
552 |
|
553 |
// Preference functions |
554 |
function showPreference( pref ) { |
555 |
var value = Preferences.user[pref]; |
556 |
|
557 |
switch (pref) { |
558 |
case 'fieldWidgets': |
559 |
$( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") ); |
560 |
break; |
561 |
case 'font': |
562 |
$( '#editor .CodeMirror' ).css( { fontFamily: value } ); |
563 |
editor.refresh(); |
564 |
break; |
565 |
case 'fontSize': |
566 |
$( '#editor .CodeMirror' ).css( { fontSize: value } ); |
567 |
editor.refresh(); |
568 |
break; |
569 |
case 'macros': |
570 |
showSavedMacros(); |
571 |
break; |
572 |
case 'selected_search_targets': |
573 |
$.each( z3950Servers, function( server_id, server ) { |
574 |
var saved_val = Preferences.user.selected_search_targets[server_id]; |
575 |
|
576 |
if ( saved_val != null ) server.checked = saved_val; |
577 |
} ); |
578 |
break; |
579 |
} |
580 |
} |
581 |
|
582 |
function bindPreference( editor, pref ) { |
583 |
function _addHandler( sel, event, handler ) { |
584 |
$( sel ).on( event, function (e) { |
585 |
e.preventDefault(); |
586 |
handler( e, Preferences.user[pref] ); |
587 |
Preferences.Save( [% USER_INFO.0.borrowernumber %] ); |
588 |
showPreference(pref); |
589 |
} ); |
590 |
} |
591 |
|
592 |
switch (pref) { |
593 |
case 'fieldWidgets': |
594 |
_addHandler( '#set-field-widgets', 'click', function( e, oldValue ) { |
595 |
editor.setUseWidgets( Preferences.user.fieldWidgets = !Preferences.user.fieldWidgets ); |
596 |
} ); |
597 |
break; |
598 |
case 'font': |
599 |
_addHandler( '#prefs-menu .set-font', 'click', function( e, oldValue ) { |
600 |
Preferences.user.font = $( e.target ).css( 'font-family' ); |
601 |
} ); |
602 |
break; |
603 |
case 'fontSize': |
604 |
_addHandler( '#prefs-menu .set-fontSize', 'click', function( e, oldValue ) { |
605 |
Preferences.user.fontSize = $( e.target ).css( 'font-size' ); |
606 |
} ); |
607 |
break; |
608 |
case 'selected_search_targets': |
609 |
$( document ).on( 'change', 'input.search-toggle-server', function() { |
610 |
var server_id = $( this ).parent().data('server-id'); |
611 |
Preferences.user.selected_search_targets[server_id] = this.checked; |
612 |
Preferences.Save( [% USER_INFO.0.borrowernumber %] ); |
613 |
} ); |
614 |
break; |
615 |
} |
616 |
} |
617 |
|
618 |
function displayPreferences( editor ) { |
619 |
$.each( Preferences.user, function( pref, value ) { |
620 |
showPreference( pref ); |
621 |
bindPreference( editor, pref ); |
622 |
} ); |
623 |
} |
624 |
|
625 |
//> Macro functions |
626 |
function loadMacro( name ) { |
627 |
$( '#macro-list li' ).removeClass( 'active' ); |
628 |
macroEditor.activeMacro = name; |
629 |
|
630 |
if ( !name ) { |
631 |
macroEditor.setValue( '' ); |
632 |
return; |
633 |
} |
634 |
|
635 |
$( '#macro-list li[data-name="' + name + '"]' ).addClass( 'active' ); |
636 |
var macro = Preferences.user.macros[name]; |
637 |
macroEditor.setValue( macro.contents ); |
638 |
$( '#macro-format' ).val( macro.format || 'its' ); |
639 |
if ( macro.history ) macroEditor.setHistory( macro.history ); |
640 |
} |
641 |
|
642 |
function storeMacro( name, macro ) { |
643 |
if ( macro ) { |
644 |
Preferences.user.macros[name] = macro; |
645 |
} else { |
646 |
delete Preferences.user.macros[name]; |
647 |
} |
648 |
|
649 |
Preferences.Save( [% USER_INFO.0.borrowernumber %] ); |
650 |
} |
651 |
|
652 |
function showSavedMacros( macros ) { |
653 |
var scrollTop = $('#macro-list').scrollTop(); |
654 |
$( '#macro-list' ).empty(); |
655 |
var macro_list = $.map( Preferences.user.macros, function( macro, name ) { |
656 |
return $.extend( { name: name }, macro ); |
657 |
} ); |
658 |
macro_list.sort( function( a, b ) { |
659 |
return a.name.localeCompare(b.name); |
660 |
} ); |
661 |
$.each( macro_list, function( undef, macro ) { |
662 |
var $li = $( '<li data-name="' + macro.name + '"><a href="#">' + macro.name + '</a><ol class="macro-info"></ol></li>' ); |
663 |
$li.click( function() { |
664 |
loadMacro(macro.name); |
665 |
return false; |
666 |
} ); |
667 |
if ( macro.name == macroEditor.activeMacro ) $li.addClass( 'active' ); |
668 |
var modified = macro.modified && new Date(macro.modified); |
669 |
$li.find( '.macro-info' ).append( |
670 |
'<li><span class="label">' + _("Last changed:") + '</span>' + |
671 |
( modified ? modified.toLocaleFormat() : _("never") ) + '</li>' |
672 |
); |
673 |
$('#macro-list').append($li); |
674 |
} ); |
675 |
var $new_li = $( '<li class="new-macro"><a href="#">' + _("New macro...") + '</a></li>' ); |
676 |
$new_li.click( function() { |
677 |
// TODO: make this a bit less retro |
678 |
var name = prompt(_("Please enter the name for the new macro:")); |
679 |
if (!name) return; |
680 |
|
681 |
if ( !Preferences.user.macros[name] ) storeMacro( name, { format: "rancor", contents: "" } ); |
682 |
showSavedMacros(); |
683 |
loadMacro( name ); |
684 |
} ); |
685 |
$('#macro-list').append($new_li); |
686 |
$('#macro-list').scrollTop(scrollTop); |
687 |
} |
688 |
|
689 |
function saveMacro() { |
690 |
var name = macroEditor.activeMacro; |
691 |
|
692 |
if ( !name || macroEditor.savedGeneration == macroEditor.changeGeneration() ) return; |
693 |
|
694 |
macroEditor.savedGeneration = macroEditor.changeGeneration(); |
695 |
storeMacro( name, { contents: macroEditor.getValue(), modified: (new Date()).valueOf(), history: macroEditor.getHistory(), format: $('#macro-format').val() } ); |
696 |
$('#macro-save-message').text(_("Saved")); |
697 |
showSavedMacros(); |
698 |
} |
699 |
|
700 |
$(document).ready( function() { |
701 |
// Editor setup |
702 |
editor = new MARCEditor( { |
703 |
onCursorActivity: function() { |
704 |
$('#status-tag-info').empty(); |
705 |
$('#status-subfield-info').empty(); |
706 |
|
707 |
var field = editor.getCurrentField(); |
708 |
var cur = editor.getCursor(); |
709 |
|
710 |
if ( !field ) return; |
711 |
|
712 |
var taginfo = KohaBackend.GetTagInfo( '', field.tag ); |
713 |
$('#status-tag-info').html( '<strong>' + field.tag + ':</strong> ' ); |
714 |
|
715 |
if ( taginfo ) { |
716 |
$('#status-tag-info').append( '<a href="' + getFieldHelpURL( field.tag ) + '" target="_blank" class="show-field-help" title="' + _("Show help for this tag") + '">[?]</a> ' + taginfo.lib ); |
717 |
|
718 |
var subfield = field.getSubfieldAt( cur.ch ); |
719 |
if ( !subfield ) return; |
720 |
|
721 |
var subfieldinfo = taginfo.subfields[ subfield.code ]; |
722 |
$('#status-subfield-info').html( '<strong>$' + subfield.code + ':</strong> ' ); |
723 |
|
724 |
if ( subfieldinfo ) { |
725 |
$('#status-subfield-info').append( subfieldinfo.lib ); |
726 |
} else { |
727 |
$('#status-subfield-info').append( '<em>' + _("Unknown subfield") + '</em>' ); |
728 |
} |
729 |
} else { |
730 |
$('#status-tag-info').append( '<em>' + _("Unknown tag") + '</em>' ); |
731 |
} |
732 |
}, |
733 |
position: function (elt) { $(elt).insertAfter('#toolbar') }, |
734 |
} ); |
735 |
|
736 |
macroEditor = CodeMirror( |
737 |
$('#macro-editor')[0], |
738 |
{ |
739 |
mode: 'null', |
740 |
lineNumbers: true, |
741 |
} |
742 |
); |
743 |
|
744 |
// Automatically detect resizes and change the height of the editor and position of modals. |
745 |
var resizeTimer = null; |
746 |
$( window ).resize( function() { |
747 |
if ( resizeTimer == null ) resizeTimer = setTimeout( function() { |
748 |
resizeTimer = null; |
749 |
|
750 |
var pos = $('#editor .CodeMirror').position(); |
751 |
$('#editor .CodeMirror').height( $(window).height() - pos.top - 24 - $('#changelanguage').height() ); // 24 is hardcoded value but works well |
752 |
|
753 |
$('.modal-body').each( function() { |
754 |
$(this).height( $(window).height() * .8 - $(this).prevAll('.modal-header').height() ); |
755 |
} ); |
756 |
}, 100); |
757 |
|
758 |
$("#advanced-search-ui, #search-results-ui, #macro-ui").css( { |
759 |
marginLeft: function() { |
760 |
return -($(this).width() / 2); |
761 |
} |
762 |
} ); |
763 |
|
764 |
} ).resize(); |
765 |
|
766 |
var saveableBackends = []; |
767 |
$.each( backends, function( id, backend ) { |
768 |
if ( backend.save ) saveableBackends.push( [ backend.saveLabel, id ] ); |
769 |
} ); |
770 |
saveableBackends.sort(); |
771 |
$.each( saveableBackends, function( undef, backend ) { |
772 |
$( '#save-dropdown' ).append( '<li><a href="#" data-backend="' + backend[1] + '">' + backend[0] + '</a></li>' ); |
773 |
} ); |
774 |
|
775 |
var macro_format_list = $.map( Macros.formats, function( format, name ) { |
776 |
return $.extend( { name: name }, format ); |
777 |
} ); |
778 |
macro_format_list.sort( function( a, b ) { |
779 |
return a.description.localeCompare(b.description); |
780 |
} ); |
781 |
$.each( macro_format_list, function() { |
782 |
$('#macro-format').append( '<option value="' + this.name + '">' + this.description + '</option>' ); |
783 |
} ); |
784 |
|
785 |
// Click bindings |
786 |
$( '#save-record, #save-dropdown a' ).click( function() { |
787 |
$( '#save-record' ).find('i').attr( 'class', 'icon-loading' ).siblings( 'span' ).text( _("Saving...") ); |
788 |
|
789 |
function finishCb(result) { |
790 |
if ( result.error == 'syntax' ) { |
791 |
humanMsg.displayAlert( _("Incorrect syntax, cannot save"), { className: 'humanError' } ); |
792 |
} else if ( result.error == 'invalid' ) { |
793 |
humanMsg.displayAlert( _("Record structure invalid, cannot save"), { className: 'humanError' } ); |
794 |
} else if ( !result.error ) { |
795 |
humanMsg.displayAlert( _("Record saved "), { className: 'humanSuccess' } ); |
796 |
} |
797 |
|
798 |
$.each( result.errors || [], function( undef, error ) { |
799 |
switch ( error.type ) { |
800 |
case 'noTag': |
801 |
editor.addError( error.line, _("Invalid tag number") ); |
802 |
break; |
803 |
case 'noIndicators': |
804 |
editor.addError( error.line, _("Invalid indicators") ); |
805 |
break; |
806 |
case 'missingTag': |
807 |
editor.addError( null, _("Missing mandatory tag: ") + error.tag ); |
808 |
break; |
809 |
case 'missingSubfield': |
810 |
if ( error.subfield == '@' ) { |
811 |
editor.addError( error.line, _("Missing control field contents") ); |
812 |
} else { |
813 |
editor.addError( error.line, _("Missing mandatory subfield: $") + error.subfield ); |
814 |
} |
815 |
break; |
816 |
case 'unrepeatableTag': |
817 |
editor.addError( error.line, _("Tag ") + error.tag + _(" cannot be repeated") ); |
818 |
break; |
819 |
case 'unrepeatableSubfield': |
820 |
editor.addError( error.line, _("Subfield $") + error.subfield + _(" cannot be repeated") ); |
821 |
break; |
822 |
} |
823 |
} ); |
824 |
|
825 |
$( '#save-record' ).find('i').attr( 'class', 'icon-hdd' ); |
826 |
|
827 |
if ( result.error ) { |
828 |
// Reset backend info |
829 |
setSource( [ state.backend, state.recordID ] ); |
830 |
} |
831 |
} |
832 |
|
833 |
var backend = $( this ).data( 'backend' ) || ( state.saveBackend ); |
834 |
if ( state.backend == backend ) { |
835 |
saveRecord( backend + '/' + state.recordID, editor, finishCb ); |
836 |
} else { |
837 |
saveRecord( backend + '/', editor, finishCb ); |
838 |
} |
839 |
|
840 |
return false; |
841 |
} ); |
842 |
|
843 |
$('#import-records').click( function() { |
844 |
$('#import-records-input') |
845 |
.off('change') |
846 |
.change( function() { |
847 |
if ( !this.files || !this.files.length ) return; |
848 |
|
849 |
var file = this.files[0]; |
850 |
var reader = new FileReader(); |
851 |
|
852 |
reader.onload = function() { |
853 |
var record = new MARC.Record(); |
854 |
|
855 |
if ( /\.mrc$/.test( file.name ) ) { |
856 |
record.loadISO2709( reader.result ); |
857 |
} else if ( /\.xml$/.test( file.name ) ) { |
858 |
record.loadMARCXML( reader.result ); |
859 |
} else { |
860 |
humanMsg.displayAlert( _("Unknown record type, cannot import"), { className: 'humanError' } ); |
861 |
return; |
862 |
} |
863 |
|
864 |
editor.displayRecord( record ); |
865 |
}; |
866 |
|
867 |
reader.readAsText( file ); |
868 |
} ) |
869 |
.click(); |
870 |
|
871 |
return false; |
872 |
} ); |
873 |
|
874 |
$('#open-macros').click( function() { |
875 |
$('#macro-ui').modal('show'); |
876 |
|
877 |
return false; |
878 |
} ); |
879 |
|
880 |
$('#run-macro').click( function() { |
881 |
var result = Macros.Run( editor, $('#macro-format').val(), macroEditor.getValue() ); |
882 |
|
883 |
if ( !result.errors.length ) { |
884 |
$('#macro-ui').modal('hide'); |
885 |
return false; |
886 |
} |
887 |
|
888 |
var errors = []; |
889 |
$.each( result.errors, function() { |
890 |
var error = '<b>' + _("Line ") + (this.line + 1) + ':</b> '; |
891 |
|
892 |
switch ( this.error ) { |
893 |
case 'failed': error += _("failed to run"); break; |
894 |
case 'unrecognized': error += _("unrecognized command"); break; |
895 |
} |
896 |
|
897 |
errors.push(error); |
898 |
} ); |
899 |
|
900 |
humanMsg.displayMsg( _("<h3>Failed to run macro:</h3>") + '<ul><li>' + errors.join('</li><li>') + '</li></ul>', { className: 'humanError' } ); |
901 |
|
902 |
return false; |
903 |
} ); |
904 |
|
905 |
$('#delete-macro').click( function() { |
906 |
if ( !macroEditor.activeMacro || !confirm( _("Are you sure you want to delete this macro?") ) ) return; |
907 |
|
908 |
storeMacro( macroEditor.activeMacro, undefined ); |
909 |
showSavedMacros(); |
910 |
loadMacro( undefined ); |
911 |
|
912 |
return false; |
913 |
} ); |
914 |
|
915 |
var saveTimeout; |
916 |
macroEditor.on( 'change', function( cm, change ) { |
917 |
$('#macro-save-message').empty(); |
918 |
if ( change.origin == 'setValue' ) return; |
919 |
|
920 |
if ( saveTimeout ) clearTimeout( saveTimeout ); |
921 |
saveTimeout = setTimeout( function() { |
922 |
saveMacro(); |
923 |
|
924 |
saveTimeout = null; |
925 |
}, 500 ); |
926 |
} ); |
927 |
|
928 |
$( '#switch-editor' ).click( function() { |
929 |
if ( !confirm( _("Any changes will not be saved. Continue?") ) ) return; |
930 |
|
931 |
$.cookie( 'catalogue_editor_[% USER_INFO.0.borrowernumber %]', 'basic', { expires: 365, path: '/' } ); |
932 |
|
933 |
if ( state.backend == 'catalog' ) { |
934 |
window.location = '/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=' + state.recordID; |
935 |
} else if ( state.backend == 'new' ) { |
936 |
window.location = '/cgi-bin/koha/cataloguing/addbiblio.pl'; |
937 |
} else { |
938 |
humanMsg.displayAlert( _("Cannot open this record in the basic editor"), { className: 'humanError' } ); |
939 |
} |
940 |
} ); |
941 |
|
942 |
$( '#show-advanced-search' ).click( function() { |
943 |
showAdvancedSearch(); |
944 |
|
945 |
return false; |
946 |
} ); |
947 |
|
948 |
$('#advanced-search').submit( function() { |
949 |
startAdvancedSearch(); |
950 |
|
951 |
return false; |
952 |
} ); |
953 |
|
954 |
$( document ).on( 'click', 'a.search-nav', function() { |
955 |
$("#search-overlay").show(); |
956 |
Search.Fetch( { offset: $( this ).data( 'offset' ) } ); |
957 |
return false; |
958 |
}); |
959 |
|
960 |
$( document ).on( 'click', 'th[data-sort-label]', function() { |
961 |
$("#search-overlay").show(); |
962 |
var direction; |
963 |
|
964 |
if ( $( this ).hasClass( 'sorting_asc' ) ) { |
965 |
direction = 'desc'; |
966 |
} else { |
967 |
direction = 'asc'; |
968 |
} |
969 |
|
970 |
showSearchSorting( $( this ).data( 'sort-label' ), direction ); |
971 |
|
972 |
Search.Fetch( { sort_key: $( this ).data( 'sort-label' ), sort_direction: direction } ); |
973 |
return false; |
974 |
}); |
975 |
|
976 |
$( document ).on( 'change', 'input.search-toggle-server', function() { |
977 |
var server = z3950Servers[ $( this ).parent().data('server-id') ]; |
978 |
server.checked = this.checked; |
979 |
|
980 |
if ( $('#search-results-ui').is( ':visible' ) ) { |
981 |
$("#search-overlay").show(); |
982 |
Search.Fetch(); |
983 |
} |
984 |
} ); |
985 |
|
986 |
// Key bindings |
987 |
bindGlobalKeys(); |
988 |
|
989 |
// Setup UI |
990 |
$("#advanced-search-ui, #search-results-ui, #macro-ui").each( function() { |
991 |
$(this).modal({ show: false }); |
992 |
} ); |
993 |
|
994 |
var $quicksearch = $('#quicksearch fieldset'); |
995 |
$('<div id="quicksearch-overlay"><h3>' + _("Search unavailable") + '</h3> <p></p></div>').css({ |
996 |
position: 'absolute', |
997 |
top: $quicksearch.offset().top, |
998 |
left: $quicksearch.offset().left, |
999 |
height: $quicksearch.outerHeight(), |
1000 |
width: $quicksearch.outerWidth(), |
1001 |
}).appendTo(document.body).hide(); |
1002 |
|
1003 |
var prevAlerts = []; |
1004 |
humanMsg.logMsg = function(msg, options) { |
1005 |
$('#show-alerts').popover('hide'); |
1006 |
prevAlerts.unshift('<li>' + msg + '</li>'); |
1007 |
prevAlerts.splice(5, 999); // Truncate old messages |
1008 |
}; |
1009 |
|
1010 |
$('#show-alerts').popover({ |
1011 |
html: true, |
1012 |
placement: 'bottom', |
1013 |
content: function() { |
1014 |
return '<div id="alerts-container"><ul>' + prevAlerts.join('') + '</ul></div>'; |
1015 |
}, |
1016 |
}); |
1017 |
$('#new-record' ).click( function() { |
1018 |
openRecord( 'new/', editor ); |
1019 |
return false; |
1020 |
} ); |
1021 |
|
1022 |
// Start editor |
1023 |
Preferences.Load( [% USER_INFO.0.borrowernumber || 0 %] ); |
1024 |
displayPreferences(editor); |
1025 |
makeAuthorisedValueWidgets( '' ); |
1026 |
Search.Init( { |
1027 |
page_size: 20, |
1028 |
onresults: function(data) { showSearchResults( editor, data ) }, |
1029 |
onerror: handleSearchError, |
1030 |
} ); |
1031 |
|
1032 |
function finishCb( data ) { |
1033 |
if ( data.error ) openRecord( 'new/', editor, finishCb ); |
1034 |
|
1035 |
Resources.GetAll().done( function() { |
1036 |
$("#loading").hide(); |
1037 |
editor.focus(); |
1038 |
} ); |
1039 |
} |
1040 |
|
1041 |
if ( "[% auth_forwarded_hash %]" ) { |
1042 |
document.location.hash = "[% auth_forwarded_hash %]"; |
1043 |
} |
1044 |
|
1045 |
if ( !document.location.hash || !openRecord( document.location.hash.slice(1), editor, finishCb ) ) { |
1046 |
openRecord( 'new/', editor, finishCb ); |
1047 |
} |
1048 |
} ); |
1049 |
} )(); |
1050 |
|
1051 |
</script> |