@liedekef/ftable 1.0.0 → 1.1.1
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/CHANGES.md +8 -0
- package/ftable.esm.js +139 -100
- package/ftable.js +146 -101
- package/ftable.min.js +3 -3
- package/ftable.umd.js +146 -102
- package/package.json +3 -4
package/ftable.umd.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
|
|
2
|
+
(function (global, factory) {
|
|
3
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
4
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
5
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.FTable = factory());
|
|
6
|
+
}(this, (function () {
|
|
7
|
+
// Modern fTable - Vanilla JS Refactor
|
|
3
8
|
|
|
4
9
|
const JTABLE_DEFAULT_MESSAGES = {
|
|
5
10
|
serverCommunicationError: 'An error occurred while communicating to the server.',
|
|
@@ -654,10 +659,6 @@ class FTableFormBuilder {
|
|
|
654
659
|
}
|
|
655
660
|
});
|
|
656
661
|
|
|
657
|
-
/*if (this.options.formCreated) {
|
|
658
|
-
this.options.formCreated(form, formType, record);
|
|
659
|
-
}*/
|
|
660
|
-
|
|
661
662
|
// Set up dependency listeners after all fields are created
|
|
662
663
|
this.setupDependencyListeners(form);
|
|
663
664
|
|
|
@@ -1336,7 +1337,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1336
1337
|
|
|
1337
1338
|
this.options = this.mergeOptions(options);
|
|
1338
1339
|
this.logger = new FTableLogger(this.options.logLevel);
|
|
1339
|
-
this.userPrefs = new FTableUserPreferences('', this.options.
|
|
1340
|
+
this.userPrefs = new FTableUserPreferences('', this.options.saveUserPreferencesMethod);
|
|
1340
1341
|
this.formBuilder = new FTableFormBuilder(this.options, this);
|
|
1341
1342
|
|
|
1342
1343
|
this.state = {
|
|
@@ -1352,6 +1353,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1352
1353
|
this.elements = {};
|
|
1353
1354
|
this.modals = {};
|
|
1354
1355
|
this.searchTimeout = null; // For debouncing
|
|
1356
|
+
this.lastSortEvent = null;
|
|
1355
1357
|
this._recalculatedOnce = false;
|
|
1356
1358
|
|
|
1357
1359
|
// store it on the DOM too, so people can access it
|
|
@@ -1369,23 +1371,28 @@ class FTable extends FTableEventEmitter {
|
|
|
1369
1371
|
animationsEnabled: true,
|
|
1370
1372
|
loadingAnimationDelay: 1000,
|
|
1371
1373
|
defaultDateFormat: 'yyyy-mm-dd',
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
+
saveUserPreferences: true,
|
|
1375
|
+
saveUserPreferencesMethod: 'localStorage',
|
|
1374
1376
|
defaultSorting: '',
|
|
1375
1377
|
|
|
1376
1378
|
// Paging
|
|
1377
1379
|
paging: false,
|
|
1380
|
+
pageList: 'normal',
|
|
1378
1381
|
pageSize: 10,
|
|
1379
1382
|
gotoPageArea: 'combobox',
|
|
1380
1383
|
|
|
1381
1384
|
// Sorting
|
|
1382
1385
|
sorting: false,
|
|
1383
1386
|
multiSorting: false,
|
|
1387
|
+
multiSortingCtrlKey: true,
|
|
1384
1388
|
|
|
1385
1389
|
// Selection
|
|
1386
1390
|
selecting: false,
|
|
1387
1391
|
multiselect: false,
|
|
1388
1392
|
|
|
1393
|
+
// child tables
|
|
1394
|
+
openChildAsAccordion: false,
|
|
1395
|
+
|
|
1389
1396
|
// Toolbar search
|
|
1390
1397
|
toolbarsearch: false, // Enable/disable toolbar search row
|
|
1391
1398
|
toolbarreset: true, // Show reset button
|
|
@@ -1622,6 +1629,9 @@ class FTable extends FTableEventEmitter {
|
|
|
1622
1629
|
if (field.list === undefined) {
|
|
1623
1630
|
field.list = true;
|
|
1624
1631
|
}
|
|
1632
|
+
if (field.sorting === undefined) {
|
|
1633
|
+
field.sorting = true;
|
|
1634
|
+
}
|
|
1625
1635
|
if (!field.hasOwnProperty('visibility')) {
|
|
1626
1636
|
field.visibility = 'visible';
|
|
1627
1637
|
}
|
|
@@ -1749,9 +1759,9 @@ class FTable extends FTableEventEmitter {
|
|
|
1749
1759
|
});
|
|
1750
1760
|
|
|
1751
1761
|
// Add selecting column if enabled
|
|
1752
|
-
if (this.options.selecting) {
|
|
1762
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
1753
1763
|
const selectHeader = FTableDOMHelper.create('th', {
|
|
1754
|
-
className:
|
|
1764
|
+
className: `ftable-column-header ftable-column-header-select`,
|
|
1755
1765
|
parent: headerRow
|
|
1756
1766
|
});
|
|
1757
1767
|
|
|
@@ -1771,7 +1781,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1771
1781
|
this.columnList.forEach(fieldName => {
|
|
1772
1782
|
const field = this.options.fields[fieldName];
|
|
1773
1783
|
const th = FTableDOMHelper.create('th', {
|
|
1774
|
-
className:
|
|
1784
|
+
className: `ftable-column-header ${field.listClass || ''} ${field.listClassHeader || ''}`,
|
|
1775
1785
|
attributes: { 'data-field-name': fieldName },
|
|
1776
1786
|
parent: headerRow
|
|
1777
1787
|
});
|
|
@@ -1786,6 +1796,10 @@ class FTable extends FTableEventEmitter {
|
|
|
1786
1796
|
parent: th
|
|
1787
1797
|
});
|
|
1788
1798
|
|
|
1799
|
+
if (field.tooltip) {
|
|
1800
|
+
container.setAttribute('title', field.tooltip);
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1789
1803
|
FTableDOMHelper.create('span', {
|
|
1790
1804
|
className: 'ftable-column-header-text',
|
|
1791
1805
|
text: field.title || fieldName,
|
|
@@ -1795,7 +1809,12 @@ class FTable extends FTableEventEmitter {
|
|
|
1795
1809
|
// Make sortable if enabled
|
|
1796
1810
|
if (this.options.sorting && field.sorting !== false) {
|
|
1797
1811
|
FTableDOMHelper.addClass(th, 'ftable-column-header-sortable');
|
|
1798
|
-
th.addEventListener('click', () =>
|
|
1812
|
+
th.addEventListener('click', (e) => {
|
|
1813
|
+
e.preventDefault();
|
|
1814
|
+
// Store event for multiSortingCtrlKey logic
|
|
1815
|
+
this.lastSortEvent = e;
|
|
1816
|
+
this.sortByColumn(fieldName);
|
|
1817
|
+
});
|
|
1799
1818
|
}
|
|
1800
1819
|
|
|
1801
1820
|
// Add resize handler if column resizing is enabled
|
|
@@ -1846,7 +1865,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1846
1865
|
});
|
|
1847
1866
|
|
|
1848
1867
|
// Add empty cell for selecting column if enabled
|
|
1849
|
-
if (this.options.selecting) {
|
|
1868
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
1850
1869
|
FTableDOMHelper.create('th', { parent: searchRow });
|
|
1851
1870
|
}
|
|
1852
1871
|
|
|
@@ -2132,14 +2151,14 @@ class FTable extends FTableEventEmitter {
|
|
|
2132
2151
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
2133
2152
|
|
|
2134
2153
|
// Save column width preference if enabled
|
|
2135
|
-
if (this.options.
|
|
2154
|
+
if (this.options.saveUserPreferences) {
|
|
2136
2155
|
this.saveColumnSettings();
|
|
2137
2156
|
}
|
|
2138
2157
|
};
|
|
2139
2158
|
}
|
|
2140
2159
|
|
|
2141
2160
|
saveColumnSettings() {
|
|
2142
|
-
if (!this.options.
|
|
2161
|
+
if (!this.options.saveUserPreferences) return;
|
|
2143
2162
|
|
|
2144
2163
|
const settings = {};
|
|
2145
2164
|
this.columnList.forEach(fieldName => {
|
|
@@ -2157,7 +2176,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2157
2176
|
}
|
|
2158
2177
|
|
|
2159
2178
|
saveState() {
|
|
2160
|
-
if (!this.options.
|
|
2179
|
+
if (!this.options.saveUserPreferences) return;
|
|
2161
2180
|
|
|
2162
2181
|
const state = {
|
|
2163
2182
|
sorting: this.state.sorting,
|
|
@@ -2168,7 +2187,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2168
2187
|
}
|
|
2169
2188
|
|
|
2170
2189
|
loadColumnSettings() {
|
|
2171
|
-
if (!this.options.
|
|
2190
|
+
if (!this.options.saveUserPreferences) return;
|
|
2172
2191
|
|
|
2173
2192
|
const settingsJson = this.userPrefs.get('column-settings');
|
|
2174
2193
|
if (!settingsJson) return;
|
|
@@ -2188,7 +2207,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2188
2207
|
}
|
|
2189
2208
|
|
|
2190
2209
|
loadState() {
|
|
2191
|
-
if (!this.options.
|
|
2210
|
+
if (!this.options.saveUserPreferences) return;
|
|
2192
2211
|
|
|
2193
2212
|
const stateJson = this.userPrefs.get('table-state');
|
|
2194
2213
|
if (!stateJson) return;
|
|
@@ -2267,9 +2286,6 @@ class FTable extends FTableEventEmitter {
|
|
|
2267
2286
|
onClick: () => {
|
|
2268
2287
|
this.modals.addRecord.close();
|
|
2269
2288
|
this.emit('formClosed', { form: this.currentForm, formType: 'create', record: null });
|
|
2270
|
-
/*if (this.options.formClosed) {
|
|
2271
|
-
this.options.formClosed(this.currentForm, 'create', null);
|
|
2272
|
-
}*/
|
|
2273
2289
|
}
|
|
2274
2290
|
},
|
|
2275
2291
|
{
|
|
@@ -2622,6 +2638,11 @@ class FTable extends FTableEventEmitter {
|
|
|
2622
2638
|
parent: this.elements.toolbarDiv
|
|
2623
2639
|
});
|
|
2624
2640
|
|
|
2641
|
+
// Add title/tooltip if provided
|
|
2642
|
+
if (item.tooltip) {
|
|
2643
|
+
button.setAttribute('title', item.tooltip);
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2625
2646
|
// Add icon if provided
|
|
2626
2647
|
if (item.icon) {
|
|
2627
2648
|
const img = FTableDOMHelper.create('img', {
|
|
@@ -2684,12 +2705,12 @@ class FTable extends FTableEventEmitter {
|
|
|
2684
2705
|
}
|
|
2685
2706
|
|
|
2686
2707
|
setupFTableUserPreferences() {
|
|
2687
|
-
if (this.options.
|
|
2708
|
+
if (this.options.saveUserPreferences) {
|
|
2688
2709
|
const prefix = this.userPrefs.generatePrefix(
|
|
2689
2710
|
this.options.tableId || '',
|
|
2690
2711
|
this.fieldList
|
|
2691
2712
|
);
|
|
2692
|
-
this.userPrefs = new FTableUserPreferences(prefix, this.options.
|
|
2713
|
+
this.userPrefs = new FTableUserPreferences(prefix, this.options.saveUserPreferencesMethod);
|
|
2693
2714
|
|
|
2694
2715
|
// Load saved column settings
|
|
2695
2716
|
this.loadState();
|
|
@@ -2861,7 +2882,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2861
2882
|
row.recordData = record;
|
|
2862
2883
|
|
|
2863
2884
|
// Add selecting checkbox if enabled
|
|
2864
|
-
if (this.options.selecting) {
|
|
2885
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
2865
2886
|
this.addSelectingCell(row);
|
|
2866
2887
|
}
|
|
2867
2888
|
|
|
@@ -3086,10 +3107,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3086
3107
|
this.modals.addRecord.close();
|
|
3087
3108
|
|
|
3088
3109
|
// Call formClosed
|
|
3089
|
-
|
|
3090
|
-
if (this.options.formClosed) {
|
|
3091
|
-
this.options.formClosed(this.currentForm, 'create', null);
|
|
3092
|
-
}
|
|
3110
|
+
this.emit('formClosed', { form: this.currentForm, formType: 'create', record: null });
|
|
3093
3111
|
|
|
3094
3112
|
if (result.Message) {
|
|
3095
3113
|
this.showInfo(result.Message);
|
|
@@ -3136,17 +3154,14 @@ class FTable extends FTableEventEmitter {
|
|
|
3136
3154
|
this.modals.editRecord.close();
|
|
3137
3155
|
|
|
3138
3156
|
// Call formClosed
|
|
3139
|
-
|
|
3140
|
-
if (this.options.formClosed) {
|
|
3141
|
-
this.options.formClosed(this.currentForm, 'edit', this.currentEditingRow.recordData);
|
|
3142
|
-
}
|
|
3157
|
+
this.emit('formClosed', { form: this.currentForm, formType: 'edit', record: this.currentEditingRow.recordData });
|
|
3143
3158
|
|
|
3144
3159
|
// Update the row with new data
|
|
3145
3160
|
this.updateRowData(this.currentEditingRow, result.Record || formData);
|
|
3146
3161
|
if (result.Message) {
|
|
3147
3162
|
this.showInfo(result.Message);
|
|
3148
3163
|
}
|
|
3149
|
-
this.emit('recordUpdated', { record: result.Record || formData });
|
|
3164
|
+
this.emit('recordUpdated', { record: result.Record || formData, row: this.currentEditingRow });
|
|
3150
3165
|
} else {
|
|
3151
3166
|
this.showError(result.Message || 'Update failed');
|
|
3152
3167
|
}
|
|
@@ -3452,25 +3467,42 @@ class FTable extends FTableEventEmitter {
|
|
|
3452
3467
|
|
|
3453
3468
|
// Sorting Methods
|
|
3454
3469
|
sortByColumn(fieldName) {
|
|
3470
|
+
const field = this.options.fields[fieldName];
|
|
3471
|
+
|
|
3472
|
+
if (!field || field.sorting === false) return;
|
|
3473
|
+
|
|
3455
3474
|
const existingSortIndex = this.state.sorting.findIndex(s => s.fieldName === fieldName);
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
this.state.sorting = [];
|
|
3459
|
-
}
|
|
3460
|
-
|
|
3475
|
+
let isSorted = true;
|
|
3476
|
+
let newDirection = 'ASC';
|
|
3461
3477
|
if (existingSortIndex >= 0) {
|
|
3462
|
-
const
|
|
3463
|
-
if (
|
|
3464
|
-
|
|
3478
|
+
const wasAsc = this.state.sorting[existingSortIndex].direction === 'ASC';
|
|
3479
|
+
if (wasAsc) {
|
|
3480
|
+
newDirection = 'DESC';
|
|
3481
|
+
this.state.sorting[existingSortIndex].direction = newDirection;
|
|
3465
3482
|
} else {
|
|
3466
|
-
this.state.sorting.splice(existingSortIndex,
|
|
3483
|
+
this.state.sorting.splice(existingSortIndex,1);
|
|
3484
|
+
isSorted = false;
|
|
3467
3485
|
}
|
|
3468
3486
|
} else {
|
|
3469
|
-
this.state.sorting.push({ fieldName, direction:
|
|
3487
|
+
this.state.sorting.push({ fieldName, direction: newDirection });
|
|
3470
3488
|
}
|
|
3471
|
-
|
|
3489
|
+
|
|
3490
|
+
// Handle multiSortingCtrlKey: did user press Ctrl/Cmd?
|
|
3491
|
+
const isCtrlPressed = this.lastSortEvent?.ctrlKey || this.lastSortEvent?.metaKey; // metaKey for Mac
|
|
3492
|
+
|
|
3493
|
+
if (this.options.multiSorting) {
|
|
3494
|
+
// If multiSorting is enabled, respect multiSortingCtrlKey
|
|
3495
|
+
if (this.options.multiSortingCtrlKey && !isCtrlPressed) {
|
|
3496
|
+
// Not using Ctrl → treat as single sort (clear others)
|
|
3497
|
+
this.state.sorting = isSorted ? [{ fieldName, direction: newDirection }] : [];
|
|
3498
|
+
}
|
|
3499
|
+
} else {
|
|
3500
|
+
// If multiSorting is disabled, always clear other sorts
|
|
3501
|
+
this.state.sorting = isSorted ? [{ fieldName, direction: newDirection }] : [];
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3472
3504
|
this.updateSortingHeaders();
|
|
3473
|
-
this.load();
|
|
3505
|
+
this.load();
|
|
3474
3506
|
this.saveState();
|
|
3475
3507
|
}
|
|
3476
3508
|
|
|
@@ -3529,27 +3561,29 @@ class FTable extends FTableEventEmitter {
|
|
|
3529
3561
|
this.createPageButton('‹', this.state.currentPage - 1, this.state.currentPage === 1, 'ftable-page-number-previous');
|
|
3530
3562
|
|
|
3531
3563
|
// Page numbers
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3564
|
+
if (this.options.pageList == 'normal') {
|
|
3565
|
+
const pageNumbers = this.calculatePageNumbers(totalPages);
|
|
3566
|
+
let lastNumber = 0;
|
|
3567
|
+
|
|
3568
|
+
pageNumbers.forEach(pageNum => {
|
|
3569
|
+
if (pageNum - lastNumber > 1) {
|
|
3570
|
+
FTableDOMHelper.create('span', {
|
|
3571
|
+
className: 'ftable-page-number-space',
|
|
3572
|
+
text: '...',
|
|
3573
|
+
parent: this.elements.pagingListArea
|
|
3574
|
+
});
|
|
3575
|
+
}
|
|
3576
|
+
|
|
3577
|
+
this.createPageButton(
|
|
3578
|
+
pageNum.toString(),
|
|
3579
|
+
pageNum,
|
|
3580
|
+
false,
|
|
3581
|
+
pageNum === this.state.currentPage ? 'ftable-page-number ftable-page-number-active' : 'ftable-page-number'
|
|
3582
|
+
);
|
|
3583
|
+
|
|
3584
|
+
lastNumber = pageNum;
|
|
3585
|
+
});
|
|
3586
|
+
}
|
|
3553
3587
|
|
|
3554
3588
|
// Next and Last buttons
|
|
3555
3589
|
this.createPageButton('›', this.state.currentPage + 1, this.state.currentPage >= totalPages, 'ftable-page-number-next');
|
|
@@ -3957,7 +3991,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3957
3991
|
if (columnIndex >= 0) {
|
|
3958
3992
|
// Calculate actual column index (accounting for selecting column)
|
|
3959
3993
|
let actualIndex = columnIndex + 1; // CSS nth-child is 1-based
|
|
3960
|
-
if (this.options.selecting) {
|
|
3994
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
3961
3995
|
actualIndex += 1; // Account for selecting column
|
|
3962
3996
|
}
|
|
3963
3997
|
|
|
@@ -3974,7 +4008,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3974
4008
|
}
|
|
3975
4009
|
|
|
3976
4010
|
// Save column settings
|
|
3977
|
-
if (this.options.
|
|
4011
|
+
if (this.options.saveUserPreferences) {
|
|
3978
4012
|
this.saveColumnSettings();
|
|
3979
4013
|
this.saveState(); // sorting might affect state
|
|
3980
4014
|
}
|
|
@@ -4172,27 +4206,6 @@ class FTable extends FTableEventEmitter {
|
|
|
4172
4206
|
});
|
|
4173
4207
|
}
|
|
4174
4208
|
|
|
4175
|
-
// Performance optimization for large datasets
|
|
4176
|
-
enableVirtualScrolling(options = {}) {
|
|
4177
|
-
const virtualOptions = {
|
|
4178
|
-
rowHeight: 40,
|
|
4179
|
-
overscan: 5,
|
|
4180
|
-
...options
|
|
4181
|
-
};
|
|
4182
|
-
|
|
4183
|
-
// This would implement virtual scrolling for performance with large datasets
|
|
4184
|
-
// Simplified version - full implementation would be more complex
|
|
4185
|
-
this.virtualScrolling = {
|
|
4186
|
-
enabled: true,
|
|
4187
|
-
...virtualOptions,
|
|
4188
|
-
visibleRange: { start: 0, end: 0 },
|
|
4189
|
-
scrollContainer: null
|
|
4190
|
-
};
|
|
4191
|
-
|
|
4192
|
-
// Replace table body with virtual scroll container
|
|
4193
|
-
// Implementation would calculate visible rows and only render those
|
|
4194
|
-
}
|
|
4195
|
-
|
|
4196
4209
|
// Real-time updates via WebSocket
|
|
4197
4210
|
enableRealTimeUpdates(websocketUrl) {
|
|
4198
4211
|
if (!websocketUrl) return;
|
|
@@ -4316,6 +4329,15 @@ class FTable extends FTableEventEmitter {
|
|
|
4316
4329
|
return this;
|
|
4317
4330
|
}
|
|
4318
4331
|
|
|
4332
|
+
editRecordByKey(keyValue) {
|
|
4333
|
+
const row = this.getRowByKey(keyValue);
|
|
4334
|
+
if (row) {
|
|
4335
|
+
this.editRecord(row);
|
|
4336
|
+
} else {
|
|
4337
|
+
this.showError(`Record with key '${keyValue}' not found`);
|
|
4338
|
+
}
|
|
4339
|
+
}
|
|
4340
|
+
|
|
4319
4341
|
async editRecordViaAjax(recordId, url, params = {}) {
|
|
4320
4342
|
try {
|
|
4321
4343
|
// Get the actual key field name (e.g., 'asset_id', 'user_id', etc.)
|
|
@@ -4355,6 +4377,10 @@ class FTable extends FTableEventEmitter {
|
|
|
4355
4377
|
}
|
|
4356
4378
|
|
|
4357
4379
|
openChildTable(parentRow, childOptions, onInit) {
|
|
4380
|
+
// Close any open child tables if accordion mode
|
|
4381
|
+
if (this.options.openChildAsAccordion) {
|
|
4382
|
+
this.closeAllChildTables();
|
|
4383
|
+
}
|
|
4358
4384
|
// Prevent multiple child tables
|
|
4359
4385
|
this.closeChildTable(parentRow);
|
|
4360
4386
|
|
|
@@ -4423,6 +4449,31 @@ class FTable extends FTableEventEmitter {
|
|
|
4423
4449
|
}
|
|
4424
4450
|
}
|
|
4425
4451
|
|
|
4452
|
+
closeAllChildTables() {
|
|
4453
|
+
Object.values(this.elements.tableRows).forEach(row => {
|
|
4454
|
+
if (row.childTable) {
|
|
4455
|
+
this.closeChildTable(row);
|
|
4456
|
+
}
|
|
4457
|
+
});
|
|
4458
|
+
}
|
|
4459
|
+
|
|
4460
|
+
getSortingInfo() {
|
|
4461
|
+
// Build sorted fields list with translated directions
|
|
4462
|
+
const messages = this.options.messages || {};
|
|
4463
|
+
const sortingInfo = this.state.sorting.map(s => {
|
|
4464
|
+
const field = this.options.fields[s.fieldName];
|
|
4465
|
+
const title = field?.title || s.fieldName;
|
|
4466
|
+
|
|
4467
|
+
// Translate direction
|
|
4468
|
+
const directionText = s.direction === 'ASC'
|
|
4469
|
+
? (messages.ascending || 'ascending')
|
|
4470
|
+
: (messages.descending || 'descending');
|
|
4471
|
+
|
|
4472
|
+
return `${title} (${directionText})`;
|
|
4473
|
+
}).join(', ');
|
|
4474
|
+
return sortingInfo;
|
|
4475
|
+
}
|
|
4476
|
+
|
|
4426
4477
|
renderSortingInfo() {
|
|
4427
4478
|
if (!this.options.sortingInfoSelector || !this.options.sorting) return;
|
|
4428
4479
|
|
|
@@ -4444,20 +4495,10 @@ class FTable extends FTableEventEmitter {
|
|
|
4444
4495
|
}
|
|
4445
4496
|
|
|
4446
4497
|
// Build sorted fields list with translated directions
|
|
4447
|
-
const
|
|
4448
|
-
const field = this.options.fields[s.fieldName];
|
|
4449
|
-
const title = field?.title || s.fieldName;
|
|
4450
|
-
|
|
4451
|
-
// Translate direction
|
|
4452
|
-
const directionText = s.direction === 'ASC'
|
|
4453
|
-
? (messages.ascending || 'ascending')
|
|
4454
|
-
: (messages.descending || 'descending');
|
|
4455
|
-
|
|
4456
|
-
return `${title} (${directionText})`;
|
|
4457
|
-
}).join(', ');
|
|
4498
|
+
const sortingInfo = this.getSortingInfo();
|
|
4458
4499
|
|
|
4459
4500
|
// Combine with prefix and suffix
|
|
4460
|
-
container.innerHTML = `${prefix}${
|
|
4501
|
+
container.innerHTML = `${prefix}${sortingInfo}${suffix}`;
|
|
4461
4502
|
|
|
4462
4503
|
// Add reset sorting button
|
|
4463
4504
|
if (this.state.sorting.length > 0) {
|
|
@@ -4748,3 +4789,6 @@ table.load();
|
|
|
4748
4789
|
*/
|
|
4749
4790
|
|
|
4750
4791
|
window.FTable = FTable;
|
|
4792
|
+
|
|
4793
|
+
return FTable;
|
|
4794
|
+
})));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liedekef/ftable",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Modern, lightweight, jQuery-free CRUD table for dynamic AJAX-powered tables.",
|
|
5
5
|
"main": "ftable.js",
|
|
6
6
|
"module": "ftable.esm.js",
|
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
"README.md"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "npm run build:
|
|
19
|
-
"build:
|
|
20
|
-
"build:umd": "echo '/* UMD wrapper will go here */' > ftable.umd.js && cat ftable.js >> ftable.umd.js",
|
|
18
|
+
"build": "npm run build:esmumd && npm run build:min",
|
|
19
|
+
"build:esmumd": "node build.mjs",
|
|
21
20
|
"build:min": "uglifyjs ftable.js -o ftable.min.js --compress --mangle",
|
|
22
21
|
"prepublishOnly": "npm run build"
|
|
23
22
|
},
|