Line 0
Link Here
|
|
|
1 |
<script src="/intranet-tmpl/lib/codemirror/codemirror.js"></script> |
2 |
<script src="/intranet-tmpl/lib/codemirror/lib/runmode.js"></script> |
3 |
<script src="/intranet-tmpl/lib/filesaver.js"></script> |
4 |
<script src="/intranet-tmpl/lib/koha/cateditor/marc-mode.js"></script> |
5 |
<script src="/intranet-tmpl/lib/require.js"></script> |
6 |
<script src="/intranet-tmpl/lib/jquery/plugins/jquery.lightbox_me.js"></script> |
7 |
<script> |
8 |
require.config( { |
9 |
baseUrl: '/intranet-tmpl/lib/koha/cateditor/', |
10 |
paths: { |
11 |
pz2: '../../pz2', |
12 |
}, |
13 |
shim: { |
14 |
pz2: { exports: 'pz2' }, |
15 |
}, |
16 |
} ); |
17 |
</script> |
18 |
|
19 |
[% IF marcflavour == 'MARC21' %] |
20 |
[% PROCESS 'cateditor-widgets-marc21.inc' %] |
21 |
[% ELSE %] |
22 |
<script>var editorWidgets = {};</script> |
23 |
[% END %] |
24 |
|
25 |
<script> |
26 |
require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'preferences', 'text-marc', 'widget', 'xslt' ], function( KohaBackend, Search, Macros, MARCEditor, MARC, Preferences, TextMARC, Widget, XSLT ) { |
27 |
var xsltResultStylesheets = { |
28 |
[% FOREACH stylesheet IN xslt_result_stylesheets %] |
29 |
'[% stylesheet.syntax %]': XSLT.Get( '[% stylesheet.url %]' ), |
30 |
[% END %] |
31 |
}; |
32 |
|
33 |
var xsltDetailStylesheets = { |
34 |
[% FOREACH stylesheet IN xslt_detail_stylesheets %] |
35 |
'[% stylesheet.syntax %]': XSLT.Get( '[% stylesheet.url %]' ), |
36 |
[% END %] |
37 |
}; |
38 |
|
39 |
var z3950Targets = { |
40 |
[% FOREACH target = z3950_targets %] |
41 |
'[% target.host %]:[% target.port %]/[% target.db %]': { |
42 |
'name': '[% target.name %]', |
43 |
'authentication': '[% target.userid %]:[% target.password %]', |
44 |
'syntax': '[% target.syntax %]', |
45 |
'kohasyntax': '[% target.syntax == 'USMARC' ? 'MARC21' : target.syntax %]', |
46 |
'encoding': '[% target.encoding %]', |
47 |
'checked': [% target.checked ? 'true' : 'false' %], |
48 |
}, |
49 |
[% END %] |
50 |
}; |
51 |
|
52 |
// The columns that should show up in a search, in order, and keyed by the corresponding <metadata> tag in the XSL and Pazpar2 config |
53 |
var z3950Labels = [ |
54 |
[ "md-work-title", "Title" ], |
55 |
[ "md-series-title", "Series-title" ], |
56 |
[ "md-work-author", "Author" ], |
57 |
[ "md-lccn", "LCCN" ], |
58 |
[ "md-isbn", "ISBN" ], |
59 |
[ "md-issn", "ISSN" ], |
60 |
[ "md-medium", "Medium" ], |
61 |
[ "md-edition", "Edition" ], |
62 |
[ "md-description", "Description" ], |
63 |
]; |
64 |
|
65 |
var state = { |
66 |
backend: '', |
67 |
saveBackend: 'catalog', |
68 |
recordID: undefined |
69 |
}; |
70 |
|
71 |
var editor; |
72 |
var macroEditor; |
73 |
|
74 |
function makeAuthorisedValueWidgets( frameworkCode ) { |
75 |
$.each( KohaBackend.GetAllTagsInfo( frameworkCode ), function( tag, tagInfo ) { |
76 |
$.each( tagInfo.subfields, function( subfield, subfieldInfo ) { |
77 |
if ( !subfieldInfo.authorised_value ) return; |
78 |
|
79 |
var authorisedWidget = { |
80 |
init: function() { |
81 |
var $result = $( '<span class="subfield-widget"></span>' ); |
82 |
|
83 |
return $result[0]; |
84 |
}, |
85 |
postCreate: function() { |
86 |
this.setText( subfieldInfo.defaultvalue ); |
87 |
|
88 |
$( '<select></select>' ).appendTo( this.node ); |
89 |
var $node = $( this.node ).find( 'select' ); |
90 |
$.each( KohaBackend.GetAuthorisedValues( subfieldInfo.authorised_value ), function( undef, authval ) { |
91 |
$node.append( '<option value="' + authval.value + '">' + authval.lib + '</option>' ); |
92 |
} ); |
93 |
$node.val( this.text ); |
94 |
|
95 |
$node.change( $.proxy( function() { |
96 |
this.setText( $node.val() ); |
97 |
}, this ) ); |
98 |
} |
99 |
}; |
100 |
|
101 |
editorWidgets[ tag + subfield ] = authorisedWidget; |
102 |
} ); |
103 |
} ); |
104 |
} |
105 |
|
106 |
function bindGlobalKeys() { |
107 |
function bindKey( key, handler ) { |
108 |
$( document ).bind( 'keydown', key, handler ); |
109 |
$( document ).bind( 'keypress', key, handler ); |
110 |
$( '#sidebar input' ).bind( 'keydown', key, handler ); |
111 |
$( '#editor textarea' ).bind( 'keydown', key, handler ); |
112 |
} |
113 |
|
114 |
shortcut.add( 'ctrl+s', function(event) { |
115 |
$( '#save-record' ).click(); |
116 |
|
117 |
event.preventDefault(); |
118 |
} ); |
119 |
|
120 |
shortcut.add( 'alt+ctrl+k', function(event) { |
121 |
$( '#search-by-keywords' ).focus(); |
122 |
|
123 |
return false; |
124 |
} ); |
125 |
|
126 |
shortcut.add( 'alt+ctrl+a', function(event) { |
127 |
$( '#search-by-author' ).focus(); |
128 |
|
129 |
return false; |
130 |
} ); |
131 |
|
132 |
shortcut.add( 'alt+ctrl+i', function(event) { |
133 |
$( '#search-by-isbn' ).focus(); |
134 |
|
135 |
return false; |
136 |
} ); |
137 |
|
138 |
shortcut.add( 'alt+ctrl+t', function(event) { |
139 |
$( '#search-by-title' ).focus(); |
140 |
|
141 |
return false; |
142 |
} ); |
143 |
|
144 |
$('#quicksearch .search-box').each( function() { |
145 |
shortcut.add( 'enter', $.proxy( function() { |
146 |
var q = this.value; |
147 |
if (!q) return false; |
148 |
|
149 |
showResultsBox(); |
150 |
Search.Start( z3950Targets, $(this).data('qualifier') + q, 20 ); |
151 |
|
152 |
return false; |
153 |
}, this), { target: this, type: 'keypress' } ); |
154 |
} ); |
155 |
} |
156 |
|
157 |
// Record loading |
158 |
var backends = { |
159 |
'new': { |
160 |
recordLabel: _("new record"), |
161 |
get: function( id, callback ) { |
162 |
record = new MARC.Record(); |
163 |
KohaBackend.FillRecord( '', record ); |
164 |
|
165 |
callback( record ); |
166 |
}, |
167 |
}, |
168 |
'new-full': { |
169 |
recordLabel: _("new full record"), |
170 |
get: function( id, callback ) { |
171 |
record = new MARC.Record(); |
172 |
KohaBackend.FillRecord( '', record, true ); |
173 |
|
174 |
callback( record ); |
175 |
}, |
176 |
}, |
177 |
'catalog': { |
178 |
recordLabel: _("catalog record #{ID}"), |
179 |
saveLabel: _("to catalog"), |
180 |
get: function( id, callback ) { |
181 |
if ( !id ) return false; |
182 |
|
183 |
KohaBackend.GetRecord( id, callback ); |
184 |
}, |
185 |
save: function( id, record, done ) { |
186 |
function finishCb( data ) { |
187 |
done( { error: data.error, newRecord: data.marcxml && data.marcxml[0], newId: data.biblionumber && [ 'catalog', data.biblionumber ] } ); |
188 |
} |
189 |
|
190 |
if ( id ) { |
191 |
KohaBackend.SaveRecord( id, record, finishCb ); |
192 |
} else { |
193 |
KohaBackend.CreateRecord( record, finishCb ); |
194 |
} |
195 |
} |
196 |
}, |
197 |
'iso2709': { |
198 |
saveLabel: _("to ISO2709 (.mrc) file"), |
199 |
save: function( id, record, done ) { |
200 |
saveAs( new Blob( [record.toISO2709()], { 'type': 'application/octet-stream;charset=utf-8' } ), 'record.mrc' ); |
201 |
|
202 |
done( {} ); |
203 |
} |
204 |
}, |
205 |
'marcxml': { |
206 |
saveLabel: _("to MARCXML (.xml) file"), |
207 |
save: function( id, record, done ) { |
208 |
saveAs( new Blob( [record.toXML()], { 'type': 'application/octet-stream;charset=utf-8' } ), 'record.xml' ); |
209 |
|
210 |
done( {} ); |
211 |
} |
212 |
}, |
213 |
'search': { |
214 |
recordLabel: _("search result"), |
215 |
get: function( id, callback ) { |
216 |
if ( !id ) return false; |
217 |
|
218 |
Search.GetDetailedRecord( decodeURIComponent(id), callback ); |
219 |
}, |
220 |
}, |
221 |
}; |
222 |
|
223 |
function setSource(parts) { |
224 |
state.backend = parts[0]; |
225 |
state.recordID = parts[1]; |
226 |
state.canSave = backends[ state.backend ].save != null; |
227 |
state.saveBackend = state.canSave ? state.backend : 'catalog'; |
228 |
|
229 |
document.location.hash = '#' + parts[0] + ':' + parts[1]; |
230 |
$( '#title' ).text( _("Editing ") + backends[ state.backend ].recordLabel.replace( '{ID}', parts[1] ) ); |
231 |
$( 'title', document.head ).html( _("Koha › Cataloging › Editing ") + backends[ state.backend ].recordLabel.replace( '{ID}', parts[1] ) ); |
232 |
$( '#save-record span' ).text( _("Save ") + backends[ state.saveBackend ].saveLabel ); |
233 |
} |
234 |
|
235 |
function saveRecord( recid, editor, callback ) { |
236 |
var parts = recid.split(':'); |
237 |
if ( parts.length != 2 ) return false; |
238 |
|
239 |
if ( !backends[ parts[0] ] || !backends[ parts[0] ].save ) return false; |
240 |
|
241 |
editor.removeErrors(); |
242 |
var record = editor.getRecord(); |
243 |
|
244 |
if ( record.errors ) { |
245 |
state.saving = false; |
246 |
callback( { error: 'syntax', errors: record.errors } ); |
247 |
return; |
248 |
} |
249 |
|
250 |
var errors = KohaBackend.ValidateRecord( '', record ); |
251 |
if ( errors.length ) { |
252 |
state.saving = false; |
253 |
callback( { error: 'invalid', errors: errors } ); |
254 |
return; |
255 |
} |
256 |
|
257 |
backends[ parts[0] ].save( parts[1], record, function(data) { |
258 |
state.saving = false; |
259 |
|
260 |
if (data.newRecord) { |
261 |
var record = new MARC.Record(); |
262 |
record.loadMARCXML(data.newRecord); |
263 |
editor.displayRecord( record ); |
264 |
} |
265 |
|
266 |
if (data.newId) { |
267 |
setSource(data.newId); |
268 |
} else { |
269 |
setSource( [ state.backend, state.recordID ] ); |
270 |
} |
271 |
|
272 |
if (callback) callback( data ); |
273 |
} ); |
274 |
} |
275 |
|
276 |
function loadRecord( recid, editor, callback ) { |
277 |
var parts = recid.split(':'); |
278 |
if ( parts.length != 2 ) return false; |
279 |
|
280 |
if ( !backends[ parts[0] ] || !backends[ parts[0] ].get ) return false; |
281 |
|
282 |
backends[ parts[0] ].get( parts[1], function( record ) { |
283 |
editor.displayRecord( record ); |
284 |
editor.focus(); |
285 |
|
286 |
if (callback) callback(record); |
287 |
} ); |
288 |
|
289 |
return true; |
290 |
} |
291 |
|
292 |
function openRecord( recid, editor, callback ) { |
293 |
return loadRecord( recid, editor, function ( record ) { |
294 |
setSource( recid.split(':') ); |
295 |
|
296 |
if (callback) callback( record ); |
297 |
} ); |
298 |
} |
299 |
|
300 |
// Search functions |
301 |
function showAdvancedSearch() { |
302 |
$('#advanced-search-ui').lightbox_me(); |
303 |
} |
304 |
|
305 |
function startAdvancedSearch() { |
306 |
var search = ''; |
307 |
|
308 |
$('#advanced-search-ui input').each( function() { |
309 |
if (!this.value) return; |
310 |
if (search) search += ' and '; |
311 |
search += $(this).data('qualifier') + this.value; |
312 |
} ); |
313 |
|
314 |
if (!search) return; |
315 |
|
316 |
$('#advanced-search-ui').trigger('close'); |
317 |
showResultsBox(); |
318 |
Search.Start( z3950Targets, search, 20 ); |
319 |
} |
320 |
|
321 |
function showResultsBox(data) { |
322 |
$('#searchresults thead tr').empty(); |
323 |
$('#searchresults tbody').empty(); |
324 |
$('#search-targetsinfo').empty().append('<li>' + _("Loading...") + '</li>'); |
325 |
$('#search-results-ui').lightbox_me(); |
326 |
} |
327 |
|
328 |
function showDetailedResult( hit, $tr, fetchOnly ) { |
329 |
Search.GetDetailedRecord( hit.recid, function( record ) { |
330 |
if ( fetchOnly ) return; |
331 |
|
332 |
xsltResultStylesheets[ z3950Targets[ hit.location[0]['@id'] ].kohasyntax ].done( function( xslDoc ) { |
333 |
$tr.find( '.results-info' ).html( XSLT.TransformToFragment( record.xmlSource, xslDoc ) ); |
334 |
} ); |
335 |
} ); |
336 |
} |
337 |
|
338 |
function showSearchResults( editor, data ) { |
339 |
$('#searchresults thead tr').empty(); |
340 |
$('#searchresults tbody').empty(); |
341 |
|
342 |
var seenColumns = {}; |
343 |
|
344 |
$.each( data.hits, function( undef, hit ) { |
345 |
for ( key in hit ) { |
346 |
if ( /^md-/.test(key) ) seenColumns[key] = true; |
347 |
} |
348 |
|
349 |
$.each( hit.location, function( undef, location ) { |
350 |
for ( key in location ) { |
351 |
if ( /^md-/.test(key) ) seenColumns[key] = true; |
352 |
} |
353 |
} ); |
354 |
} ); |
355 |
|
356 |
$('#searchresults thead tr').append('<th>' + _("Source") + '</th>'); |
357 |
|
358 |
$.each( z3950Labels, function( undef, label ) { |
359 |
if ( seenColumns[ label[0] ] ) { |
360 |
$('#searchresults thead tr').append( '<th>' + label[1] + '</th>' ); |
361 |
} |
362 |
} ); |
363 |
|
364 |
$('#searchresults thead tr').append('<th>' + _("Tools") + '</th>'); |
365 |
|
366 |
$.each( data.hits, function( undef, hit ) { |
367 |
var result = '<tr>'; |
368 |
result += '<td class="sourcecol">' + hit.location[0]['@name'] + '</td>'; |
369 |
|
370 |
$.each( z3950Labels, function( undef, label ) { |
371 |
if ( !seenColumns[ label[0] ] ) return; |
372 |
|
373 |
if ( hit[ label[0] ] ) { |
374 |
result += '<td class="infocol">' + hit[ label[0] ].join('<br/>') + '</td>'; |
375 |
} else if ( hit.location[0][ label[0] ] ) { |
376 |
result += '<td class="infocol">' + hit.location[0][ label[0] ].join('<br/>') + '</td>'; |
377 |
} else { |
378 |
result += '<td class="infocol"> </td>'; |
379 |
} |
380 |
} ); |
381 |
|
382 |
result += '<td class="toolscol"><ul><li><a href="#" class="marc-link">' + _("View MARC") + '</a></li>'; |
383 |
result += '<li><a href="#" class="open-link">' + _("Import") + '</a></li>'; |
384 |
if ( state.canSave ) result += '<li><a href="#" class="substitute-link" title="' + _("Replace the current record's contents") + '">' + _("Substitute") + '</a></li>'; |
385 |
// REMOVE: (vim syntax highlighting bug) "</a></a>" |
386 |
result += '</ul></td></tr>'; |
387 |
|
388 |
var $tr = $( result ); |
389 |
$tr.find( '.marc-link' ).click( function() { |
390 |
Search.GetDetailedRecord( hit.recid, function( record ) { |
391 |
var $columns = $tr.find( '.infocol' ); |
392 |
CodeMirror.runMode( TextMARC.RecordToText( record ), 'marc', $( '<td class="infocol results-marc" colspan="' + $columns.length + '"></td>' ).replaceAll( $columns.slice(1).remove().end()[0] )[0] ); |
393 |
} ); |
394 |
|
395 |
return false; |
396 |
} ); |
397 |
$tr.find( '.open-link' ).click( function() { |
398 |
$( '#search-results-ui' ).trigger( 'close' ); |
399 |
openRecord( hit.id, editor ); |
400 |
|
401 |
return false; |
402 |
} ); |
403 |
$tr.find( '.substitute-link' ).click( function() { |
404 |
$( '#search-results-ui' ).trigger( 'close' ); |
405 |
loadRecord( hit.id, editor ); |
406 |
|
407 |
return false; |
408 |
} ); |
409 |
$('#searchresults tbody').append( $tr ); |
410 |
|
411 |
//showDetailedResult( hit, $tr, !!data.activeclients ); |
412 |
} ); |
413 |
|
414 |
var $overlay = $('#search-overlay'); |
415 |
$overlay.find('span').text(_("Loading")); |
416 |
$overlay.find('.bar').css( { display: 'block', width: 100 * ( 1 - data.activeclients / Search.includedTargets.length ) + '%' } ); |
417 |
|
418 |
if ( data.activeclients ) { |
419 |
$overlay.find('.bar').css( { display: 'block', width: 100 * ( 1 - data.activeclients / Search.includedTargets.length ) + '%' } ); |
420 |
$overlay.show(); |
421 |
} else { |
422 |
$overlay.find('.bar').css( { display: 'block', width: '100%' } ); |
423 |
$overlay.fadeOut(); |
424 |
} |
425 |
} |
426 |
|
427 |
function invalidateSearchResults() { |
428 |
var $overlay = $('#search-overlay'); |
429 |
$overlay.find('span').text(_("Search expired, please try again")); |
430 |
$overlay.find('.bar').css( { display: 'none' } ); |
431 |
$overlay.show(); |
432 |
} |
433 |
|
434 |
function showSearchTargets(data) { |
435 |
$('#search-targetsinfo').empty(); |
436 |
|
437 |
$.each( data, function( undef, target ) { |
438 |
$('#search-targetsinfo').append( '<li>' + target.name + ' (' + target.hits + ')' + '</li>' ); |
439 |
} ); |
440 |
} |
441 |
|
442 |
function handleSearchError(error) { |
443 |
if (error.code == 1) { |
444 |
invalidateSearchResults(); |
445 |
Search.Reconnect(); |
446 |
} else { |
447 |
humanMsg.displayMsg( _("<h3>Internal search error</h3>") + '<p>' + error + '</p>' + _("<p>Please <b>refresh</b> the page and try again."), { className: 'humanError' } ); |
448 |
} |
449 |
} |
450 |
|
451 |
// Preference functions |
452 |
function showPreference( pref ) { |
453 |
var value = Preferences.user[pref]; |
454 |
|
455 |
switch (pref) { |
456 |
case 'fieldWidgets': |
457 |
$( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") ); |
458 |
break; |
459 |
case 'font': |
460 |
$( '#editor .CodeMirror' ).css( { fontFamily: value } ); |
461 |
editor.refresh(); |
462 |
break; |
463 |
case 'fontSize': |
464 |
$( '#editor .CodeMirror' ).css( { fontSize: value } ); |
465 |
editor.refresh(); |
466 |
break; |
467 |
case 'macros': |
468 |
showSavedMacros(); |
469 |
break; |
470 |
} |
471 |
} |
472 |
|
473 |
function bindPreference( editor, pref ) { |
474 |
function _addHandler( sel, event, handler ) { |
475 |
$( sel ).on( event, function (e) { |
476 |
e.preventDefault(); |
477 |
handler( e, Preferences.user[pref] ); |
478 |
Preferences.Save( [% USER_INFO.0.borrowernumber %] ); |
479 |
showPreference(pref); |
480 |
} ); |
481 |
} |
482 |
|
483 |
switch (pref) { |
484 |
case 'fieldWidgets': |
485 |
_addHandler( '#set-field-widgets', 'click', function( e, oldValue ) { |
486 |
editor.setUseWidgets( Preferences.user.fieldWidgets = !Preferences.user.fieldWidgets ); |
487 |
} ); |
488 |
break; |
489 |
case 'font': |
490 |
_addHandler( '#prefs-menu .set-font', 'click', function( e, oldValue ) { |
491 |
Preferences.user.font = $( e.target ).css( 'font-family' ); |
492 |
} ); |
493 |
break; |
494 |
case 'fontSize': |
495 |
_addHandler( '#prefs-menu .set-fontSize', 'click', function( e, oldValue ) { |
496 |
Preferences.user.fontSize = $( e.target ).css( 'font-size' ); |
497 |
} ); |
498 |
break; |
499 |
} |
500 |
} |
501 |
|
502 |
function displayPreferences( editor ) { |
503 |
$.each( Preferences.user, function( pref, value ) { |
504 |
showPreference( pref ); |
505 |
bindPreference( editor, pref ); |
506 |
} ); |
507 |
} |
508 |
|
509 |
//> Macro functions |
510 |
function loadMacro( name ) { |
511 |
$( '#macro-list li' ).removeClass( 'active' ); |
512 |
macroEditor.activeMacro = name; |
513 |
|
514 |
if ( !name ) { |
515 |
macroEditor.setValue( '' ); |
516 |
return; |
517 |
} |
518 |
|
519 |
$( '#macro-list li[data-name="' + name + '"]' ).addClass( 'active' ); |
520 |
var macro = Preferences.user.macros[name]; |
521 |
macroEditor.setValue( macro.contents ); |
522 |
if ( macro.history ) macroEditor.setHistory( macro.history ); |
523 |
} |
524 |
|
525 |
function storeMacro( name, macro ) { |
526 |
if ( macro ) { |
527 |
Preferences.user.macros[name] = macro; |
528 |
} else { |
529 |
delete Preferences.user.macros[name]; |
530 |
} |
531 |
|
532 |
Preferences.Save( [% USER_INFO.0.borrowernumber %] ); |
533 |
} |
534 |
|
535 |
function showSavedMacros( macros ) { |
536 |
var scrollTop = $('#macro-list').scrollTop(); |
537 |
$( '#macro-list' ).empty(); |
538 |
var macro_list = $.map( Preferences.user.macros, function( macro, name ) { |
539 |
return $.extend( { name: name }, macro ); |
540 |
} ); |
541 |
macro_list.sort( function( a, b ) { |
542 |
return a.name.localeCompare(b.name); |
543 |
} ); |
544 |
$.each( macro_list, function( undef, macro ) { |
545 |
var $li = $( '<li data-name="' + macro.name + '"><a href="#">' + macro.name + '</a><ol class="macro-info"></ol></li>' ); |
546 |
$li.click( function() { |
547 |
loadMacro(macro.name); |
548 |
return false; |
549 |
} ); |
550 |
if ( macro.name == macroEditor.activeMacro ) $li.addClass( 'active' ); |
551 |
var modified = macro.modified && new Date(macro.modified); |
552 |
$li.find( '.macro-info' ).append( |
553 |
'<li><span class="label">' + _("Last changed:") + '</span>' + |
554 |
( modified ? modified.toLocaleFormat() : _("never") ) + '</li>' |
555 |
); |
556 |
$('#macro-list').append($li); |
557 |
} ); |
558 |
var $new_li = $( '<li class="new-macro"><a href="#">' + _("New macro...") + '</a></li>' ); |
559 |
$new_li.click( function() { |
560 |
// TODO: make this a bit less retro |
561 |
var name = prompt(_("Please enter the name for the new macro:")); |
562 |
if (!name) return; |
563 |
|
564 |
if ( !Preferences.user.macros[name] ) storeMacro( name, { contents: "" } ); |
565 |
showSavedMacros(); |
566 |
loadMacro( name ); |
567 |
} ); |
568 |
$('#macro-list').append($new_li); |
569 |
$('#macro-list').scrollTop(scrollTop); |
570 |
} |
571 |
|
572 |
function saveMacro() { |
573 |
var name = macroEditor.activeMacro; |
574 |
|
575 |
if ( !name || macroEditor.savedGeneration == macroEditor.changeGeneration() ) return; |
576 |
|
577 |
macroEditor.savedGeneration = macroEditor.changeGeneration(); |
578 |
storeMacro( name, { contents: macroEditor.getValue(), modified: (new Date()).valueOf(), history: macroEditor.getHistory() } ); |
579 |
$('#macro-save-message').text(_("Saved")); |
580 |
showSavedMacros(); |
581 |
} |
582 |
|
583 |
$(document).ready( function() { |
584 |
// Editor setup |
585 |
editor = new MARCEditor( function (elt) { $(elt).insertAfter('#toolbar') } ); |
586 |
|
587 |
macroEditor = CodeMirror( |
588 |
$('#macro-editor')[0], |
589 |
{ |
590 |
mode: 'null', |
591 |
lineNumbers: true, |
592 |
} |
593 |
); |
594 |
|
595 |
var resizeTimer = null; |
596 |
$( window ).resize( function() { |
597 |
if ( resizeTimer == null ) resizeTimer = setTimeout( function() { |
598 |
resizeTimer = null; |
599 |
|
600 |
var pos = $('#editor .CodeMirror').position(); |
601 |
$('#editor .CodeMirror').height( $(window).height() - pos.top - 24 ); |
602 |
}, 100); |
603 |
} ).resize(); |
604 |
|
605 |
var saveableBackends = []; |
606 |
$.each( backends, function( id, backend ) { |
607 |
if ( backend.save ) saveableBackends.push( [ backend.saveLabel, id ] ); |
608 |
} ); |
609 |
saveableBackends.sort(); |
610 |
$.each( saveableBackends, function( undef, backend ) { |
611 |
$( '#save-dropdown' ).append( '<li><a href="#" data-backend="' + backend[1] + '">' + _("Save ") + backend[0] + '</a></li>' ); |
612 |
} ); |
613 |
|
614 |
// Click bindings |
615 |
$( '#save-record, #save-dropdown a' ).click( function() { |
616 |
$( '#save-record' ).find('i').attr( 'class', 'icon-loading' ).siblings( 'span' ).text( _("Saving...") ); |
617 |
|
618 |
function finishCb(result) { |
619 |
if ( result.error == 'syntax' ) { |
620 |
humanMsg.displayAlert( _("Incorrect syntax, cannot save"), { className: 'humanError' } ); |
621 |
} else if ( result.error == 'invalid' ) { |
622 |
humanMsg.displayAlert( _("Record structure invalid, cannot save"), { className: 'humanError' } ); |
623 |
} else if ( !result.error ) { |
624 |
humanMsg.displayAlert( _("Record saved "), { className: 'humanSuccess' } ); |
625 |
} |
626 |
|
627 |
$.each( result.errors || [], function( undef, error ) { |
628 |
switch ( error.type ) { |
629 |
case 'noTag': |
630 |
editor.addError( error.line, _("Invalid tag number") ); |
631 |
break; |
632 |
case 'noIndicators': |
633 |
editor.addError( error.line, _("Invalid indicators") ); |
634 |
break; |
635 |
case 'missingTag': |
636 |
editor.addError( null, _("Missing mandatory tag: ") + error.tag ); |
637 |
break; |
638 |
case 'missingSubfield': |
639 |
if ( error.subfield == '@' ) { |
640 |
editor.addError( error.line, _("Missing control field contents") ); |
641 |
} else { |
642 |
editor.addError( error.line, _("Missing mandatory subfield: $") + error.subfield ); |
643 |
} |
644 |
break; |
645 |
case 'unrepeatableTag': |
646 |
editor.addError( error.line, _("Tag ") + error.tag + _(" cannot be repeated") ); |
647 |
break; |
648 |
case 'unrepeatableSubfield': |
649 |
editor.addError( error.line, _("Subfield $") + error.subfield + _(" cannot be repeated") ); |
650 |
break; |
651 |
} |
652 |
} ); |
653 |
|
654 |
$( '#save-record' ).find('i').attr( 'class', 'icon-hdd' ); |
655 |
|
656 |
if ( result.error ) { |
657 |
// Reset backend info |
658 |
setSource( [ state.backend, state.recordID ] ); |
659 |
} |
660 |
} |
661 |
|
662 |
var backend = $( this ).data( 'backend' ) || ( state.saveBackend ); |
663 |
if ( state.backend == backend ) { |
664 |
saveRecord( backend + ':' + state.recordID, editor, finishCb ); |
665 |
} else { |
666 |
saveRecord( backend + ':', editor, finishCb ); |
667 |
} |
668 |
|
669 |
return false; |
670 |
} ); |
671 |
|
672 |
$('#import-records').click( function() { |
673 |
$('#import-records-input') |
674 |
.off('change') |
675 |
.change( function() { |
676 |
if ( !this.files || !this.files.length ) return; |
677 |
|
678 |
var file = this.files[0]; |
679 |
var reader = new FileReader(); |
680 |
|
681 |
reader.onload = function() { |
682 |
var record = new MARC.Record(); |
683 |
|
684 |
if ( /\.mrc$/.test( file.name ) ) { |
685 |
record.loadISO2709( reader.result ); |
686 |
} else if ( /\.xml$/.test( file.name ) ) { |
687 |
record.loadMARCXML( reader.result ); |
688 |
} else { |
689 |
humanMsg.displayAlert( _("Unknown record type, cannot import"), { className: 'humanError' } ); |
690 |
return; |
691 |
} |
692 |
|
693 |
editor.displayRecord( record ); |
694 |
}; |
695 |
|
696 |
reader.readAsText( file ); |
697 |
} ) |
698 |
.click(); |
699 |
|
700 |
return false; |
701 |
} ); |
702 |
|
703 |
$('#open-macros').click( function() { |
704 |
$('#macro-ui').lightbox_me(); |
705 |
|
706 |
return false; |
707 |
} ); |
708 |
|
709 |
$('#run-macro').click( function() { |
710 |
var result = Macros.Run( editor, macroEditor.getValue() ); |
711 |
|
712 |
if ( !result.errors.length ) return false; |
713 |
|
714 |
var errors = []; |
715 |
$.each( result.errors, function() { |
716 |
var error = '<b>' + _("Line ") + (this.line + 1) + ':</b> '; |
717 |
|
718 |
switch ( this.error ) { |
719 |
case 'failed': error += _("failed to run"); break; |
720 |
case 'unrecognized': error += _("unrecognized command"); break; |
721 |
} |
722 |
|
723 |
errors.push(error); |
724 |
} ); |
725 |
|
726 |
humanMsg.displayMsg( _("<h3>Failed to run macro:</h3>") + '<ul><li>' + errors.join('</li><li>') + '</li></ul>', { className: 'humanError' } ); |
727 |
|
728 |
return false; |
729 |
} ); |
730 |
|
731 |
$('#delete-macro').click( function() { |
732 |
if ( !macroEditor.activeMacro || !confirm( _("Are you sure you want to delete this macro?") ) ) return; |
733 |
|
734 |
storeMacro( macroEditor.activeMacro, undefined ); |
735 |
showSavedMacros(); |
736 |
loadMacro( undefined ); |
737 |
|
738 |
return false; |
739 |
} ); |
740 |
|
741 |
var saveTimeout; |
742 |
macroEditor.on( 'change', function( cm, change ) { |
743 |
$('#macro-save-message').empty(); |
744 |
if ( change.origin == 'setValue' ) return; |
745 |
|
746 |
if ( saveTimeout ) clearTimeout( saveTimeout ); |
747 |
saveTimeout = setTimeout( function() { |
748 |
saveMacro(); |
749 |
|
750 |
saveTimeout = null; |
751 |
}, 500 ); |
752 |
} ); |
753 |
|
754 |
$( '#switch-editor' ).click( function() { |
755 |
if ( !confirm( _("Any changes will not be saved. Continue?") ) ) return; |
756 |
|
757 |
$.cookie( 'catalogue_editor_[% USER_INFO.0.borrowernumber %]', 'basic', { expires: 365, path: '/' } ); |
758 |
|
759 |
if ( state.backend == 'catalog' ) { |
760 |
window.location = '/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=' + state.recordID; |
761 |
} else if ( state.backend == 'new' ) { |
762 |
window.location = '/cgi-bin/koha/cataloguing/addbiblio.pl'; |
763 |
} else { |
764 |
humanMsg.displayAlert( _("Cannot open this record in the basic editor"), { className: 'humanError' } ); |
765 |
} |
766 |
} ); |
767 |
|
768 |
$( '#show-advanced-search' ).click( function() { |
769 |
showAdvancedSearch(); |
770 |
|
771 |
return false; |
772 |
} ); |
773 |
|
774 |
$('#advanced-search').submit( function() { |
775 |
startAdvancedSearch(); |
776 |
|
777 |
return false; |
778 |
} ); |
779 |
|
780 |
// Key bindings |
781 |
bindGlobalKeys(); |
782 |
|
783 |
// Start editor |
784 |
Preferences.Load( [% USER_INFO.0.borrowernumber %] ); |
785 |
displayPreferences(editor); |
786 |
makeAuthorisedValueWidgets( '' ); |
787 |
Search.Init( z3950Targets, { onresults: function(data) { showSearchResults( editor, data ) }, onbytarget: showSearchTargets, onerror: handleSearchError } ); |
788 |
|
789 |
function finishCb() { |
790 |
$("#loading").hide(); |
791 |
editor.focus(); |
792 |
} |
793 |
|
794 |
if ( "[% auth_forwarded_hash %]" ) { |
795 |
document.location.hash = "[% auth_forwarded_hash %]"; |
796 |
} |
797 |
|
798 |
if ( !document.location.hash || !openRecord( document.location.hash.slice(1), editor, finishCb ) ) { |
799 |
openRecord( 'new:', editor, finishCb ); |
800 |
} |
801 |
} ); |
802 |
} )(); |
803 |
|
804 |
</script> |