Lines 64-69
window.onbeforeunload = function () {
Link Here
|
64 |
} |
64 |
} |
65 |
}; |
65 |
}; |
66 |
|
66 |
|
|
|
67 |
// Add event handlers to any elements with .expand-textarea classes |
68 |
// this allows the CodeMirror widget to be displayed |
69 |
function addExpandHandler() { |
70 |
// Don't duplicate click event handlers |
71 |
const ev = $._data($('.expand-textarea'), 'events'); |
72 |
if (ev && ev.click) { |
73 |
return; |
74 |
} |
75 |
$(".expand-textarea").on("click", function (e) { |
76 |
e.preventDefault(); |
77 |
$(this).hide(); |
78 |
var target = $(this).data("target"); |
79 |
var syntax = $(this).data("syntax"); |
80 |
$("#collapse_" + target).show(); |
81 |
if (syntax) { |
82 |
var editor = CodeMirror.fromTextArea(document.getElementById("pref_" + target), { |
83 |
lineNumbers: true, |
84 |
mode: syntax, |
85 |
lineWrapping: true, |
86 |
viewportMargin: Infinity, |
87 |
gutters: ["CodeMirror-lint-markers"], |
88 |
lint: true |
89 |
}); |
90 |
editor.on("change", function () { |
91 |
mark_modified.call($("#pref_" + target)[0]); |
92 |
}); |
93 |
editor.on("blur", function () { |
94 |
editor.save(); |
95 |
}); |
96 |
} else { |
97 |
$("#pref_" + target).show(); |
98 |
} |
99 |
}); |
100 |
} |
101 |
|
102 |
// Add event handlers to any elements with .collapse-textarea classes |
103 |
// this allows the hiding of the CodeMirror widget |
104 |
function addCollapseHandler() { |
105 |
// Don't duplicate click event handlers |
106 |
const ev = $._data($('.collapse-textarea'), 'events'); |
107 |
if (ev && ev.click) { |
108 |
return; |
109 |
} |
110 |
$(".collapse-textarea").on("click", function (e) { |
111 |
e.preventDefault(); |
112 |
$(this).hide(); |
113 |
var target = $(this).data("target"); |
114 |
var syntax = $(this).data("syntax"); |
115 |
$("#expand_" + target).show(); |
116 |
if (syntax) { |
117 |
var editor = $("#pref_" + target).next(".CodeMirror")[0].CodeMirror; |
118 |
editor.toTextArea(); |
119 |
} |
120 |
$("#pref_" + target).hide(); |
121 |
}); |
122 |
} |
123 |
|
124 |
// Add a handler for any consent delete links |
125 |
function addConsentDeleteHandler() { |
126 |
// Don't duplicate click event handlers |
127 |
const ev = $._data($('.consentDelete'), 'events'); |
128 |
if (ev && ev.click) { |
129 |
return; |
130 |
} |
131 |
$('.consentDelete').on('click', function (e) { |
132 |
e.preventDefault(); |
133 |
const target = $(this).data('target'); |
134 |
const proceed = confirm(__('Are you sure you want to delete this consent item?')); |
135 |
if (proceed) { |
136 |
$('#' + target).remove(); |
137 |
} |
138 |
}); |
139 |
} |
140 |
|
67 |
$( document ).ready( function () { |
141 |
$( document ).ready( function () { |
68 |
|
142 |
|
69 |
$("table.preferences").dataTable($.extend(true, {}, dataTablesDefaults, { |
143 |
$("table.preferences").dataTable($.extend(true, {}, dataTablesDefaults, { |
Lines 107-150
$( document ).ready( function () {
Link Here
|
107 |
return false; |
181 |
return false; |
108 |
}); |
182 |
}); |
109 |
|
183 |
|
110 |
$( ".expand-textarea" ).on("click", function(e){ |
184 |
addExpandHandler(); |
111 |
e.preventDefault(); |
|
|
112 |
$(this).hide(); |
113 |
var target = $(this).data("target"); |
114 |
var syntax = $(this).data("syntax"); |
115 |
$("#collapse_" + target ).show(); |
116 |
if( syntax ){ |
117 |
var editor = CodeMirror.fromTextArea( document.getElementById( "pref_" + target ), { |
118 |
lineNumbers: true, |
119 |
mode: syntax, |
120 |
lineWrapping: true, |
121 |
viewportMargin: Infinity, |
122 |
gutters: ["CodeMirror-lint-markers"], |
123 |
lint: true |
124 |
}); |
125 |
editor.on("change", function(){ |
126 |
mark_modified.call( $("#pref_" + target )[0]); |
127 |
}); |
128 |
editor.on("blur", function(){ |
129 |
editor.save(); |
130 |
}); |
131 |
} else { |
132 |
$("#pref_" + target ).show(); |
133 |
} |
134 |
}); |
135 |
|
185 |
|
136 |
$( ".collapse-textarea" ).on("click", function(e){ |
186 |
addCollapseHandler(); |
137 |
e.preventDefault(); |
|
|
138 |
$(this).hide(); |
139 |
var target = $(this).data("target"); |
140 |
var syntax = $(this).data("syntax"); |
141 |
$("#expand_" + target ).show(); |
142 |
if( syntax ){ |
143 |
var editor = $("#pref_" + target ).next(".CodeMirror")[0].CodeMirror; |
144 |
editor.toTextArea(); |
145 |
} |
146 |
$("#pref_" + target ).hide(); |
147 |
}); |
148 |
|
187 |
|
149 |
$("h3").attr("class", "expanded").attr("title", __("Click to collapse this section")); |
188 |
$("h3").attr("class", "expanded").attr("title", __("Click to collapse this section")); |
150 |
var collapsible = $(".collapsed,.expanded"); |
189 |
var collapsible = $(".collapsed,.expanded"); |
Lines 256-283
$( document ).ready( function () {
Link Here
|
256 |
}).appendTo("#prefModalForm"); |
295 |
}).appendTo("#prefModalForm"); |
257 |
}); |
296 |
}); |
258 |
$("#saveModalPrefs").data("target", this.id ); |
297 |
$("#saveModalPrefs").data("target", this.id ); |
|
|
298 |
$("#saveModalPrefs").data("type", "modalselect" ); |
259 |
$("#prefModalLabel").text( pref_name ); |
299 |
$("#prefModalLabel").text( pref_name ); |
260 |
$("#prefModal").modal("show"); |
300 |
$("#prefModal").modal("show"); |
261 |
}); |
301 |
}); |
262 |
|
302 |
|
263 |
$(".modaljs").on("click", function () { |
303 |
// Initialise the content of our modal, using the function |
264 |
console.log('modaljs clicked'); |
304 |
// specified in the data-initiator attribute |
|
|
305 |
$('.modaljs').on('click', function () { |
306 |
const init = $(this).data('initiator'); |
307 |
if (init) { |
308 |
window[init](this); |
309 |
$("#prefModal").modal("show"); |
310 |
} |
265 |
}); |
311 |
}); |
266 |
|
312 |
|
267 |
$("#saveModalPrefs").on("click", function(){ |
313 |
// Initialise the content of our modal, if we are dealing |
268 |
var formfieldid = $("#" + $(this).data("target") ); |
314 |
// with a modalselect modal |
|
|
315 |
function prepareModalSelect(formfieldid) { |
269 |
var prefs = []; |
316 |
var prefs = []; |
270 |
$("#prefModal input[type='checkbox']").each(function(){ |
317 |
$("#prefModal input[type='checkbox']").each(function(){ |
271 |
if( $(this).prop("checked") ){ |
318 |
if( $(this).prop("checked") ){ |
272 |
prefs.push( this.value ); |
319 |
prefs.push( this.value ); |
273 |
} |
320 |
} |
274 |
}); |
321 |
}); |
|
|
322 |
return prefs.join("|"); |
323 |
} |
324 |
|
325 |
// Return a checkbox with an appropriate checked state |
326 |
function checkBox(id, className, state) { |
327 |
return state ? |
328 |
'<input id="' + id + '" type="checkbox" class="' + className + '" checked>' : |
329 |
'<input id="' + id + '" type="checkbox" class="' + className + '">'; |
330 |
} |
331 |
|
332 |
// Create a consentJS item, correctly populated |
333 |
function createConsentJSItem(item, idx) { |
334 |
const id = 'ConsentJS_' + idx; |
335 |
const code = item.code && item.code.length > 0 ? atob(item.code) : ''; |
336 |
const itemId = item.id && item.id.length > 0 ? item.id : ''; |
337 |
return '<div id="' + id + '" class="consentJSItem" data-id="' + itemId + '"><div class="consentRow"><div class="consentItem"><label class="required" for="name_' + id + '">' + __('Name') + ':</label><input id="name_' + id + '" class="metaName" type="text" value="' + item.name + '"><span class="required">' + __('Required') + '</span></div><div class="consentItem"><label class="required" for="description_' + id + '">' + __('Description') + ':</label><input id="description_' + id + '" class="metaDescription" type="text" value="' + item.description + '"><span class="required">' + __('Required') + '</span></div><div class="consentItem"><label for="opacConsent_' + id + '">' + __('Requires consent in OPAC') + ':</label>' + checkBox('opacConsent_' + id, 'opacConsent', item.opacConsent) + '</div><div class="consentItem"><label for="staffConsent_' + id + '">' + __('Requires consent in staff interface') + ':</label>' + checkBox('staffConsent_' + id, 'staffConsent', item.staffConsent) + '</div></div><div class="consentRow codeRow"><textarea style="display:none;" id="pref_' + id + '" class="preference preference-code codemirror" rows="10" cols="40">' + code + '</textarea><div><a id="expand_' + id + '" class="expand-textarea" data-target="' + id + '" data-syntax="javascript" href="#">' + __('Click to expand') + '</a><a id="collapse_' + id + '" class="collapse-textarea" data-target="' + id + '" data-syntax="javascript" href="#" style="display:none">' + __('Click to collapse') + '</a></div></div><a class="consentDelete" data-target="' + id + '" href="#">Delete</a></div>'; |
338 |
} |
339 |
|
340 |
// Return the markup for all consentJS items concatenated |
341 |
function populateConsentMarkup(items) { |
342 |
return items.reduce(function (acc, current, idx) { |
343 |
return acc + createConsentJSItem(current, idx); |
344 |
}, ''); |
345 |
} |
346 |
|
347 |
// Return the markup for a validation warning |
348 |
function populateValidationWarning() { |
349 |
return '<div id="consentJSWarning" class="error" style="display:none;">' + __('You must complete all fields') + '</div>'; |
350 |
} |
351 |
|
352 |
// Return a new, empty consent item |
353 |
function emptyConsentItem() { |
354 |
return { |
355 |
name: '', |
356 |
description: '', |
357 |
code: '', |
358 |
consentInOpac: false, |
359 |
consentInStaff: false |
360 |
}; |
361 |
} |
362 |
|
363 |
// Add the handler for a new empty consent item |
364 |
function addNewHandler() { |
365 |
$("#consentJSAddNew").on("click", function (e) { |
366 |
e.preventDefault(); |
367 |
const currentLen = $('.consentJSItem').length; |
368 |
const newItem = emptyConsentItem(); |
369 |
const markup = createConsentJSItem(newItem, currentLen); |
370 |
$('#prefModal .modal-body #consentJSItems').append($(markup)); |
371 |
addExpandHandler(); |
372 |
addCollapseHandler(); |
373 |
addConsentDeleteHandler(); |
374 |
}); |
375 |
} |
376 |
|
377 |
// Populate the consentJS modal, we also initialise any |
378 |
// event handlers that are required. This function is added |
379 |
// to the window object so we can call it if we are passed it's name |
380 |
// as a data-initiator attribute |
381 |
// (e.g.) |
382 |
// const f = 'populateConsentJS'; |
383 |
// window[f](); |
384 |
window.populateConsentJS = function(el) { |
385 |
let items = []; |
386 |
let decoded = ''; |
387 |
if (el.value && el.value.length > 0) { |
388 |
try { |
389 |
decoded = atob(el.value); |
390 |
} catch (err) { |
391 |
throw (__( |
392 |
'Unable to Base64 decode value stored in ConsentJS syspref: ' + |
393 |
err.message |
394 |
)); |
395 |
} |
396 |
try { |
397 |
items = JSON.parse(decoded); |
398 |
} catch (err) { |
399 |
throw (__( |
400 |
'Unable to JSON parse decoded value stored in ConsentJS syspref: ' + |
401 |
err.message |
402 |
)); |
403 |
} |
404 |
} |
405 |
const markup = populateConsentMarkup(items); |
406 |
const validationWarning = populateValidationWarning(); |
407 |
const pref_name = el.id.replace(/pref_/, ''); |
408 |
$('#saveModalPrefs').data('target', el.id); |
409 |
$('#prefModalLabel').text( pref_name ); |
410 |
$('#prefModal .modal-body').html($('<div id="consentJSItems">' + validationWarning + markup + '</div><div><a href="#" id="consentJSAddNew">' + __('Add new code') + '</a></div>')); |
411 |
addExpandHandler(); |
412 |
addCollapseHandler(); |
413 |
addNewHandler(); |
414 |
addConsentDeleteHandler(); |
415 |
} |
416 |
|
417 |
// Prepare the data in the UI for sending back as a syspref. |
418 |
// We validate that everything is what we expect. This function is added |
419 |
// to the window object so we can call it if we are passed it's name |
420 |
// as a data-initiator attribute |
421 |
// e.g. |
422 |
// const f = 'prepareConsentJS'; |
423 |
// window[f](); |
424 |
window.prepareConsentJS = function () { |
425 |
const items = $('.consentJSItem'); |
426 |
const invalid = []; |
427 |
const valid = []; |
428 |
items.each(function () { |
429 |
const id = $(this).data('id').length > 0 ? |
430 |
$(this).data('id') : |
431 |
'_' + Math.random().toString(36).substr(2, 9); |
432 |
const name = $(this).find('.metaName').val(); |
433 |
const desc = $(this).find('.metaDescription').val(); |
434 |
const opacConsent = $(this).find('.opacConsent').is(':checked') |
435 |
const staffConsent = $(this).find('.staffConsent').is(':checked'); |
436 |
const code = $(this).find('.preference-code').val(); |
437 |
// If the name, description and code are empty, then they've |
438 |
// added a new entry, but not filled it in, we can skip it |
439 |
if (name.length === 0 && desc.length === 0 && code.length === 0) { |
440 |
return; |
441 |
} |
442 |
// They've filled in at least some info |
443 |
if ( |
444 |
(name.length === 0) || |
445 |
(desc.length === 0) || |
446 |
(code.length === 0) |
447 |
) { |
448 |
invalid.push(this); |
449 |
} else { |
450 |
const obj = { |
451 |
id: id, |
452 |
name: name, |
453 |
description: desc, |
454 |
opacConsent: opacConsent, |
455 |
staffConsent: staffConsent, |
456 |
code: btoa(code) |
457 |
} |
458 |
valid.push(obj); |
459 |
} |
460 |
}); |
461 |
// We failed validation |
462 |
if (invalid.length > 0) { |
463 |
$('#consentJSWarning').show(); |
464 |
return false; |
465 |
} |
466 |
$('#consentJSWarning').hide(); |
467 |
if (valid.length === 0) { |
468 |
return ''; |
469 |
} |
470 |
const json = JSON.stringify(valid); |
471 |
const base64 = btoa(json); |
472 |
return base64; |
473 |
} |
275 |
|
474 |
|
276 |
formfieldid.val( prefs.join("|") ) |
475 |
$("#saveModalPrefs").on("click", function(){ |
277 |
.addClass("modified"); |
476 |
var formfieldid = $("#" + $(this).data("target")); |
278 |
mark_modified.call( formfieldid ); |
477 |
let finalString = ""; |
279 |
KOHA.Preferences.Save( formfieldid.closest("form") ); |
478 |
if ($(this).data("type") == "modalselect") { |
280 |
$("#prefModal").modal("hide"); |
479 |
finalString = prepareModalSelect(formfieldid); |
|
|
480 |
} else { |
481 |
const processor = $(".modaljs").data("processor"); |
482 |
finalString = window[processor](); |
483 |
} |
484 |
// A processor can return false if any of the submitted |
485 |
// data has failed validation |
486 |
if (finalString !== false) { |
487 |
formfieldid.val(finalString).addClass("modified"); |
488 |
mark_modified.call( formfieldid ); |
489 |
KOHA.Preferences.Save( formfieldid.closest("form") ); |
490 |
$("#prefModal").modal("hide"); |
491 |
} |
281 |
}); |
492 |
}); |
282 |
|
493 |
|
283 |
$("#prefModal").on("hide.bs.modal", function(){ |
494 |
$("#prefModal").on("hide.bs.modal", function(){ |
284 |
- |
|
|