View | Details | Raw Unified | Return to bug 34655
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js (-257 / +447 lines)
Lines 1-14 Link Here
1
/* keep tidy */
1
/* global KOHA CodeMirror to_highlight search_jumped humanMsg dataTablesDefaults themelang */
2
/* global KOHA CodeMirror to_highlight search_jumped humanMsg dataTablesDefaults themelang */
2
// We can assume 'KOHA' exists, as we depend on KOHA.AJAX
3
// We can assume 'KOHA' exists, as we depend on KOHA.AJAX
3
4
4
KOHA.Preferences = {
5
KOHA.Preferences = {
5
    Save: function ( form ) {
6
    Save: function (form) {
6
        if ( ! $(form).valid() ) {
7
        if (!$(form).valid()) {
7
            humanMsg.displayAlert( __("Error: presence of invalid data prevent saving. Please make the corrections and try again.") );
8
            humanMsg.displayAlert(
9
                __(
10
                    "Error: presence of invalid data prevent saving. Please make the corrections and try again."
11
                )
12
            );
8
            return;
13
            return;
9
        }
14
        }
10
15
11
        let sysprefs = $(form).find('.modified').not('.preference-checkbox').toArray().reduce((map, e) => ({ ...map, [$(e).attr('name')]: [$(e).val()].flat()}), {});
16
        let sysprefs = $(form)
17
            .find(".modified")
18
            .not(".preference-checkbox")
19
            .toArray()
20
            .reduce(
21
                (map, e) => ({
22
                    ...map,
23
                    [$(e).attr("name")]: [$(e).val()].flat(),
24
                }),
25
                {}
26
            );
12
27
13
        // checkbox prefs
28
        // checkbox prefs
14
        let modified_boxes = $(form).find(".modified.preference-checkbox");
29
        let modified_boxes = $(form).find(".modified.preference-checkbox");
Lines 29-79 KOHA.Preferences = { Link Here
29
            }
44
            }
30
        }
45
        }
31
46
32
        if ( !Object.keys(sysprefs).length ) {
47
        if (!Object.keys(sysprefs).length) {
33
            humanMsg.displayAlert( __("Nothing to save") );
48
            humanMsg.displayAlert(__("Nothing to save"));
34
            return;
49
            return;
35
        }
50
        }
36
        KOHA.AJAX.MarkRunning($(form).find('.save-all'), __("Saving...") );
51
        KOHA.AJAX.MarkRunning($(form).find(".save-all"), __("Saving..."));
37
        const client = APIClient.syspref;
52
        const client = APIClient.syspref;
38
        client.sysprefs.update_all(sysprefs).then(
53
        client.sysprefs
39
            success => {
54
            .update_all(sysprefs)
40
                KOHA.Preferences.Success( form );
55
            .then(
41
            },
56
                success => {
42
            error => {
57
                    KOHA.Preferences.Success(form);
43
                 console.warn("Something wrong happened: %s".format(error));
58
                },
44
            }
59
                error => {
45
        ).then(() => {
60
                    console.warn("Something wrong happened: %s".format(error));
46
            KOHA.AJAX.MarkDone( $( form ).find( '.save-all' ) );
61
                }
47
        });
62
            )
48
63
            .then(() => {
64
                KOHA.AJAX.MarkDone($(form).find(".save-all"));
65
            });
49
    },
66
    },
50
    Success: function ( form ) {
67
    Success: function (form) {
51
        var msg = "";
68
        var msg = "";
52
        $(form).find('.modified').each(function(){
69
        $(form)
53
            var modified_pref = $(this).attr("id");
70
            .find(".modified")
54
            modified_pref = modified_pref.replace("pref_","");
71
            .each(function () {
55
            msg += "<strong>" + __("Saved preference %s").format(modified_pref) + "</strong>\n";
72
                var modified_pref = $(this).attr("id");
56
        });
73
                modified_pref = modified_pref.replace("pref_", "");
74
                msg +=
75
                    "<strong>" +
76
                    __("Saved preference %s").format(modified_pref) +
77
                    "</strong>\n";
78
            });
57
        humanMsg.displayAlert(msg);
79
        humanMsg.displayAlert(msg);
58
80
59
        $( form )
81
        $(form)
60
            .find( '.modified-warning' ).remove().end()
82
            .find(".modified-warning")
61
            .find( '.modified' ).removeClass('modified');
83
            .remove()
84
            .end()
85
            .find(".modified")
86
            .removeClass("modified");
62
        KOHA.Preferences.Modified = false;
87
        KOHA.Preferences.Modified = false;
63
    }
88
    },
