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

(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/columns_settings.inc (-2 / +4 lines)
Lines 1-5 Link Here
1
[% USE TablesSettings %]
1
[% USE TablesSettings %]
2
2
[% Asset.js("js/datatables_buttons_shim.js") | $raw %]
3
<script>
3
<script>
4
function KohaTable(selector, dt_parameters, columns_settings) {
4
function KohaTable(selector, dt_parameters, columns_settings) {
5
    var id = 0;
5
    var id = 0;
Lines 40-45 function KohaTable(selector, dt_parameters, columns_settings) { Link Here
40
        }
40
        }
41
    }
41
    }
42
42
43
    const export_format_spreadsheet = ButtonsShim.export_format_spreadsheet;
44
43
    // Add a "Clear filter" button to table filter form field
45
    // Add a "Clear filter" button to table filter form field
44
    dt_parameters[ "buttons" ] = [
46
    dt_parameters[ "buttons" ] = [
45
        {
47
        {
Lines 58-64 function KohaTable(selector, dt_parameters, columns_settings) { Link Here
58
            text: _("CSV"),
60
            text: _("CSV"),
59
            exportOptions: {
61
            exportOptions: {
60
                columns: exportColumns,
62
                columns: exportColumns,
61
                format: export_format
63
                format: export_format_spreadsheet
62
            },
64
            },
63
        },
65
        },
64
        {
66
        {
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/datatables.inc (+1 lines)
Lines 2-5 Link Here
2
[% USE Asset %]
2
[% USE Asset %]
3
[% Asset.js("lib/jquery/plugins/jquery.dataTables.min.js") | $raw %]
3
[% Asset.js("lib/jquery/plugins/jquery.dataTables.min.js") | $raw %]
4
[% Asset.js("lib/jquery/plugins/dataTables.responsive.min.js") | $raw %]
4
[% Asset.js("lib/jquery/plugins/dataTables.responsive.min.js") | $raw %]
5
[% Asset.js("js/datatables_buttons_shim.js") | $raw %]
5
[% Asset.js("js/datatables.js") | $raw %]
6
[% Asset.js("js/datatables.js") | $raw %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (-1 / +4 lines)
Lines 1210-1215 Link Here
1210
                );
1210
                );
1211
            });
1211
            });
1212
1212
1213
            const export_format_spreadsheet = ButtonsShim.export_format_spreadsheet;
1214
1213
            var dTables = $("#checkoutst,#holdst,#overduest,#opac-user-relative-issues-table");
1215
            var dTables = $("#checkoutst,#holdst,#overduest,#opac-user-relative-issues-table");
1214
            dTables.each(function(){
1216
            dTables.each(function(){
1215
                var thIndex = $(this).find("th.psort").index();
1217
                var thIndex = $(this).find("th.psort").index();
Lines 1250-1256 Link Here
1250
                            extend: "csv",
1252
                            extend: "csv",
1251
                            exportOptions: {
1253
                            exportOptions: {
1252
                                /* CSV export should include all columns (even invisible ones) unless they are .noExport */
1254
                                /* CSV export should include all columns (even invisible ones) unless they are .noExport */
1253
                                columns: ":not(.noExport)"
1255
                                columns: ":not(.noExport)",
1256
                                format:  export_format_spreadsheet
1254
                            }
1257
                            }
1255
                        }
1258
                        }
1256
                    ]
1259
                    ]
(-)a/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js (-1 / +3 lines)
Lines 240-245 $.fn.dataTable.ext.buttons.clearFilter = { Link Here
240
            }
240
            }
241
        };
241
        };
242
242
243
        const export_format_spreadsheet = ButtonsShim.export_format_spreadsheet;
