@osimatic/helpers-js 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/data_table.js ADDED
@@ -0,0 +1,419 @@
1
+
2
+ class DataTable {
3
+ // criteres = {};
4
+
5
+ constructor() {
6
+ this.criteres = {};
7
+ }
8
+
9
+ static setCallbackOnLoadData(callback) {
10
+ this.callbackOnLoadData = callback;
11
+ }
12
+
13
+ // ------------------------------------------------------------
14
+ // Critères
15
+ // ------------------------------------------------------------
16
+
17
+ static populateFormFromFilters(form) {
18
+ FormHelper.populateForm(form, this.criteres);
19
+ }
20
+
21
+ static setDefaultFilters(filters) {
22
+ this.criteres = filters;
23
+ }
24
+
25
+ static setFiltersFromForm(form) {
26
+ this.criteres = UrlAndQueryString.parseQuery(form.serialize());
27
+ }
28
+
29
+ static getFilterParam(key) {
30
+ return this.criteres[key] || 'NONE';
31
+ }
32
+
33
+ static getFilters() {
34
+ return this.criteres;
35
+ }
36
+
37
+ // ------------------------------------------------------------
38
+ // Chargement tableau
39
+ // ------------------------------------------------------------
40
+
41
+ static init(options) {
42
+ var div = options.div;
43
+ var defaultFilters = options.default_filters || {};
44
+
45
+ //let form = div.find('.filter_popover_content form');
46
+ //if (typeof form != 'undefined') {
47
+ let queryStringFilters = UrlAndQueryString.parseQuery(window.location.search);
48
+ defaultFilters = Object.assign(defaultFilters, queryStringFilters);
49
+ //}
50
+
51
+ // Bouton filtrer
52
+ var filterLink = div.find('a.filter_link');
53
+ if (filterLink.length) {
54
+ filterLink.popover({
55
+ content: div.find('.filter_popover_content').html(),
56
+ template: '<div class="popover filter_popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>',
57
+ container: 'body',
58
+ // trigger: 'manual',
59
+ trigger: 'click',
60
+ html: true,
61
+ animation: false,
62
+ // placement: 'topRight'
63
+ placement: 'leftTop'
64
+ })
65
+ .click(function(e) {
66
+ // $('.popover').not(this).hide(); // optional, hide other popovers
67
+ e.preventDefault();
68
+ });
69
+
70
+ filterLink.on('shown.bs.popover', function () {
71
+ var form = $('.filter_popover form');
72
+
73
+ DataTable.populateFormFromFilters(form);
74
+
75
+ // Lien input period
76
+ InputPeriod.addLinks(form);
77
+
78
+ // Callback custom
79
+ if (typeof options.on_show_filter_form != 'undefined' && options.on_show_filter_form != null) {
80
+ options.on_show_filter_form(form);
81
+ }
82
+
83
+ form.find('button[type="submit"]').off('click').click(function(e) {
84
+ // e.preventDefault();
85
+ DataTable.updateFiltersAndLoadData(div, form);
86
+ return false;
87
+ });
88
+ });
89
+ }
90
+
91
+ // Bouton exporter
92
+ var exportLink = div.find('a.export_link');
93
+ if (exportLink.length) {
94
+ if (typeof options.export_modal_enabled == 'undefined' || !options.export_modal_enabled) {
95
+ // sans modal
96
+ exportLink.click(function(e) {
97
+ e.preventDefault();
98
+ var button = $(this).attr('disabled', true).button('loading');
99
+ if (typeof options.on_export != 'undefined' && options.on_export != null) {
100
+ options.on_export(button.data('format'), {...DataTable.getFilters()}, () => {
101
+ button.attr('disabled', false).button('reset');
102
+ });
103
+ }
104
+ return false;
105
+ });
106
+ }
107
+ else {
108
+ // avec modal
109
+ exportLink.click(function(e) {
110
+ // todo : ouvrir modal #modal_export lors du click sur le lien
111
+ });
112
+
113
+ $('div#modal_export').on('show.bs.modal', function (event) {
114
+ var button = $(event.relatedTarget);
115
+ var modal = $(this);
116
+ var form = modal.find('form');
117
+
118
+ // Fonction de callback permettant d'initialiser contenu du modal export, cette fonction doit renvoyer le contenu du modal
119
+ if (typeof options.set_export_form != 'undefined' && options.set_export_form != null) {
120
+ modal.find('modal-body').html(options.set_export_form(modal, button));
121
+ }
122
+
123
+ // Fonction de callback permettant d'initialiser le modal export
124
+ if (typeof options.on_show_export_form != 'undefined' && options.on_show_export_form != null) {
125
+ modal.find('modal-body').html(options.on_show_export_form(modal, button));
126
+ }
127
+
128
+ var btnSubmit = form.find('button[type="submit"]').attr('disabled', false).button('reset');
129
+ btnSubmit.off('click').click(function(e) {
130
+ e.preventDefault();
131
+ $(this).attr('disabled', true).button('loading');
132
+
133
+ // Une fois le formulaire d'export validé, si fonction callback spécifié, on l'appelle, cette fonction doit renvoyer true ou false pour savoir si le form contient des erreurs ou non.
134
+ let hasErrors = false;
135
+ if (typeof options.on_submit_export_modal != 'undefined' && options.on_submit_export_modal != null) {
136
+ hasErrors = options.on_submit_export_modal(modal, button);
137
+ }
138
+
139
+ if (hasErrors) {
140
+ $(this).attr('disabled', false).button('reset');
141
+ return false;
142
+ }
143
+
144
+ // S'il n'y a pas d'erreur on enclenche l'export
145
+ if (typeof options.on_export != 'undefined' && options.on_export != null) {
146
+ options.on_export(button.data('format'), {...DataTable.getFilters()}, form, () => {
147
+ // Retrait du modal
148
+ modal.modal('hide');
149
+ });
150
+ }
151
+
152
+ return false;
153
+ });
154
+ });
155
+ }
156
+
157
+ }
158
+
159
+ console.log('defaultFilters', defaultFilters);
160
+
161
+ DataTable.setDefaultFilters(defaultFilters);
162
+ DataTable.setCallbackOnLoadData(options.on_load_data);
163
+
164
+ DataTable.loadData(div);
165
+ }
166
+
167
+ static updateFiltersAndLoadData(div, form) {
168
+ DataTable.setFiltersFromForm(form);
169
+ DataTable.addBrowserHistory();
170
+ // DataTable.populateFormFromFilters($('.filter_popover form'));
171
+
172
+ $('a.filter_link').popover('hide');
173
+ $('.filter_popover').remove();
174
+
175
+ DataTable.loadData(div);
176
+ }
177
+
178
+ static loadData(div) {
179
+ console.log('DataTable.loadData');
180
+ DataTable.addLoader(div);
181
+
182
+ if (typeof this.callbackOnLoadData != 'undefined' && this.callbackOnLoadData != null) {
183
+ this.callbackOnLoadData(div, DataTable.getFilters());
184
+ }
185
+ }
186
+
187
+ static addBrowserHistory() {
188
+ //console.log('addBrowserHistory');
189
+ // on ne garde que les critères contenant des valeurs de type string ou tableau avec max 3 éléments
190
+ let savedCriterias = Object.filter(this.criteres, value => (!Array.isArray(value) || (Array.isArray(value) && value.length <= 3)));
191
+ //console.log('savedCriterias', savedCriterias);
192
+
193
+ //var url = urldecode(urlRetour);
194
+ var url = window.location.href;
195
+ //console.log('current url', url);
196
+
197
+ let queryString = UrlAndQueryString.getQueryString(url);
198
+ //console.log('current QueryString', queryString);
199
+
200
+ // todo : delete params qui ne sont pas dans savedCriterias
201
+ Object.entries(savedCriterias).forEach(([key, value]) => queryString = UrlAndQueryString.setParam(queryString, key, value));
202
+ queryString = queryString.includes('?') ? queryString.substring(1) : queryString;
203
+ //console.log('new queryString', queryString);
204
+
205
+ let newUrl = UrlAndQueryString.getPath(url) + '?' + queryString;
206
+ window.history.pushState("", "", newUrl);
207
+ }
208
+
209
+
210
+ // ------------------------------------------------------------
211
+ // Affichage tableau
212
+ // ------------------------------------------------------------
213
+
214
+ static resetContent(div) {
215
+ //console.log('resetContent');
216
+ div.find('span.nb_items_many, span.nb_items_one').addClass('hide');
217
+ div.find('span.nb_items_no').removeClass('hide');
218
+ var table = div.find('table.table');
219
+ table.find('thead,tfoot').removeClass('hide');
220
+ table.find('tbody').children().remove();
221
+
222
+ if ($.fn.dataTable.isDataTable(table)) {
223
+ table.DataTable().clear();
224
+ table.DataTable().destroy();
225
+ }
226
+ }
227
+
228
+ static addModalLoader(modal, btnSubmit) {
229
+ modal.find('.modal-body').addClass('hide').before('<div class="modal-body loader center"><i class="fa fa-circle-notch fa-spin"></i></div>');
230
+ if (typeof btnSubmit != 'undefined') {
231
+ btnSubmit.attr('disabled', true).button('loading');
232
+ }
233
+ }
234
+ static removeModalLoader(modal, btnSubmit) {
235
+ modal.find('.modal-body').removeClass('hide').parent().find('.loader').remove();
236
+ if (typeof btnSubmit != 'undefined') {
237
+ btnSubmit.attr('disabled', false).button('reset');
238
+ }
239
+ }
240
+
241
+ static addLoader(div, isSmall) {
242
+ if (typeof isSmall != 'undefined' && isSmall) {
243
+ div.addClass('hide').before('<p class="loader center"><i class="fa fa-circle-notch fa-spin"></i></p>');
244
+ return;
245
+ }
246
+ //div.addClass('hide').parent().prepend('<div class="alert alert-info loader center">Veuillez patienter… <br><p><i class="fa fa-circle-notch fa-spin"></i></p></div>');
247
+ div.addClass('hide').before('<div class="alert alert-info loader center">Veuillez patienter… <br><p><i class="fa fa-circle-notch fa-spin"></i></p></div>');
248
+ }
249
+ static removeLoader(div) {
250
+ div.removeClass('hide').parent().find('.loader').remove();
251
+ }
252
+
253
+ static displayErrorMessage(div, msg) {
254
+ this.displayMessage(div, msg, 'danger');
255
+ }
256
+ static displayMessage(div, msg, cssClass /*, removeLoader=false*/) {
257
+ this.resetContent(div);
258
+ var table = div.find('table');
259
+ table.find('thead,tfoot').addClass('hide');
260
+ var msgHtml = '<div class="text-'+cssClass+' center">'+msg+'</div>';
261
+ if (table.find('tbody').length == 0) {
262
+ table.append('<tbody></tbody>');
263
+ }
264
+ table.find('tbody').append('<tr class="no_items '+cssClass+'"><td>'+msgHtml+'</td></tr>');
265
+ // table.after(msgHtml);
266
+ // if (removeLoader) {
267
+ DataTable.removeLoader(div);
268
+ // }
269
+ }
270
+
271
+ static displayErrorFromXhr(div, jqxhr, defaultMessage) {
272
+ this.displayError(div, JSON.parse(jqxhr.responseJSON), defaultMessage);
273
+ }
274
+
275
+ static displayError(div, data, defaultMessage) {
276
+ var error = null;
277
+ if (data != null) {
278
+ if (typeof data.error != 'undefined') {
279
+ error = data.error;
280
+ }
281
+ else if (typeof data[0] != 'undefined' && typeof data[0].error != 'undefined') {
282
+ error = data[0].error;
283
+ }
284
+ }
285
+
286
+ if (error == null) {
287
+ return this.displayErrorMessage(div, (typeof defaultMessage != 'undefined' ? defaultMessage : labelErrorOccured));
288
+ }
289
+ return this.displayErrorMessage(div, 'Critères sélectionnés incorrect.');
290
+ }
291
+
292
+ static getDefaultColumnsForDisplayedTable(div) {
293
+ var table = div.find('table');
294
+ var columns = [];
295
+ var defaultHiddenColumns = table.data('hidden_fields') != null ? table.data('hidden_fields').split(',') : [];
296
+ table.find('thead tr th').each(function(idx, th) {
297
+ if (defaultHiddenColumns.indexOf($(th).data('key')) == -1) {
298
+ columns.push($(th).data('key'));
299
+ }
300
+ });
301
+ //console.log(columns);
302
+ return columns;
303
+ }
304
+
305
+ static setDataContent(div, data, displayLineCallback, completeCallback) {
306
+ //console.log('setDataContent');
307
+ var table = div.find('table').removeClass('hide');
308
+
309
+ try {
310
+ DataTable.resetContent(div);
311
+ var tableBody = table.find('tbody');
312
+ for (var i = 0; i < data.length; i++) {
313
+ tableBody.append(displayLineCallback(data[i]));
314
+ }
315
+
316
+ if (data.length) {
317
+ div.find('span.nb_items_no').addClass('hide');
318
+ if (data.length === 1 && div.find('span.nb_items_one').length) {
319
+ div.find('span.nb_items_one').removeClass('hide');
320
+ }
321
+ else {
322
+ div.find('span.nb_items_many').removeClass('hide');
323
+ div.find('span.nb_items').text(data.length);
324
+ }
325
+ }
326
+ else {
327
+ // si pas de plugin DataTable sur le tableau, on cache le tableau s'il n'y a pas de résultat
328
+ if (table.is('[data-no_datatables="1"]')) {
329
+ table.addClass('hide');
330
+ }
331
+ }
332
+
333
+ DataTable.initDataContent(div);
334
+ if (typeof completeCallback == 'function') {
335
+ completeCallback();
336
+ }
337
+ DataTable.removeLoader(div);
338
+ }
339
+ catch (e) {
340
+ console.log(e);
341
+ }
342
+ }
343
+
344
+ static initDataContent(div) {
345
+ //console.log('initDataContent');
346
+ var table = div.find('table');
347
+
348
+ // Popover/Tooltip
349
+ div.find('[data-toggle="popover"]').popover({'trigger':'hover', 'html':true});
350
+ div.find('[data-toggle="tooltip"]').tooltip();
351
+
352
+ // Action multiple / checkbox select all
353
+ if (table.length > 0) {
354
+ //SelectAll.initInTable(table);
355
+ //MultipleActionInTable.init(table);
356
+
357
+ //paging(div.find('select.pagination_max_rows'));
358
+ }
359
+
360
+ if (table.length > 0 && !table.is('[data-no_datatables="1"]') && !$.fn.dataTable.isDataTable(table)) {
361
+ if (table.data('page_length') != null) {
362
+ dateTablesOptions.pageLength = table.data('page_length');
363
+ }
364
+ table.DataTable(dateTablesOptions);
365
+ }
366
+
367
+ DataTable.updateDataContent(div);
368
+ }
369
+
370
+ static updateDataContent(div) {
371
+ var table = div.find('table');
372
+
373
+ // Maj colonnes
374
+ if (table.length > 0 && typeof div.data('table_name') != 'undefined' && div.data('table_name') != null && div.data('display_items').split(',').indexOf('table_columns') != -1) {
375
+ table.find('thead tr th').each(function(idx, th) {
376
+ // table.find('.'+$(th).data('key')+':not(.select):not(.action)').hide();
377
+ table.find('.'+$(th).data('key')+':not(.select):not(.action)').addClass('hide');
378
+ });
379
+ var columns = this.getDisplayParam(div, 'html', null, 'columns').split(',').removeEmptyValues();
380
+ $.each(columns, function(idx, key) {
381
+ table.find('.'+key).removeClass('hide');
382
+ // table.find('.'+key).show();
383
+ });
384
+ }
385
+
386
+ if (typeof this.callbackOnUpdateDataContent != 'undefined' && this.callbackOnUpdateDataContent != null) {
387
+ this.callbackOnUpdateDataContent(div);
388
+ }
389
+ }
390
+
391
+ static filterRows(table, callback) {
392
+ if (!$.fn.dataTable.isDataTable(table)) {
393
+ return;
394
+ }
395
+
396
+ $.fn.dataTable.ext.search = [];
397
+ //$.fn.dataTable.ext.search.pop();
398
+ var dataTableObject = table.DataTable();
399
+ $.fn.dataTable.ext.search.push(
400
+ function(settings, searchData, index, rowData, counter) {
401
+ return callback($(dataTableObject.row(index).node()));
402
+ }
403
+ );
404
+ dataTableObject.draw();
405
+ }
406
+
407
+ static sort(table, tdSelector) {
408
+ //if (table.find('tbody tr').length > 0 && $.fn.dataTable.isDataTable(table)) {
409
+ if ($.fn.dataTable.isDataTable(table)) {
410
+ let idx = table.find('thead tr '+tdSelector).index();
411
+ if (idx >= 0) {
412
+ table.DataTable().order([idx, 'asc']);
413
+ }
414
+ }
415
+ }
416
+
417
+ }
418
+
419
+ exports.DataTable = DataTable;