64
};
89
};
65
90
66
function mark_modified() {
91
function mark_modified() {
67
    $( this.form ).find( '.save-all' ).prop('disabled', false);
92
    $(this.form).find(".save-all").prop("disabled", false);
68
    $( this ).addClass( 'modified' );
93
    $(this).addClass("modified");
69
    var name_cell = $( this ).parents( '.name-row' ).find( '.name-cell' );
94
    var name_cell = $(this).parents(".name-row").find(".name-cell");
70
    if ( !name_cell.find( '.modified-warning' ).length )
95
    if (!name_cell.find(".modified-warning").length)
71
        name_cell.append('<em class="modified-warning">(' + __("modified") + ')</em>');
96
        name_cell.append(
97
            '<em class="modified-warning">(' + __("modified") + ")</em>"
98
        );
72
    KOHA.Preferences.Modified = true;
99
    KOHA.Preferences.Modified = true;
73
}
100
}
74
101
75
window.onbeforeunload = function () {
102
window.onbeforeunload = function () {
76
    if ( KOHA.Preferences.Modified ) {
103
    if (KOHA.Preferences.Modified) {
77
        return __("You have made changes to system preferences.");
104
        return __("You have made changes to system preferences.");
78
    }
105
    }
79
};
106
};
Lines 81-92 window.onbeforeunload = function () { Link Here
81
// Add event handlers to any elements with .expand-textarea classes
108
// Add event handlers to any elements with .expand-textarea classes
82
// this allows the CodeMirror widget to be displayed
109
// this allows the CodeMirror widget to be displayed
83
function addExpandHandler() {
110
function addExpandHandler() {
84
    const textAreas = $('.expand-textarea').map(function() {
111
    const textAreas = $(".expand-textarea")
85
        return this
112
        .map(function () {
86
    }).get();
113
            return this;
87
    textAreas.forEach((expandTextArea) => {
114
        })
115
        .get();
116
    textAreas.forEach(expandTextArea => {
88
        // Don't duplicate click event handlers
117
        // Don't duplicate click event handlers
89
        const ev = $._data($(expandTextArea).get(0), 'events');
118
        const ev = $._data($(expandTextArea).get(0), "events");
90
        if (ev && ev.click) {
119
        if (ev && ev.click) {
91
            return;
120
            return;
92
        }
121
        }
Lines 96-112 function addExpandHandler() { Link Here
96
            $(this).hide();
125
            $(this).hide();
97
            var target = $(this).data("target");
126
            var target = $(this).data("target");
98
            var syntax = $(this).data("syntax");
127
            var syntax = $(this).data("syntax");
99
            var lint_type = syntax === 'javascript'? { 'esversion': 6 } : true;
128
            var lint_type = syntax === "javascript" ? { esversion: 6 } : true;
100
            $("#collapse_" + target).show();
129
            $("#collapse_" + target).show();
101
            if (syntax) {
130
            if (syntax) {
102
                var editor = CodeMirror.fromTextArea(document.getElementById("pref_" + target), {
131
                var editor = CodeMirror.fromTextArea(
103
                    lineNumbers: true,
132
                    document.getElementById("pref_" + target),
104
                    mode: syntax,
133
                    {
105
                    lineWrapping: true,
134
                        lineNumbers: true,
106
                    viewportMargin: Infinity,
135
                        mode: syntax,
107
                    gutters: ["CodeMirror-lint-markers"],
136
                        lineWrapping: true,
108
                    lint: lint_type,
137
                        viewportMargin: Infinity,
109
                });
138
                        gutters: ["CodeMirror-lint-markers"],
139
                        lint: lint_type,
140
                    }
141
                );
110
                editor.on("change", function () {
142
                editor.on("change", function () {
111
                    mark_modified.call($("#pref_" + target)[0]);
143
                    mark_modified.call($("#pref_" + target)[0]);
112
                });
144
                });
Lines 117-134 function addExpandHandler() { Link Here
117
                $("#pref_" + target).show();
149
                $("#pref_" + target).show();
118
            }
150
            }
119
        });
151
        });
120
    })
152
    });
121
}
153
}
122
154
123
// Add event handlers to any elements with .collapse-textarea classes
155
// Add event handlers to any elements with .collapse-textarea classes
124
// this allows the hiding of the CodeMirror widget
156
// this allows the hiding of the CodeMirror widget
125
function addCollapseHandler() {
157
function addCollapseHandler() {
126
    const textAreas = $('.collapse-textarea').map(function() {
158
    const textAreas = $(".collapse-textarea")
127
        return this
159
        .map(function () {
128
    }).get();
160
            return this;
129
    textAreas.forEach((collapseTextArea) => {
161
        })
162
        .get();
163
    textAreas.forEach(collapseTextArea => {
130
        // Don't duplicate click event handlers
164
        // Don't duplicate click event handlers
131
        const ev = $._data($(collapseTextArea).get(0), 'events');
165
        const ev = $._data($(collapseTextArea).get(0), "events");
132
        if (ev && ev.click) {
166
        if (ev && ev.click) {
133
            return;
167
            return;
134
        }
168
        }
Lines 139-218 function addCollapseHandler() { Link Here
139
            var syntax = $(this).data("syntax");
173
            var syntax = $(this).data("syntax");
140
            $("#expand_" + target).show();
174
            $("#expand_" + target).show();
141
            if (syntax) {
175
            if (syntax) {
142
                var editor = $("#pref_" + target).next(".CodeMirror")[0].CodeMirror;
176
                var editor = $("#pref_" + target).next(".CodeMirror")[0]
177
                    .CodeMirror;
143
                editor.toTextArea();
178
                editor.toTextArea();
144
            }
179
            }
145
            $("#pref_" + target).hide();
180
            $("#pref_" + target).hide();
146
        });
181
        });
147
    })
182
    });