244
243
        var export_buttons = [
245
        var export_buttons = [
244
            {
246
            {
245
                extend: 'excelHtml5',
247
                extend: 'excelHtml5',
Lines 252-258 $.fn.dataTable.ext.buttons.clearFilter = { Link Here
252
                extend: 'csvHtml5',
254
                extend: 'csvHtml5',
253
                exportOptions: {
255
                exportOptions: {
254
                    columns: exportColumns,
256
                    columns: exportColumns,
255
                    format:  export_format
257
                    format:  export_format_spreadsheet
256
                },
258
                },
257
            },
259
            },
258
            {
260
            {
(-)a/koha-tmpl/opac-tmpl/bootstrap/js/datatables_buttons_shim.js (-1 / +112 lines)
Line 0 Link Here
0
- 
1
window.ButtonsShim = {};
2
3
ButtonsShim.export_format_spreadsheet = {
4
    body: function (data, row, column, node) {
5
        const newnode = node.cloneNode(true);
6
        const no_export_nodes = newnode.querySelectorAll(".no-export");
7
        no_export_nodes.forEach(child => {
8
            child.parentNode.removeChild(child);
9
        });
10
        //Note: innerHTML is the same thing as the data variable,
11
        //minus the ".no-export" nodes that we've removed
12
        //Note: See dataTables.buttons.js for original function usage
13
        const str = ButtonsShim.stripData(newnode.innerHTML, {
14
            decodeEntities: false,
15
            stripHtml: true,
16
            stripNewlines: true,
17
            trim: true,
18
            escapeExcelFormula: true
19
        });
20
        return str;
21
    },
22
};
23
24
ButtonsShim._stripHtml = function (input) {
25
    var _max_str_len = Math.pow(2, 28);
26
    var _re_html = /<([^>]*>)/g;
27
    if (! input || typeof input !== 'string') {
28
        return input;
29
    }
30
    // Irrelevant check to workaround CodeQL's false positive on the regex
31
    if (input.length > _max_str_len) {
32
        throw new Error('Exceeded max str len');
33
    }
34
    var previous;
35
    input = input.replace(_re_html, ''); // Complete tags
36
    // Safety for incomplete script tag - use do / while to ensure that
37
    // we get all instances
38
    do {
39
        previous = input;
40
        input = input.replace(/<script/i, '');
41
    } while (input !== previous);
42
    return previous;
43
};
44
45
ButtonsShim.stripHtml = function (mixed) {
46
    var type = typeof mixed;
47
48
    if (type === 'function') {
49
        ButtonsShim._stripHtml = mixed;
50
        return;
51
    }
52
    else if (type === 'string') {
53
        return ButtonsShim._stripHtml(mixed);
54
    }
55
    return mixed;
56
};
57
ButtonsShim.stripHtmlScript = function (input) {
58
    var previous;
59
    do {
60
        previous = input;
61
        input = input.replace(/<script\b[^<]*(?:(?!<\/script[^>]*>)<[^<]*)*<\/script[^>]*>/gi, '');
62
    } while (input !== previous);
63
    return input;
64
};
65
ButtonsShim.stripHtmlComments = function (input) {
66
    var previous;
67
    do {
68
        previous = input;
69
        input = input.replace(/(<!--.*?--!?>)|(<!--[\S\s]+?--!?>)|(<!--[\S\s]*?$)/g, '');
70
    } while (input !== previous);
71
    return input;
72
};
73
ButtonsShim.stripData = function (str, config) {
74
    // If the input is an HTML element, we can use the HTML from it (HTML might be stripped below).
75
    if (str !== null && typeof str === 'object' && str.nodeName && str.nodeType) {
76
        str = str.innerHTML;
77
    }
78
79
    if (typeof str !== 'string') {
80
        return str;
81
    }
82
83
    // Always remove script tags
84
    //str = Buttons.stripHtmlScript(str);
85
    str = ButtonsShim.stripHtmlScript(str);
86
87
    // Always remove comments
88
    //str = Buttons.stripHtmlComments(str);
89
    str = ButtonsShim.stripHtmlComments(str);
90
91
    if (!config || config.stripHtml) {
92
        //str = DataTable.util.stripHtml(str);
93
        str = ButtonsShim.stripHtml(str);
94
    }
95
96
    if (!config || config.trim) {
97
        str = str.trim();
98
    }
99
100
    if (!config || config.stripNewlines) {
101
        str = str.replace(/\n/g, ' ');
102
    }
103
104
    // Prevent Excel from running a formula
105
    if (!config || config.escapeExcelFormula) {
106
        if (str.match(/^[=@\t\r]/)) {
107
            str = "'" + str;
108
        }
109
    }
110
111
    return str;
112
};

Return to bug 40525