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

(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc (-352 lines)
Lines 1-351 Link Here
1
[% USE raw %]
2
[% USE Koha %]
3
[% USE TablesSettings %]
4
<!-- columns_settings.inc -->
5
6
<script>
7
// default_filters is not used but keeping the same constructor as kohaTable for consistency
8
function KohaTable(id_selector, dt_parameters, table_settings, add_filters, default_filters, filters_options) {
9
    var selector = '#' + id_selector;
10
11
    if ( table_settings ) {
12
13
        let columns_settings = table_settings["columns"];
14
15
        let table_key = 'DataTables_%s_%s_%s_%s'.format(
16
            table_settings.module,
17
            table_settings.page,
18
            table_settings.table,
19
            id_selector,
20
        );
21
22
        let default_save_state        = table_settings.default_save_state;
23
        let default_save_state_search = table_settings.default_save_state_search;
24
25
        dt_parameters.stateSave = true;
26
        dt_parameters.stateSaveCallback = function( settings, data ) {
27
            localStorage.setItem( table_key, JSON.stringify(data) )
28
        }
29
30
        function set_default(table_settings, table_dt){
31
            let columns = new Array(table_dt.columns()[0].length).fill({visible: true});
32
            let hidden_ids = _dt_visibility(table_settings, table_dt);
33
            hidden_ids.forEach((id, i) => { columns[id] = { visible: false } } );
34
            // State is not loaded if time is not passed
35
            return { columns, time: new Date() };
36
        }
37
        dt_parameters.stateLoadCallback = function(settings) {
38
39
            // Load state from URL
40
            const url = new URL(window.location.href);
41
            let state_from_url = url.searchParams.get( table_key + '_state');
42
            if ( state_from_url ) {
43
                settings.loaded_from_state = true;
44
                return JSON.parse(atob(state_from_url));
45
            }
46
47
            if (!default_save_state) return set_default(table_settings, this.api());
48
49
            let state = localStorage.getItem(table_key);
50
            if (!state) return set_default(table_settings, this.api());
51
52
            state = JSON.parse(state);
53
54
            if (default_save_state_search ) {
55
                settings.loaded_from_state = true;
56
            } else {
57
                delete state.search;
58
                state.columns.forEach(c => delete c.search );
59
            }
60
            return state;
61
        }
62
63
        if ( table_settings.hasOwnProperty('default_save_state') && table_settings['default_save_state'] === 0 ) {
64
            localStorage.removeItem(table_key);
65
        }
66
    }
67
68
    var exportColumns = ":visible:not(.noExport)";
69
    var exportRows = ":visible:not(.noExport)";
70
    if( dt_parameters.hasOwnProperty("exportColumns") ){
71
        // A custom buttons configuration has been passed from the page
72
        exportColumns = dt_parameters["exportColumns"];
73
    }
74
75
    const export_format_spreadsheet = {
76
        body: function ( data, row, column, node ) {
77
            var newnode = $(node);
78
79
            if ( newnode.find(".noExport").length > 0 ) {
80
                newnode = newnode.clone();
81
                newnode.find(".noExport").remove();
82
            }
83
            let trimmed_str = newnode.text().replace( /\n/g, ' ' ).trim();
84
            const unsafeCharacters = /^[=+\-@\t\r]/;
85
            if ( unsafeCharacters.test(trimmed_str) ){
86
                trimmed_str = "'" + trimmed_str;
87
            }
88
            return trimmed_str;
89
        }
90
    }
91
92
    var export_format = {
93
        body: function ( data, row, column, node ) {
94
            var newnode = $(node);
95
96
            if ( newnode.find(".noExport").length > 0 ) {
97
                newnode = newnode.clone();
98
                newnode.find(".noExport").remove();
99
            }
100
101
            return newnode.text().replace( /\n/g, ' ' ).trim();
102
        }
103
    }
104
105
    var export_numeric = {
106
        body: function ( data, row, column, node ) {
107
            var newnode = $(node);
108
109
            if ( newnode.find(".noExport").length > 0 ) {
110
                newnode = newnode.clone();
111
                newnode.find(".noExport").remove();
112
            }
113
            let tp = newnode.text().replace( /\n/g, ' ' ).trim();
114
            tp = $('<p>' + tp + '</p>').text();
115
            return $.isNumeric(tp.replace(',', '.')) ? tp.replace(',', '.') : tp;
116
        }
117
    }
118
119
    var export_buttons = [
120
        {
121
            extend: 'csvHtml5',
122
            text: _("CSV"),
123
            exportOptions: {
124
                columns: exportColumns,
125
                rows: exportRows,
126
                format:  export_format
127
            },
128
        },
129
        {
130
            extend: 'copyHtml5',
131
            text: _("Copy"),
132
            exportOptions: {
133
                columns: exportColumns,
134
                rows: exportRows,
135
                format:  export_format_spreadsheet
136
            },
137
        },
138
        {
139
            extend: 'print',
140
            text: _("Print"),
141
            exportOptions: {
142
                columns: exportColumns,
143
                rows: exportRows,
144
                format:  export_format
145
            },
146
        }
147
    ];
148
149
    [% IF Koha.Preference("CurrencyFormat") != 'FR' %]
150
        export_buttons.unshift (
151
            {
152
                extend: 'excelHtml5',
153
                text: _("Excel"),
154
                exportOptions: {
155
                    columns: exportColumns,
156
                    rows: exportRows,
157
                    format:  export_format_spreadsheet
158
                },
159
            }
160
        );
161
    [% ELSE %]
162
        export_buttons.unshift (
163
            {
164
                extend: 'excelHtml5',
165
                text: _("Excel"),
166
                exportOptions: {
167
                    columns: exportColumns,
168
                    rows: exportRows,
169
                    format:  export_numeric
170
                },
171
            }
172
        );
173
    [% END %]
174
175
    $.fn.dataTable.ext.buttons.clear_filter =
176
        {
177
            fade: 100,
178
            className: "dt_button_clear_filter",
179
            titleAttr: _("Clear filter"),
180
            enabled: false,
181
            text: '<i class="fa fa-lg fa-times"></i> <span class="dt-button-text">' + _("Clear filter") + '</span>',
182
            action: function ( e, dt, node, config ) {
183
                dt.search( "" ).draw("page");
184
                node.addClass("disabled");
185
            }
186
        };
187
188
    dt_parameters[ "buttons" ] = ['clear_filter'];
189
190
    // Retrieving bKohaColumnsUseNames from the options passed to the constructor, not DT settings
191
    // But ideally should be retrieved using table.data()
192
    let use_names = dt_parameters.bKohaColumnsUseNames;
193
    let included_columns = [];
194
    if (table_settings) {
195
        if (use_names) {
196
            // bKohaColumnsUseNames is set, identify columns by their data-colname
197
            included_columns = table_settings.columns
198
                .filter(c => !c.cannot_be_toggled)
199
                .map(c => "[data-colname='%s']".format(c.columnname))
200
                .join(",");
201
        } else {
202
            // Not set, columns are ordered the same than in the columns settings
203
            included_columns = table_settings.columns
204
                .map((c, i) => (!c.cannot_be_toggled ? i : null))
205
                .filter(i => i !== null);
206
        }
207
    }
208
209
    if( included_columns.length > 0 ){
210
        dt_parameters[ "buttons" ].push(
211
            {
212
                extend: 'colvis',
213
                fade: 100,
214
                columns: included_columns,
215
                className: "columns_controls",
216
                titleAttr: _("Columns settings"),
217
                text: '<i class="fa fa-lg fa-gear"></i> <span class="dt-button-text">' + _("Columns") + '</span>',
218
                exportOptions: {
219
                    columns: exportColumns,
220
                    rows: exportRows,
221
                }
222
            }
223
        );
224
    }
225
226
    dt_parameters[ "buttons" ].push(
227
        {
228
            extend: 'collection',
229
            autoClose: true,
230
            fade: 100,
231
            className: "export_controls",
232
            titleAttr: _("Export or print"),
233
            text: '<i class="fa fa-lg fa-download"></i> <span class="dt-button-text">' + _("Export") + '</span>',
234
            buttons: export_buttons
235
        }
236
    );
237
238
    /* No other exceptions should be added here! */
239
    if ( table_settings && table_settings.page != 'itemsearch' ) {
240
        dt_parameters["buttons"].push(
241
            {
242
                autoClose: true,
243
                fade: 100,
244
                className: "copyConditions_controls",
245
                titleAttr: __("Copy shareable link"),
246
                text: '<i class="fa fa-lg fa-copy"></i> <span class="dt-button-text">' + __("Copy shareable link") + '</span>',
247
                action: function (e, dt, node, config) {
248
                    let table_key = 'DataTables_%s_%s_%s_%s'.format(
249
                        table_settings.module,
250
                        table_settings.page,
251
                        table_settings.table,
252
                        dt.settings()[0].nTable.id,
253
                    );
254
255
                    let state = JSON.stringify(dt.state());
256
                    delete state.time;
257
                    let searchParams = new URLSearchParams(window.location.search);
258
                    searchParams.set(table_key + '_state', btoa(state));
259
                    let url = window.location.origin + window.location.pathname + '?' + searchParams.toString() + window.location.hash;
260
                    if( navigator.clipboard && navigator.clipboard.writeText){
261
                        navigator.clipboard.writeText( url );
262
                        $(node).tooltip({trigger: 'manual', title: _("Copied!")}).tooltip('show');
263
                    }
264
                },
265
            }
266
        );
267
    }
268
269
    if ( table_settings && CAN_user_parameters_manage_column_config ) {
270
        dt_parameters[ "buttons" ].push(
271
            {
272
                className: "dt_button_configure_table",
273
                fade: 100,
274
                titleAttr: _("Configure table"),
275
                text: '<i class="fa fa-lg fa-wrench"></i> <span class="dt-button-text">' + _("Configure") + '</span>',
276
                action: function() {
277
                    window.location = '/cgi-bin/koha/admin/columns_settings.pl?module=' + table_settings['module'] + '&page=' + table_settings['page'] + '&table=' + table_settings['table'];
278
                },
279
            }
280
        );
281
    }
282
283
    if ( add_filters ) {
284
        dt_parameters['orderCellsTop'] = true;
285
    }
286
287
    var table = $(selector);
288
289
    var new_parameters = {}
290
    $.extend(true, new_parameters, dataTablesDefaults, dt_parameters);
291
    var default_column_defs = [
292
        { "targets": [ "title-string" ], "type": "title-string" },
293
        { "targets": [ "string-sort" ],  "type": "string" },
294
        { "targets": [ "anti-the" ],     "type": "anti-the" },
295
        { "targets": [ "NoSort" ],       "orderable": false, "searchable": false },
296
        { "targets": [ "NoVisible" ],    "visible": false }
297
    ];
298
    if ( new_parameters["aoColumnDefs"] === undefined ) {
299
        new_parameters["aoColumnDefs"] = default_column_defs;
300
    } else {
301
        $(default_column_defs).each(function(){
302
            new_parameters["aoColumnDefs"].push(this);
303
        });
304
    }
305
306
    new_parameters["loaded_from_state"] = false;
307
308
    if ( table_settings ) {
309
        if ( table_settings.hasOwnProperty('default_display_length') && table_settings['default_display_length'] != null ) {
310
            // pageLength needs to be a number, not a string, or it can cause issues with DataTable's next button.
311
            new_parameters["pageLength"] = parseInt(table_settings['default_display_length']);
312
        }
313
        if ( table_settings.hasOwnProperty('default_sort_order') && table_settings['default_sort_order'] != null ) {
314
            new_parameters["order"] = [[ table_settings['default_sort_order'], 'asc' ]];
315
        }
316
    }
317
318
    $(table).data('bKohaColumnsUseNames', dt_parameters.bKohaColumnsUseNames);
319
320
    table.dataTable(new_parameters);
321
    var table_dt = table.DataTable();
322
    table_dt.on("column-visibility.dt", function(){
323
        if( typeof columnsInit == 'function' ){
324
            // This function can be created separately and used to trigger
325
            // an event after the DataTable has loaded AND column visibility
326
            // has been updated according to the table's configuration
327
            columnsInit(this);
328
        }
329
    });
330
331
    if ( add_filters ) {
332
        _dt_add_filters(table, table_dt, filters_options);
333
    }
334
335
    table_dt.on("column-visibility.dt", function(){
336
        if ( add_filters ) {
337
            _dt_add_filters(table, table_dt, filters_options);
338
        }
339
    });
340
341
    table_dt.on( 'search.dt', function ( e, settings ) {
342
        // When the DataTables search function is triggered,
343
        // enable or disable the "Clear filter" button based on
344
        // the presence of a search string
345
        toggledClearFilter(table_dt.search(), settings.nTable.id);
346
    });
347
348
    return table;
349
}
350
</script>
351
<!-- / columns_settings.inc -->
352
- 

Return to bug 26553