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

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

Return to bug 26553