|
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> |