148
}
183
}
149
184
150
// Add a handler for any consent delete links
185
// Add a handler for any consent delete links
151
function addConsentDeleteHandler() {
186
function addConsentDeleteHandler() {
152
    const deleteButtons = $('.consentDelete').map(function() {
187
    const deleteButtons = $(".consentDelete")
153
        return this
188
        .map(function () {
154
    }).get();
189
            return this;
155
    deleteButtons.forEach((deleteButton) => {
190
        })
191
        .get();
192
    deleteButtons.forEach(deleteButton => {
156
        // Don't duplicate click event handlers
193
        // Don't duplicate click event handlers
157
        const ev = $._data($(deleteButton).get(0), 'events');
194
        const ev = $._data($(deleteButton).get(0), "events");
158
        if (ev && ev.click) {
195
        if (ev && ev.click) {
159
            return;
196
            return;
160
        }
197
        }
161
        $(deleteButton).on('click', function (e) {
198
        $(deleteButton).on("click", function (e) {
162
            e.preventDefault();
199
            e.preventDefault();
163
            const target = $(this).data('target');
200
            const target = $(this).data("target");
164
            const proceed = confirm(__('Are you sure you want to delete this consent item?'));
201
            const proceed = confirm(
202
                __("Are you sure you want to delete this consent item?")
203
            );
165
            if (proceed) {
204
            if (proceed) {
166
                $('#' + target).remove();
205
                $("#" + target).remove();
167
            }
206
            }
168
        });
207
        });
169
    })
208
    });
170
}
209
}
171
210
172
$("table.preferences").dataTable($.extend(true, {}, dataTablesDefaults, {
211
$("table.preferences").dataTable(
173
    "dom":  't',
212
    $.extend(true, {}, dataTablesDefaults, {
174
    "columnDefs":  [
213
        dom: "t",
175
        { "targets":  [ -1 ], "orderable":  false, "searchable":  false }
214
        columnDefs: [{ targets: [-1], orderable: false, searchable: false }],
176
    ],
215
        paging: false,
177
    "paging":  false
216
    })
178
}));
217
);
179
218
180
$( '.prefs-tab' )
219
$(".prefs-tab")
181
    .find( 'input.preference, textarea.preference' ).on('input', function () {
220
    .find("input.preference, textarea.preference")
182
        if ( this.defaultValue === undefined || this.value != this.defaultValue ) mark_modified.call( this );
221
    .on("input", function () {
183
    } ).end()
222
        if (this.defaultValue === undefined || this.value != this.defaultValue)
184
    .find( 'select.preference' ).change( mark_modified );
223
            mark_modified.call(this);
185
$('.preference-checkbox').change( function () {
224
    })
186
    $('.preference-checkbox').addClass('modified');
225
    .end()
226
    .find("select.preference")
227
    .change(mark_modified);
228
$(".preference-checkbox").change(function () {
229
    $(".preference-checkbox").addClass("modified");
187
    mark_modified.call(this);
230
    mark_modified.call(this);
188
} );
231
});
189
232
190
$(".set_syspref").click(function() {
233
$(".set_syspref").click(function () {
191
    var s = $(this).attr('data-syspref');
234
    var s = $(this).attr("data-syspref");
192
    var v = $(this).attr('data-value');
235
    var v = $(this).attr("data-value");
193
    // populate the input with the value in data-value
236
    // populate the input with the value in data-value
194
    $("#pref_"+s).val(v);
237
    $("#pref_" + s).val(v);
195
    // pass the DOM element to trigger "modified" to enable submit button
238
    // pass the DOM element to trigger "modified" to enable submit button
196
    mark_modified.call($("#pref_"+s)[0]);
239
    mark_modified.call($("#pref_" + s)[0]);
197
    return false;
240
    return false;
198
});
241
});
199
242
200
$(".sortable").each( (i, e) => {
243
$(".sortable").each((i, e) => {
201
    Sortable.create(e, {
244
    Sortable.create(e, {
202
        animation: 150,
245
        animation: 150,
203
        onUpdate: function( e ){
246
        onUpdate: function (e) {
204
            $(e.target).find('input:first').change();
247
            $(e.target).find("input:first").change();
205
        }
248
        },
206
    });
249
    });
207
});
250
});
208
251
209
$( '.prefs-tab .action .cancel' ).click( function () { KOHA.Preferences.Modified = false } );
252
$(".prefs-tab .action .cancel").click(function () {
210
253
    KOHA.Preferences.Modified = false;
211
$( '.prefs-tab .save-all' ).prop('disabled', true).click( function () {
212
    KOHA.Preferences.Save( this.form );
213
    return false;
214
});
254
});
215
255
256
$(".prefs-tab .save-all")
257
    .prop("disabled", true)
258
    .click(function () {
259
        KOHA.Preferences.Save(this.form);
260
        return false;
261
    });
262
216
addExpandHandler();
263
addExpandHandler();
217
264
218
addCollapseHandler();
265
addCollapseHandler();
Lines 220-305 addCollapseHandler(); Link Here
220
$("h3").attr("class", "expanded").attr("title", __("Collapse this section"));
267
$("h3").attr("class", "expanded").attr("title", __("Collapse this section"));
221
var collapsible = $(".collapsed,.expanded");
268
var collapsible = $(".collapsed,.expanded");
222
269
223
$(collapsible).on("click",function(){
270
$(collapsible).on("click", function () {
224
    var h3Id = $(this).attr("id");
271
    var h3Id = $(this).attr("id");
225
    var panel = $("#collapse_" + h3Id);
272
    var panel = $("#collapse_" + h3Id);
226
    if(panel.is(":visible")){
273
    if (panel.is(":visible")) {
227
        $(this).addClass("collapsed").removeClass("expanded").attr("title", __("Expand this section") );
274
        $(this)
275
            .addClass("collapsed")
276
            .removeClass("expanded")
277
            .attr("title", __("Expand this section"));
228
        panel.hide();
278
        panel.hide();
229
    } else {
279
    } else {
230
        $(this).addClass("expanded").removeClass("collapsed").attr("title", __("Collapse this section") );
280
        $(this)
281
            .addClass("expanded")
282
            .removeClass("collapsed")
283
            .attr("title", __("Collapse this section"));
231
        panel.show();
284
        panel.show();
232
    }
285
    }
233
});
286
});
234
287
235
$(".pref_sublink").on("click", function(){
288
$(".pref_sublink").on("click", function () {
236
    /* If the user clicks a sub-menu link in the sidebar,
289
    /* If the user clicks a sub-menu link in the sidebar,
237
       check to see if it is collapsed. If so, expand it */
290
       check to see if it is collapsed. If so, expand it */
238
    var href = $(this).attr("href");
291
    var href = $(this).attr("href");
239
    href = href.replace("#","");
292
    href = href.replace("#", "");
240
    var panel = $("#collapse_" + href );
293
    var panel = $("#collapse_" + href);
241
    if( panel.is(":hidden") ){
294
    if (panel.is(":hidden")) {
242
        $("#" + href).addClass("expanded").removeClass("collapsed").attr("title", __("Collapse this section") );
295
        $("#" + href)
296
            .addClass("expanded")
297
            .removeClass("collapsed")
298
            .attr("title", __("Collapse this section"));
243
        panel.show();
299
        panel.show();
244
    }
300
    }
245
});
301
});
246
302
247
if ( to_highlight ) {
303
if (to_highlight) {
248
    var words = to_highlight.split( ' ' );
304
    var words = to_highlight.split(" ");
249
    $( '.prefs-tab table' ).find( 'td, th' ).not( '.name-cell' ).each( function ( i, td ) {
305
    $(".prefs-tab table")
250
        $.each( words, function ( i, word ) { $( td ).highlight( word ) } );
306
        .find("td, th")
251
    } ).find( 'option, textarea' ).removeHighlight();
307
        .not(".name-cell")
308
        .each(function (i, td) {
309
            $.each(words, function (i, word) {
310
                $(td).highlight(word);
311
            });
312
        })
313
        .find("option, textarea")
314
        .removeHighlight();
252
}
315
}
253
316
254
if ( search_jumped ) {
317
if (search_jumped) {
255
    document.location.hash = "jumped";
318
    document.location.hash = "jumped";
256
}
319
}
257
320
258
$("#pref_UpdateItemLocationOnCheckin, #pref_UpdateItemLocationOnCheckout").change(function(){
321
$(
322
    "#pref_UpdateItemLocationOnCheckin, #pref_UpdateItemLocationOnCheckout"
323
).change(function () {
259
    var the_text = $(this).val();
324
    var the_text = $(this).val();
260
    var alert_text = '';
325
    var alert_text = "";
261
    if (the_text.indexOf('_ALL_:') != -1) alert_text = __("Note: _ALL_ value will override all other values") + '\n';
326
    if (the_text.indexOf("_ALL_:") != -1)
262
    var split_text  =the_text.split("\n");
327
        alert_text =
263
    var alert_issues = '';
328
            __("Note: _ALL_ value will override all other values") + "\n";
329
    var split_text = the_text.split("\n");
330
    var alert_issues = "";
264
    var issue_count = 0;
331
    var issue_count = 0;
265
    var reg_check = /.*:\s.*/;
332
    var reg_check = /.*:\s.*/;
266
    for (var i=0; i < split_text.length; i++){
333
    for (var i = 0; i < split_text.length; i++) {
267
        if ( !split_text[i].match(reg_check) && split_text[i].length ) {
334
        if (!split_text[i].match(reg_check) && split_text[i].length) {
268
            alert_issues+=split_text[i]+"\n";
335
            alert_issues += split_text[i] + "\n";
269
            issue_count++;
336
            issue_count++;
270
        }
337
        }
271
    }
338
    }
272
    if (issue_count) alert_text += "\n" + __("The following values are not formatted correctly:") + "\n" + alert_issues;
339
    if (issue_count)
273
    if ( alert_text.length )  alert(alert_text);
340
        alert_text +=
341
            "\n" +
342
            __("The following values are not formatted correctly:") +
343
            "\n" +
344
            alert_issues;
345
    if (alert_text.length) alert(alert_text);
274
});
346
});
275
347
276
$(".prefs-tab form").each(function () {
348
$(".prefs-tab form").each(function () {
277
    $(this).validate({
349
    $(this).validate({
278
        rules: { },
350
        rules: {},
279
        errorPlacement: function(error, element) {
351
        errorPlacement: function (error, element) {
280
            var placement = $(element).parent();
352
            var placement = $(element).parent();
281
            if (placement) {
353
            if (placement) {
282
                $(placement).append(error)
354
                $(placement).append(error);
283
            } else {
355
            } else {
284
                error.insertAfter(element);
356
                error.insertAfter(element);
285
            }
357
            }
286
        }
358
        },
287
    });
359
    });
288
});
360
});
289
361
290
$(".preference-email").each(function() {
362
$(".preference-email").each(function () {
291
    $(this).rules("add", {
363
    $(this).rules("add", {
292
        email: true
364
        email: true,
293
    });
365
    });
294
});
366
});
295
367
296
368
$(".modalselect").on("click", function () {
297
$(".modalselect").on("click", function(){
298
    var datasource = $(this).data("source");
369
    var datasource = $(this).data("source");
299
    var exclusions = $(this).data("exclusions").split('|');
370
    var exclusions = $(this).data("exclusions").split("|");
300
    var inclusions = $(this).data("inclusions").split('|');
371
    var inclusions = $(this).data("inclusions").split("|");
301
    var required = $(this).data("required").split('|');
372
    var required = $(this).data("required").split("|");
302
    var pref_name = this.id.replace(/pref_/, '');
373
    var pref_name = this.id.replace(/pref_/, "");
303
    var pref_value = this.value;
374
    var pref_value = this.value;
304
    var prefs = pref_value.split("|");
375
    var prefs = pref_value.split("|");
305
376
Lines 309-353 $(".modalselect").on("click", function(){ Link Here
309
    var readonly = "";
380
    var readonly = "";
310
    var disabled = "";
381
    var disabled = "";
311
    var style = "";
382
    var style = "";
312
    $.each( Object.keys(data).sort(), function( i, key ){
383
    $.each(Object.keys(data).sort(), function (i, key) {
313
        if( prefs.indexOf( key ) >= 0 ){
384
        if (prefs.indexOf(key) >= 0) {
314
            checked = ' checked="checked" ';
385
            checked = ' checked="checked" ';
315
        } else {
386
        } else {
316
            checked = "";
387
            checked = "";
317
        }
388
        }
318
        if( required.indexOf( key ) >= 0 ){
389
        if (required.indexOf(key) >= 0) {
319
            style = "required";
390
            style = "required";
320
            checked  = ' checked="checked" ';
391
            checked = ' checked="checked" ';
321
        } else if( exclusions.indexOf( key ) >= 0 ){
392
        } else if (exclusions.indexOf(key) >= 0) {
322
            style = "disabled";
393
            style = "disabled";
323
            disabled = ' disabled="disabled" ';
394
            disabled = ' disabled="disabled" ';
324
            checked  = "";
395
            checked = "";
325
        } else if( inclusions.indexOf( key ) >= 0 ){
396
        } else if (inclusions.indexOf(key) >= 0) {
326
            style = "disabled";
397
            style = "disabled";
327
            disabled = ' disabled="disabled" ';
398
            disabled = ' disabled="disabled" ';
328
            checked  = ' checked="checked" ';
399
            checked = ' checked="checked" ';
329
        } else {
400
        } else {
330
            style = "";
401
            style = "";
331
            disabled = "";
402
            disabled = "";
332
        }
403
        }
333
404
334
        items.push('<label class="' + style +'"><input class="dbcolumn_selection" type="checkbox" id="' + key + '"' + checked + disabled + ' name="pref" value="' + key + '" /> ' + data[key]+ ' (' + key + ')</label>');
405
        items.push(
406
            '<label class="' +
407
                style +
408
                '"><input class="dbcolumn_selection" type="checkbox" id="' +
409
                key +
410
                '"' +
411
                checked +
412
                disabled +
413
                ' name="pref" value="' +
414
                key +
415
                '" /> ' +
416
                data[key] +
417
                " (" +
418
                key +
419
                ")</label>"
420
        );
335
    });
421
    });
336
    $("<div/>", {
422
    $("<div/>", {
337
        "class": "columns-2",
423
        class: "columns-2",
338
        html: items.join("")
424
        html: items.join(""),
339
    }).appendTo("#prefModalBody");
425
    }).appendTo("#prefModalBody");
340
426
341
    $("#saveModalPrefs").data("target", this.id );
427
    $("#saveModalPrefs").data("target", this.id);
342
    $("#saveModalPrefs").data("type", "modalselect" );
428
    $("#saveModalPrefs").data("type", "modalselect");
343
    $("#prefModalLabel").text( pref_name );
429
    $("#prefModalLabel").text(pref_name);
344
    $("#prefModal").modal("show");
430
    $("#prefModal").modal("show");
345
});
431
});
346
432
347
// Initialise the content of our modal, using the function
433
// Initialise the content of our modal, using the function
348
// specified in the data-initiator attribute
434
// specified in the data-initiator attribute
349
$('.modaljs').on('click', function () {
435
$(".modaljs").on("click", function () {
350
    const init = $(this).data('initiator');
436
    const init = $(this).data("initiator");
351
    if (init) {
437
    if (init) {
352
        window[init](this);
438
        window[init](this);
353
        $("#prefModal").modal("show");
439
        $("#prefModal").modal("show");
Lines 358-366 $('.modaljs').on('click', function () { Link Here
358
// with a modalselect modal
444
// with a modalselect modal
359
function prepareModalSelect(formfieldid) {
445
function prepareModalSelect(formfieldid) {
360
    var prefs = [];
446
    var prefs = [];
361
    $("#prefModal input[type='checkbox']").each(function(){
447
    $("#prefModal input[type='checkbox']").each(function () {
362
        if( $(this).prop("checked") ){
448
        if ($(this).prop("checked")) {
363
            prefs.push( this.value );
449
            prefs.push(this.value);
364
        }
450
        }
365
    });
451
    });
366
    return prefs.join("|");
452
    return prefs.join("|");
Lines 368-448 function prepareModalSelect(formfieldid) { Link Here
368
454
369
// Return a checkbox with an appropriate checked state
455
// Return a checkbox with an appropriate checked state
370
function checkBox(id, className, state) {
456
function checkBox(id, className, state) {
371
    return state ?
457
    return state
372
        '<input id="' + id + '" type="checkbox" class="' + className + '" checked>' :
458
        ? '<input id="' +
373
        '<input id="' + id + '" type="checkbox" class="' + className + '">';
459
              id +
460
              '" type="checkbox" class="' +
461
              className +
462
              '" checked>'
463
        : '<input id="' + id + '" type="checkbox" class="' + className + '">';
374
}
464
}
375
465
376
// Create a cookieConsentedJS item, correctly populated
466
// Create a cookieConsentedJS item, correctly populated
377
function createCookieConsentedJSItem(item, idx) {
467
function createCookieConsentedJSItem(item, idx) {
378
    const id = 'CookieConsentedJS_' + idx;
468
    const id = "CookieConsentedJS_" + idx;
379
    const code = item.code && item.code.length > 0 ? atob(item.code) : '';
469
    const code = item.code && item.code.length > 0 ? atob(item.code) : "";
380
    const itemId = item.id && item.id.length > 0 ? item.id : '';
470
    const itemId = item.id && item.id.length > 0 ? item.id : "";
381
    return '<div id="' + id + '" class="cookieConsentedJSItem" data-id="' + itemId + '">' +
471
    return (
382
           '    <div class="consentRow">' +
472
        '<div id="' +
383
           '        <div class="consentItem">' +
473
        id +
384
           '            <label class="required" for="name_' + id + '">' + __('Name') + ':</label>' +
474
        '" class="cookieConsentedJSItem" data-id="' +
385
           '            <input id="name_' + id + '" class="metaName" type="text" value="' + item.name + '"><span class="required">' + __('Required') + '</span>' +
475
        itemId +
386
           '        </div >' +
476
        '">' +
387
           '        <div class="consentItem">' +
477
        '    <div class="consentRow">' +
388
           '            <label class="required" for="description_' + id + '">' + __('Description') + ':</label>' +
478
        '        <div class="consentItem">' +
389
           '            <input id="description_' + id + '" class="metaDescription" type="text" value="' + item.description + '"><span class="required">' + __('Required') + '</span>' +
479
        '            <label class="required" for="name_' +
390
           '        </div>' +
480
        id +
391
           '        <div class="consentItem">' +
481
        '">' +
392
           '            <label for="opacConsent_' + id + '">' + __('Requires consent in OPAC') + ':</label>' +
482
        __("Name") +
393
                        checkBox('opacConsent_' + id, 'opacConsent', item.opacConsent) +
483
        ":</label>" +
394
           '        </div>' +
484
        '            <input id="name_' +
395
           '        <div class="consentItem">' +
485
        id +
396
           '            <label for="staffConsent_' + id + '">' + __('Requires consent in staff interface') + ':</label>' +
486
        '" class="metaName" type="text" value="' +
397
                        checkBox('staffConsent_' + id, 'staffConsent', item.staffConsent) +
487
        item.name +
398
           '        </div >' +
488
        '"><span class="required">' +
399
           '        <div class="consentItem">' +
489
        __("Required") +
400
           '            <label for="matchPattern_' + id + '">' + __('String used to identify cookie name') + ':</label>' +
490
        "</span>" +
401
           '            <input id="matchPattern_' + id + '" class="metaMatchPattern" type="text" value="' + item.matchPattern + '"><span class="required">' + __('Required') + '</span>' +
491
        "        </div >" +
402
           '        </div >' +
492
        '        <div class="consentItem">' +
403
           '        <div class="consentItem">' +
493
        '            <label class="required" for="description_' +
404
           '            <label for="cookieDomain' + id + '">' + __('Cookie domain') + ':</label>' +
494
        id +
405
           '            <input id="cookieDomain' + id + '" class="metaCookieDomain" type="text" value="' + item.cookieDomain + '"><span class="required">' + __('Required') + '</span>' +
495
        '">' +
406
           '        </div >' +
496
        __("Description") +
407
           '        <div class="consentItem">' +
497
        ":</label>" +
408
           '            <label for="cookiePath' + id + '">' + __('Cookie path') + ':</label>' +
498
        '            <input id="description_' +
409
           '            <input id="cookiePath' + id + '" class="metaCookiePath" type="text" value="' + item.cookiePath + '"><span class="required">' + __('Required') + '</span>' +
499
        id +
410
           '        </div >' +
500
        '" class="metaDescription" type="text" value="' +
411
           '    </div >' +
501
        item.description +
412
           '    <div class="consentRow codeRow">' +
502
        '"><span class="required">' +
413
           '        <textarea style="display:none;" id="pref_' + id + '" class="preference preference-code codemirror" rows="10" cols="40">' + code + '</textarea>' +
503
        __("Required") +
414
           '        <div>' +
504
        "</span>" +
415
           '            <a id="expand_' + id + '" class="expand-textarea" data-target="' + id + '" data-syntax="javascript" href="#">' + __('Expand') + '</a>' +
505
        "        </div>" +
416
           '            <a id="collapse_' + id + '" class="collapse-textarea" data-target="' + id + '" data-syntax="javascript" href="#" style="display:none">' + __('Collapse') + '</a>' +
506
        '        <div class="consentItem">' +
417
           '        </div >' +
507
        '            <label for="opacConsent_' +
418
           '    </div>' +
508
        id +
419
           '    <a class="consentDelete" data-target="' + id + '" href="#">' + __('Delete') + '</a>' +
509
        '">' +
420
           '</div > ';
510
        __("Requires consent in OPAC") +
511
        ":</label>" +
512
        checkBox("opacConsent_" + id, "opacConsent", item.opacConsent) +
513
        "        </div>" +
514
        '        <div class="consentItem">' +
515
        '            <label for="staffConsent_' +
516
        id +
517
        '">' +
518
        __("Requires consent in staff interface") +
519
        ":</label>" +
520
        checkBox("staffConsent_" + id, "staffConsent", item.staffConsent) +
521
        "        </div >" +
522
        '        <div class="consentItem">' +
523
        '            <label for="matchPattern_' +
524
        id +
525
        '">' +
526
        __("String used to identify cookie name") +
527
        ":</label>" +
528
        '            <input id="matchPattern_' +
529
        id +
530
        '" class="metaMatchPattern" type="text" value="' +
531
        item.matchPattern +
532
        '"><span class="required">' +
533
        __("Required") +
534
        "</span>" +
535
        "        </div >" +
536
        '        <div class="consentItem">' +
537
        '            <label for="cookieDomain' +
538
        id +
539
        '">' +
540
        __("Cookie domain") +
541
        ":</label>" +
542
        '            <input id="cookieDomain' +
543
        id +
544
        '" class="metaCookieDomain" type="text" value="' +
545
        item.cookieDomain +
546
        '"><span class="required">' +
547
        __("Required") +
548
        "</span>" +
549
        "        </div >" +
550
        '        <div class="consentItem">' +
551
        '            <label for="cookiePath' +
552
        id +
553
        '">' +
554
        __("Cookie path") +
555
        ":</label>" +
556
        '            <input id="cookiePath' +
557
        id +
558
        '" class="metaCookiePath" type="text" value="' +
559
        item.cookiePath +
560
        '"><span class="required">' +
561
        __("Required") +
562
        "</span>" +
563
        "        </div >" +
564
        "    </div >" +
565
        '    <div class="consentRow codeRow">' +
566
        '        <textarea style="display:none;" id="pref_' +
567
        id +
568
        '" class="preference preference-code codemirror" rows="10" cols="40">' +
569
        code +
570
        "</textarea>" +
571
        "        <div>" +
572
        '            <a id="expand_' +
573
        id +
574
        '" class="expand-textarea" data-target="' +
575
        id +
576
        '" data-syntax="javascript" href="#">' +
577
        __("Expand") +
578
        "</a>" +
579
        '            <a id="collapse_' +
580
        id +
581
        '" class="collapse-textarea" data-target="' +
582
        id +
583
        '" data-syntax="javascript" href="#" style="display:none">' +
584
        __("Collapse") +
585
        "</a>" +
586
        "        </div >" +
587
        "    </div>" +
588
        '    <a class="consentDelete" data-target="' +
589
        id +
590
        '" href="#">' +
591
        __("Delete") +
592
        "</a>" +
593
        "</div > "
594
    );
421
}
595
}
422
596
423
// Return the markup for all cookieConsentedJS items concatenated
597
// Return the markup for all cookieConsentedJS items concatenated
424
function populateConsentMarkup(items) {
598
function populateConsentMarkup(items) {
425
    return items.reduce(function (acc, current, idx) {
599
    return items.reduce(function (acc, current, idx) {
426
        return acc + createCookieConsentedJSItem(current, idx);
600
        return acc + createCookieConsentedJSItem(current, idx);
427
    }, '');
601
    }, "");
428
}
602
}
429
603
430
// Return the markup for a validation warning
604
// Return the markup for a validation warning
431
function populateValidationWarning() {
605
function populateValidationWarning() {
432
    return '<div id="cookieConsentedJSWarning" class="error" style="display:none;">' + __('You must complete all fields') + '</div>';
606
    return (
607
        '<div id="cookieConsentedJSWarning" class="error" style="display:none;">' +
608
        __("You must complete all fields") +
609
        "</div>"
610
    );
433
}
611
}
434
612
435
// Return a new, empty consent item
613
// Return a new, empty consent item
436
function emptyConsentItem() {
614
function emptyConsentItem() {
437
    return {
615
    return {
438
        name: '',
616
        name: "",
439
        description: '',
617
        description: "",
440
        matchPattern: '',
618
        matchPattern: "",
441
        cookieDomain: '',
619
        cookieDomain: "",
442
        cookiePath: '',
620
        cookiePath: "",
443
        code: '',
621
        code: "",
444
        opacConsent: false,
622
        opacConsent: false,
445
        staffConsent: false
623
        staffConsent: false,
446
    };
624
    };
447
}
625
}
448
626
Lines 450-459 function emptyConsentItem() { Link Here
450
function addNewHandler() {
628
function addNewHandler() {
451
    $("#cookieConsentedJSAddNew").on("click", function (e) {
629
    $("#cookieConsentedJSAddNew").on("click", function (e) {
452
        e.preventDefault();
630
        e.preventDefault();
453
        const currentLen = $('.cookieConsentedJSItem').length;
631
        const currentLen = $(".cookieConsentedJSItem").length;
454
        const newItem = emptyConsentItem();
632
        const newItem = emptyConsentItem();
455
        const markup = createCookieConsentedJSItem(newItem, currentLen);
633
        const markup = createCookieConsentedJSItem(newItem, currentLen);
456
        $('#prefModal .modal-body #cookieConsentedJSItems').append($(markup));
634
        $("#prefModal .modal-body #cookieConsentedJSItems").append($(markup));
457
        addExpandHandler();
635
        addExpandHandler();
458
        addCollapseHandler();
636
        addCollapseHandler();
459
        addConsentDeleteHandler();
637
        addConsentDeleteHandler();
Lines 467-504 function addNewHandler() { Link Here
467
// (e.g.)
645
// (e.g.)
468
// const f = 'populateCookieConsentedJS';
646
// const f = 'populateCookieConsentedJS';
469
// window[f]();
647
// window[f]();
470
window.populateCookieConsentedJS = function(el) {
648
window.populateCookieConsentedJS = function (el) {
471
    let items = [];
649
    let items = [];
472
    let decoded = '';
650
    let decoded = "";
473
    if (el.value && el.value.length > 0) {
651
    if (el.value && el.value.length > 0) {
474
        try {
652
        try {
475
            decoded = atob(el.value);
653
            decoded = atob(el.value);
476
        } catch (err) {
654
        } catch (err) {
477
            throw (__(
655
            throw __(
478
                'Unable to Base64 decode value stored in CookieConsentedJS syspref: ' +
656
                "Unable to Base64 decode value stored in CookieConsentedJS syspref: " +
479
                err.message
657
                    err.message
480
            ));
658
            );
481
        }
659
        }
482
        try {
660
        try {
483
            items = JSON.parse(decoded);
661
            items = JSON.parse(decoded);
484
        } catch (err) {
662
        } catch (err) {
485
            throw (__(
663
            throw __(
486
                'Unable to JSON parse decoded value stored in CookieConsentedJS syspref: ' +
664
                "Unable to JSON parse decoded value stored in CookieConsentedJS syspref: " +
487
                err.message
665
                    err.message
488
            ));
666
            );
489
        }
667
        }
490
    }
668
    }
491
    const markup = populateConsentMarkup(items);
669
    const markup = populateConsentMarkup(items);
492
    const validationWarning = populateValidationWarning();
670
    const validationWarning = populateValidationWarning();
493
    const pref_name = el.id.replace(/pref_/, '');
671
    const pref_name = el.id.replace(/pref_/, "");
494
    $('#saveModalPrefs').data('target', el.id);
672
    $("#saveModalPrefs").data("target", el.id);
495
    $('#prefModalLabel').text( pref_name );
673
    $("#prefModalLabel").text(pref_name);
496
    $('#prefModal .modal-body').html($('<div id="cookieConsentedJSItems">' + validationWarning + markup + '</div><div><a href="#" id="cookieConsentedJSAddNew">' + __('Add new code') + '</a></div>'));
674
    $("#prefModal .modal-body").html(
675
        $(
676
            '<div id="cookieConsentedJSItems">' +
677
                validationWarning +
678
                markup +
679
                '</div><div><a href="#" id="cookieConsentedJSAddNew">' +
680
                __("Add new code") +
681
                "</a></div>"
682
        )
683
    );
497
    addExpandHandler();
684
    addExpandHandler();
498
    addCollapseHandler();
685
    addCollapseHandler();
499
    addNewHandler();
686
    addNewHandler();
500
    addConsentDeleteHandler();
687
    addConsentDeleteHandler();
501
}
688
};
502
689
503
// Prepare the data in the UI for sending back as a syspref.
690
// Prepare the data in the UI for sending back as a syspref.
504
// We validate that everything is what we expect. This function is added
691
// We validate that everything is what we expect. This function is added
Lines 508-528 window.populateCookieConsentedJS = function(el) { Link Here
508
// const f = 'prepareCookieConsentedJS';
695
// const f = 'prepareCookieConsentedJS';
509
// window[f]();
696
// window[f]();
510
window.prepareCookieConsentedJS = function () {
697
window.prepareCookieConsentedJS = function () {
511
    const items = $('.cookieConsentedJSItem');
698
    const items = $(".cookieConsentedJSItem");
512
    const invalid = [];
699
    const invalid = [];
513
    const valid = [];
700
    const valid = [];
514
    items.each(function () {
701
    items.each(function () {
515
        const id = $(this).data('id').length > 0 ?
702
        const id =
516
            $(this).data('id') :
703
            $(this).data("id").length > 0
517
            '_' + Math.random().toString(36).substr(2, 9);
704
                ? $(this).data("id")
518
        const name = $(this).find('.metaName').val();
705
                : "_" + Math.random().toString(36).substr(2, 9);
519
        const desc = $(this).find('.metaDescription').val();
706
        const name = $(this).find(".metaName").val();
520
        const matchPattern = $(this).find('.metaMatchPattern').val();
707
        const desc = $(this).find(".metaDescription").val();
521
        const cookieDomain = $(this).find('.metaCookieDomain').val();
708
        const matchPattern = $(this).find(".metaMatchPattern").val();
522
        const cookiePath = $(this).find('.metaCookiePath').val();
709
        const cookieDomain = $(this).find(".metaCookieDomain").val();
523
        const opacConsent = $(this).find('.opacConsent').is(':checked')
710
        const cookiePath = $(this).find(".metaCookiePath").val();
524
        const staffConsent = $(this).find('.staffConsent').is(':checked');
711
        const opacConsent = $(this).find(".opacConsent").is(":checked");
525
        const code = $(this).find('.preference-code').val();
712
        const staffConsent = $(this).find(".staffConsent").is(":checked");
713
        const code = $(this).find(".preference-code").val();
526
        // If the name, description, match pattern code are empty, then they've
714
        // If the name, description, match pattern code are empty, then they've
527
        // added a new entry, but not filled it in, we can skip it
715
        // added a new entry, but not filled it in, we can skip it
528
        if (
716
        if (
Lines 537-547 window.prepareCookieConsentedJS = function () { Link Here
537
        }
725
        }
538
        // They've filled in at least some info
726
        // They've filled in at least some info
539
        if (
727
        if (
540
            (name.length === 0) ||
728
            name.length === 0 ||
541
            (desc.length === 0) ||
729
            desc.length === 0 ||
542
            (matchPattern.length === 0) ||
730
            matchPattern.length === 0 ||
543
            (cookiePath.length === 0) ||
731
            cookiePath.length === 0 ||
544
            (code.length === 0)
732
            code.length === 0
545
        ) {
733
        ) {
546
            invalid.push(this);
734
            invalid.push(this);
547
        } else {
735
        } else {
Lines 554-579 window.prepareCookieConsentedJS = function () { Link Here
554
                cookiePath: cookiePath,
742
                cookiePath: cookiePath,
555
                opacConsent: opacConsent,
743
                opacConsent: opacConsent,
556
                staffConsent: staffConsent,
744
                staffConsent: staffConsent,
557
                code: btoa(code)
745
                code: btoa(code),
558
            }
746
            };
559
            valid.push(obj);
747
            valid.push(obj);
560
        }
748
        }
561
    });
749
    });
562
    // We failed validation
750
    // We failed validation
563
    if (invalid.length > 0) {
751
    if (invalid.length > 0) {
564
        $('#cookieConsentedJSWarning').show();
752
        $("#cookieConsentedJSWarning").show();
565
        return false;
753
        return false;
566
    }
754
    }
567
    $('#cookieConsentedJSWarning').hide();
755
    $("#cookieConsentedJSWarning").hide();
568
    if (valid.length === 0) {
756
    if (valid.length === 0) {
569
        return '';
757
        return "";
570
    }
758
    }
571
    const json = JSON.stringify(valid);
759
    const json = JSON.stringify(valid);
572
    const base64 = btoa(json);
760
    const base64 = btoa(json);
573
    return base64;
761
    return base64;
574
}
762
};
575
763
576
$("#saveModalPrefs").on("click", function(){
764
$("#saveModalPrefs").on("click", function () {
577
    var formfieldid = $("#" + $(this).data("target"));
765
    var formfieldid = $("#" + $(this).data("target"));
578
    let finalString = "";
766
    let finalString = "";
579
    if ($(this).data("type") == "modalselect") {
767
    if ($(this).data("type") == "modalselect") {
Lines 586-611 $("#saveModalPrefs").on("click", function(){ Link Here
586
    // data has failed validation
774
    // data has failed validation
587
    if (finalString !== false) {
775
    if (finalString !== false) {
588
        formfieldid.val(finalString).addClass("modified");
776
        formfieldid.val(finalString).addClass("modified");
589
        mark_modified.call( formfieldid );
777
        mark_modified.call(formfieldid);
590
        KOHA.Preferences.Save( formfieldid.closest("form") );
778
        KOHA.Preferences.Save(formfieldid.closest("form"));
591
        $("#prefModal").modal("hide");
779
        $("#prefModal").modal("hide");
592
    }
780
    }
593
});
781
});
594
782
595
$("#prefModal").on("hide.bs.modal", function(){
783
$("#prefModal").on("hide.bs.modal", function () {
596
    $("#prefModalLabel,#prefModalBody").html("");
784
    $("#prefModalLabel,#prefModalBody").html("");
597
    $("#saveModalPrefs").data("target", "" );
785
    $("#saveModalPrefs").data("target", "");
598
});
786
});
599
787
600
$("#select_all").on("click",function(e){
788
$("#select_all").on("click", function (e) {
601
    e.preventDefault();
789
    e.preventDefault();
602
    $("label:not(.required) .dbcolumn_selection:not(:disabled)").prop("checked", true);
790
    $("label:not(.required) .dbcolumn_selection:not(:disabled)").prop(
791
        "checked",
792
        true
793
    );
603
});
794
});
604
$("#clear_all").on("click",function(e){
795
$("#clear_all").on("click", function (e) {
605
    e.preventDefault();
796
    e.preventDefault();
606
    $("label:not(.required) .dbcolumn_selection").prop("checked", false);
797
    $("label:not(.required) .dbcolumn_selection").prop("checked", false);
607
});
798
});
608
799
609
$("body").on("click", "label.required input.dbcolumn_selection", function(e){
800
$("body").on("click", "label.required input.dbcolumn_selection", function (e) {
610
    e.preventDefault();
801
    e.preventDefault();
611
});
802
});
612
- 

Return to bug 34655