@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/CHANGES.md
ADDED
package/ftable.esm.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
// Modern fTable - Vanilla JS Refactor
|
|
2
3
|
|
|
3
4
|
const JTABLE_DEFAULT_MESSAGES = {
|
|
@@ -653,10 +654,6 @@ class FTableFormBuilder {
|
|
|
653
654
|
}
|
|
654
655
|
});
|
|
655
656
|
|
|
656
|
-
/*if (this.options.formCreated) {
|
|
657
|
-
this.options.formCreated(form, formType, record);
|
|
658
|
-
}*/
|
|
659
|
-
|
|
660
657
|
// Set up dependency listeners after all fields are created
|
|
661
658
|
this.setupDependencyListeners(form);
|
|
662
659
|
|
|
@@ -1335,7 +1332,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1335
1332
|
|
|
1336
1333
|
this.options = this.mergeOptions(options);
|
|
1337
1334
|
this.logger = new FTableLogger(this.options.logLevel);
|
|
1338
|
-
this.userPrefs = new FTableUserPreferences('', this.options.
|
|
1335
|
+
this.userPrefs = new FTableUserPreferences('', this.options.saveUserPreferencesMethod);
|
|
1339
1336
|
this.formBuilder = new FTableFormBuilder(this.options, this);
|
|
1340
1337
|
|
|
1341
1338
|
this.state = {
|
|
@@ -1351,6 +1348,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1351
1348
|
this.elements = {};
|
|
1352
1349
|
this.modals = {};
|
|
1353
1350
|
this.searchTimeout = null; // For debouncing
|
|
1351
|
+
this.lastSortEvent = null;
|
|
1354
1352
|
this._recalculatedOnce = false;
|
|
1355
1353
|
|
|
1356
1354
|
// store it on the DOM too, so people can access it
|
|
@@ -1368,23 +1366,28 @@ class FTable extends FTableEventEmitter {
|
|
|
1368
1366
|
animationsEnabled: true,
|
|
1369
1367
|
loadingAnimationDelay: 1000,
|
|
1370
1368
|
defaultDateFormat: 'yyyy-mm-dd',
|
|
1371
|
-
|
|
1372
|
-
|
|
1369
|
+
saveUserPreferences: true,
|
|
1370
|
+
saveUserPreferencesMethod: 'localStorage',
|
|
1373
1371
|
defaultSorting: '',
|
|
1374
1372
|
|
|
1375
1373
|
// Paging
|
|
1376
1374
|
paging: false,
|
|
1375
|
+
pageList: 'normal',
|
|
1377
1376
|
pageSize: 10,
|
|
1378
1377
|
gotoPageArea: 'combobox',
|
|
1379
1378
|
|
|
1380
1379
|
// Sorting
|
|
1381
1380
|
sorting: false,
|
|
1382
1381
|
multiSorting: false,
|
|
1382
|
+
multiSortingCtrlKey: true,
|
|
1383
1383
|
|
|
1384
1384
|
// Selection
|
|
1385
1385
|
selecting: false,
|
|
1386
1386
|
multiselect: false,
|
|
1387
1387
|
|
|
1388
|
+
// child tables
|
|
1389
|
+
openChildAsAccordion: false,
|
|
1390
|
+
|
|
1388
1391
|
// Toolbar search
|
|
1389
1392
|
toolbarsearch: false, // Enable/disable toolbar search row
|
|
1390
1393
|
toolbarreset: true, // Show reset button
|
|
@@ -1621,6 +1624,9 @@ class FTable extends FTableEventEmitter {
|
|
|
1621
1624
|
if (field.list === undefined) {
|
|
1622
1625
|
field.list = true;
|
|
1623
1626
|
}
|
|
1627
|
+
if (field.sorting === undefined) {
|
|
1628
|
+
field.sorting = true;
|
|
1629
|
+
}
|
|
1624
1630
|
if (!field.hasOwnProperty('visibility')) {
|
|
1625
1631
|
field.visibility = 'visible';
|
|
1626
1632
|
}
|
|
@@ -1748,9 +1754,9 @@ class FTable extends FTableEventEmitter {
|
|
|
1748
1754
|
});
|
|
1749
1755
|
|
|
1750
1756
|
// Add selecting column if enabled
|
|
1751
|
-
if (this.options.selecting) {
|
|
1757
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
1752
1758
|
const selectHeader = FTableDOMHelper.create('th', {
|
|
1753
|
-
className:
|
|
1759
|
+
className: `ftable-column-header ftable-column-header-select`,
|
|
1754
1760
|
parent: headerRow
|
|
1755
1761
|
});
|
|
1756
1762
|
|
|
@@ -1770,7 +1776,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1770
1776
|
this.columnList.forEach(fieldName => {
|
|
1771
1777
|
const field = this.options.fields[fieldName];
|
|
1772
1778
|
const th = FTableDOMHelper.create('th', {
|
|
1773
|
-
className:
|
|
1779
|
+
className: `ftable-column-header ${field.listClass || ''} ${field.listClassHeader || ''}`,
|
|
1774
1780
|
attributes: { 'data-field-name': fieldName },
|
|
1775
1781
|
parent: headerRow
|
|
1776
1782
|
});
|
|
@@ -1785,6 +1791,10 @@ class FTable extends FTableEventEmitter {
|
|
|
1785
1791
|
parent: th
|
|
1786
1792
|
});
|
|
1787
1793
|
|
|
1794
|
+
if (field.tooltip) {
|
|
1795
|
+
container.setAttribute('title', field.tooltip);
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1788
1798
|
FTableDOMHelper.create('span', {
|
|
1789
1799
|
className: 'ftable-column-header-text',
|
|
1790
1800
|
text: field.title || fieldName,
|
|
@@ -1794,7 +1804,12 @@ class FTable extends FTableEventEmitter {
|
|
|
1794
1804
|
// Make sortable if enabled
|
|
1795
1805
|
if (this.options.sorting && field.sorting !== false) {
|
|
1796
1806
|
FTableDOMHelper.addClass(th, 'ftable-column-header-sortable');
|
|
1797
|
-
th.addEventListener('click', () =>
|
|
1807
|
+
th.addEventListener('click', (e) => {
|
|
1808
|
+
e.preventDefault();
|
|
1809
|
+
// Store event for multiSortingCtrlKey logic
|
|
1810
|
+
this.lastSortEvent = e;
|
|
1811
|
+
this.sortByColumn(fieldName);
|
|
1812
|
+
});
|
|
1798
1813
|
}
|
|
1799
1814
|
|
|
1800
1815
|
// Add resize handler if column resizing is enabled
|
|
@@ -1845,7 +1860,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1845
1860
|
});
|
|
1846
1861
|
|
|
1847
1862
|
// Add empty cell for selecting column if enabled
|
|
1848
|
-
if (this.options.selecting) {
|
|
1863
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
1849
1864
|
FTableDOMHelper.create('th', { parent: searchRow });
|
|
1850
1865
|
}
|
|
1851
1866
|
|
|
@@ -2131,14 +2146,14 @@ class FTable extends FTableEventEmitter {
|
|
|
2131
2146
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
2132
2147
|
|
|
2133
2148
|
// Save column width preference if enabled
|
|
2134
|
-
if (this.options.
|
|
2149
|
+
if (this.options.saveUserPreferences) {
|
|
2135
2150
|
this.saveColumnSettings();
|
|
2136
2151
|
}
|
|
2137
2152
|
};
|
|
2138
2153
|
}
|
|
2139
2154
|
|
|
2140
2155
|
saveColumnSettings() {
|
|
2141
|
-
if (!this.options.
|
|
2156
|
+
if (!this.options.saveUserPreferences) return;
|
|
2142
2157
|
|
|
2143
2158
|
const settings = {};
|
|
2144
2159
|
this.columnList.forEach(fieldName => {
|
|
@@ -2156,7 +2171,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2156
2171
|
}
|
|
2157
2172
|
|
|
2158
2173
|
saveState() {
|
|
2159
|
-
if (!this.options.
|
|
2174
|
+
if (!this.options.saveUserPreferences) return;
|
|
2160
2175
|
|
|
2161
2176
|
const state = {
|
|
2162
2177
|
sorting: this.state.sorting,
|
|
@@ -2167,7 +2182,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2167
2182
|
}
|
|
2168
2183
|
|
|
2169
2184
|
loadColumnSettings() {
|
|
2170
|
-
if (!this.options.
|
|
2185
|
+
if (!this.options.saveUserPreferences) return;
|
|
2171
2186
|
|
|
2172
2187
|
const settingsJson = this.userPrefs.get('column-settings');
|
|
2173
2188
|
if (!settingsJson) return;
|
|
@@ -2187,7 +2202,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2187
2202
|
}
|
|
2188
2203
|
|
|
2189
2204
|
loadState() {
|
|
2190
|
-
if (!this.options.
|
|
2205
|
+
if (!this.options.saveUserPreferences) return;
|
|
2191
2206
|
|
|
2192
2207
|
const stateJson = this.userPrefs.get('table-state');
|
|
2193
2208
|
if (!stateJson) return;
|
|
@@ -2266,9 +2281,6 @@ class FTable extends FTableEventEmitter {
|
|
|
2266
2281
|
onClick: () => {
|
|
2267
2282
|
this.modals.addRecord.close();
|
|
2268
2283
|
this.emit('formClosed', { form: this.currentForm, formType: 'create', record: null });
|
|
2269
|
-
/*if (this.options.formClosed) {
|
|
2270
|
-
this.options.formClosed(this.currentForm, 'create', null);
|
|
2271
|
-
}*/
|
|
2272
2284
|
}
|
|
2273
2285
|
},
|
|
2274
2286
|
{
|
|
@@ -2621,6 +2633,11 @@ class FTable extends FTableEventEmitter {
|
|
|
2621
2633
|
parent: this.elements.toolbarDiv
|
|
2622
2634
|
});
|
|
2623
2635
|
|
|
2636
|
+
// Add title/tooltip if provided
|
|
2637
|
+
if (item.tooltip) {
|
|
2638
|
+
button.setAttribute('title', item.tooltip);
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2624
2641
|
// Add icon if provided
|
|
2625
2642
|
if (item.icon) {
|
|
2626
2643
|
const img = FTableDOMHelper.create('img', {
|
|
@@ -2683,12 +2700,12 @@ class FTable extends FTableEventEmitter {
|
|
|
2683
2700
|
}
|
|
2684
2701
|
|
|
2685
2702
|
setupFTableUserPreferences() {
|
|
2686
|
-
if (this.options.
|
|
2703
|
+
if (this.options.saveUserPreferences) {
|
|
2687
2704
|
const prefix = this.userPrefs.generatePrefix(
|
|
2688
2705
|
this.options.tableId || '',
|
|
2689
2706
|
this.fieldList
|
|
2690
2707
|
);
|
|
2691
|
-
this.userPrefs = new FTableUserPreferences(prefix, this.options.
|
|
2708
|
+
this.userPrefs = new FTableUserPreferences(prefix, this.options.saveUserPreferencesMethod);
|
|
2692
2709
|
|
|
2693
2710
|
// Load saved column settings
|
|
2694
2711
|
this.loadState();
|
|
@@ -2860,7 +2877,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2860
2877
|
row.recordData = record;
|
|
2861
2878
|
|
|
2862
2879
|
// Add selecting checkbox if enabled
|
|
2863
|
-
if (this.options.selecting) {
|
|
2880
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
2864
2881
|
this.addSelectingCell(row);
|
|
2865
2882
|
}
|
|
2866
2883
|
|
|
@@ -3085,10 +3102,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3085
3102
|
this.modals.addRecord.close();
|
|
3086
3103
|
|
|
3087
3104
|
// Call formClosed
|
|
3088
|
-
|
|
3089
|
-
if (this.options.formClosed) {
|
|
3090
|
-
this.options.formClosed(this.currentForm, 'create', null);
|
|
3091
|
-
}
|
|
3105
|
+
this.emit('formClosed', { form: this.currentForm, formType: 'create', record: null });
|
|
3092
3106
|
|
|
3093
3107
|
if (result.Message) {
|
|
3094
3108
|
this.showInfo(result.Message);
|
|
@@ -3135,17 +3149,14 @@ class FTable extends FTableEventEmitter {
|
|
|
3135
3149
|
this.modals.editRecord.close();
|
|
3136
3150
|
|
|
3137
3151
|
// Call formClosed
|
|
3138
|
-
|
|
3139
|
-
if (this.options.formClosed) {
|
|
3140
|
-
this.options.formClosed(this.currentForm, 'edit', this.currentEditingRow.recordData);
|
|
3141
|
-
}
|
|
3152
|
+
this.emit('formClosed', { form: this.currentForm, formType: 'edit', record: this.currentEditingRow.recordData });
|
|
3142
3153
|
|
|
3143
3154
|
// Update the row with new data
|
|
3144
3155
|
this.updateRowData(this.currentEditingRow, result.Record || formData);
|
|
3145
3156
|
if (result.Message) {
|
|
3146
3157
|
this.showInfo(result.Message);
|
|
3147
3158
|
}
|
|
3148
|
-
this.emit('recordUpdated', { record: result.Record || formData });
|
|
3159
|
+
this.emit('recordUpdated', { record: result.Record || formData, row: this.currentEditingRow });
|
|
3149
3160
|
} else {
|
|
3150
3161
|
this.showError(result.Message || 'Update failed');
|
|
3151
3162
|
}
|
|
@@ -3451,25 +3462,42 @@ class FTable extends FTableEventEmitter {
|
|
|
3451
3462
|
|
|
3452
3463
|
// Sorting Methods
|
|
3453
3464
|
sortByColumn(fieldName) {
|
|
3465
|
+
const field = this.options.fields[fieldName];
|
|
3466
|
+
|
|
3467
|
+
if (!field || field.sorting === false) return;
|
|
3468
|
+
|
|
3454
3469
|
const existingSortIndex = this.state.sorting.findIndex(s => s.fieldName === fieldName);
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
this.state.sorting = [];
|
|
3458
|
-
}
|
|
3459
|
-
|
|
3470
|
+
let isSorted = true;
|
|
3471
|
+
let newDirection = 'ASC';
|
|
3460
3472
|
if (existingSortIndex >= 0) {
|
|
3461
|
-
const
|
|
3462
|
-
if (
|
|
3463
|
-
|
|
3473
|
+
const wasAsc = this.state.sorting[existingSortIndex].direction === 'ASC';
|
|
3474
|
+
if (wasAsc) {
|
|
3475
|
+
newDirection = 'DESC';
|
|
3476
|
+
this.state.sorting[existingSortIndex].direction = newDirection;
|
|
3464
3477
|
} else {
|
|
3465
|
-
this.state.sorting.splice(existingSortIndex,
|
|
3478
|
+
this.state.sorting.splice(existingSortIndex,1);
|
|
3479
|
+
isSorted = false;
|
|
3466
3480
|
}
|
|
3467
3481
|
} else {
|
|
3468
|
-
this.state.sorting.push({ fieldName, direction:
|
|
3482
|
+
this.state.sorting.push({ fieldName, direction: newDirection });
|
|
3469
3483
|
}
|
|
3470
|
-
|
|
3484
|
+
|
|
3485
|
+
// Handle multiSortingCtrlKey: did user press Ctrl/Cmd?
|
|
3486
|
+
const isCtrlPressed = this.lastSortEvent?.ctrlKey || this.lastSortEvent?.metaKey; // metaKey for Mac
|
|
3487
|
+
|
|
3488
|
+
if (this.options.multiSorting) {
|
|
3489
|
+
// If multiSorting is enabled, respect multiSortingCtrlKey
|
|
3490
|
+
if (this.options.multiSortingCtrlKey && !isCtrlPressed) {
|
|
3491
|
+
// Not using Ctrl → treat as single sort (clear others)
|
|
3492
|
+
this.state.sorting = isSorted ? [{ fieldName, direction: newDirection }] : [];
|
|
3493
|
+
}
|
|
3494
|
+
} else {
|
|
3495
|
+
// If multiSorting is disabled, always clear other sorts
|
|
3496
|
+
this.state.sorting = isSorted ? [{ fieldName, direction: newDirection }] : [];
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3471
3499
|
this.updateSortingHeaders();
|
|
3472
|
-
this.load();
|
|
3500
|
+
this.load();
|
|
3473
3501
|
this.saveState();
|
|
3474
3502
|
}
|
|
3475
3503
|
|
|
@@ -3528,27 +3556,29 @@ class FTable extends FTableEventEmitter {
|
|
|
3528
3556
|
this.createPageButton('‹', this.state.currentPage - 1, this.state.currentPage === 1, 'ftable-page-number-previous');
|
|
3529
3557
|
|
|
3530
3558
|
// Page numbers
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3559
|
+
if (this.options.pageList == 'normal') {
|
|
3560
|
+
const pageNumbers = this.calculatePageNumbers(totalPages);
|
|
3561
|
+
let lastNumber = 0;
|
|
3562
|
+
|
|
3563
|
+
pageNumbers.forEach(pageNum => {
|
|
3564
|
+
if (pageNum - lastNumber > 1) {
|
|
3565
|
+
FTableDOMHelper.create('span', {
|
|
3566
|
+
className: 'ftable-page-number-space',
|
|
3567
|
+
text: '...',
|
|
3568
|
+
parent: this.elements.pagingListArea
|
|
3569
|
+
});
|
|
3570
|
+
}
|
|
3571
|
+
|
|
3572
|
+
this.createPageButton(
|
|
3573
|
+
pageNum.toString(),
|
|
3574
|
+
pageNum,
|
|
3575
|
+
false,
|
|
3576
|
+
pageNum === this.state.currentPage ? 'ftable-page-number ftable-page-number-active' : 'ftable-page-number'
|
|
3577
|
+
);
|
|
3578
|
+
|
|
3579
|
+
lastNumber = pageNum;
|
|
3580
|
+
});
|
|
3581
|
+
}
|
|
3552
3582
|
|
|
3553
3583
|
// Next and Last buttons
|
|
3554
3584
|
this.createPageButton('›', this.state.currentPage + 1, this.state.currentPage >= totalPages, 'ftable-page-number-next');
|
|
@@ -3956,7 +3986,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3956
3986
|
if (columnIndex >= 0) {
|
|
3957
3987
|
// Calculate actual column index (accounting for selecting column)
|
|
3958
3988
|
let actualIndex = columnIndex + 1; // CSS nth-child is 1-based
|
|
3959
|
-
if (this.options.selecting) {
|
|
3989
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
3960
3990
|
actualIndex += 1; // Account for selecting column
|
|
3961
3991
|
}
|
|
3962
3992
|
|
|
@@ -3973,7 +4003,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3973
4003
|
}
|
|
3974
4004
|
|
|
3975
4005
|
// Save column settings
|
|
3976
|
-
if (this.options.
|
|
4006
|
+
if (this.options.saveUserPreferences) {
|
|
3977
4007
|
this.saveColumnSettings();
|
|
3978
4008
|
this.saveState(); // sorting might affect state
|
|
3979
4009
|
}
|
|
@@ -4171,27 +4201,6 @@ class FTable extends FTableEventEmitter {
|
|
|
4171
4201
|
});
|
|
4172
4202
|
}
|
|
4173
4203
|
|
|
4174
|
-
// Performance optimization for large datasets
|
|
4175
|
-
enableVirtualScrolling(options = {}) {
|
|
4176
|
-
const virtualOptions = {
|
|
4177
|
-
rowHeight: 40,
|
|
4178
|
-
overscan: 5,
|
|
4179
|
-
...options
|
|
4180
|
-
};
|
|
4181
|
-
|
|
4182
|
-
// This would implement virtual scrolling for performance with large datasets
|
|
4183
|
-
// Simplified version - full implementation would be more complex
|
|
4184
|
-
this.virtualScrolling = {
|
|
4185
|
-
enabled: true,
|
|
4186
|
-
...virtualOptions,
|
|
4187
|
-
visibleRange: { start: 0, end: 0 },
|
|
4188
|
-
scrollContainer: null
|
|
4189
|
-
};
|
|
4190
|
-
|
|
4191
|
-
// Replace table body with virtual scroll container
|
|
4192
|
-
// Implementation would calculate visible rows and only render those
|
|
4193
|
-
}
|
|
4194
|
-
|
|
4195
4204
|
// Real-time updates via WebSocket
|
|
4196
4205
|
enableRealTimeUpdates(websocketUrl) {
|
|
4197
4206
|
if (!websocketUrl) return;
|
|
@@ -4315,6 +4324,15 @@ class FTable extends FTableEventEmitter {
|
|
|
4315
4324
|
return this;
|
|
4316
4325
|
}
|
|
4317
4326
|
|
|
4327
|
+
editRecordByKey(keyValue) {
|
|
4328
|
+
const row = this.getRowByKey(keyValue);
|
|
4329
|
+
if (row) {
|
|
4330
|
+
this.editRecord(row);
|
|
4331
|
+
} else {
|
|
4332
|
+
this.showError(`Record with key '${keyValue}' not found`);
|
|
4333
|
+
}
|
|
4334
|
+
}
|
|
4335
|
+
|
|
4318
4336
|
async editRecordViaAjax(recordId, url, params = {}) {
|
|
4319
4337
|
try {
|
|
4320
4338
|
// Get the actual key field name (e.g., 'asset_id', 'user_id', etc.)
|
|
@@ -4354,6 +4372,10 @@ class FTable extends FTableEventEmitter {
|
|
|
4354
4372
|
}
|
|
4355
4373
|
|
|
4356
4374
|
openChildTable(parentRow, childOptions, onInit) {
|
|
4375
|
+
// Close any open child tables if accordion mode
|
|
4376
|
+
if (this.options.openChildAsAccordion) {
|
|
4377
|
+
this.closeAllChildTables();
|
|
4378
|
+
}
|
|
4357
4379
|
// Prevent multiple child tables
|
|
4358
4380
|
this.closeChildTable(parentRow);
|
|
4359
4381
|
|
|
@@ -4422,6 +4444,31 @@ class FTable extends FTableEventEmitter {
|
|
|
4422
4444
|
}
|
|
4423
4445
|
}
|
|
4424
4446
|
|
|
4447
|
+
closeAllChildTables() {
|
|
4448
|
+
Object.values(this.elements.tableRows).forEach(row => {
|
|
4449
|
+
if (row.childTable) {
|
|
4450
|
+
this.closeChildTable(row);
|
|
4451
|
+
}
|
|
4452
|
+
});
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
getSortingInfo() {
|
|
4456
|
+
// Build sorted fields list with translated directions
|
|
4457
|
+
const messages = this.options.messages || {};
|
|
4458
|
+
const sortingInfo = this.state.sorting.map(s => {
|
|
4459
|
+
const field = this.options.fields[s.fieldName];
|
|
4460
|
+
const title = field?.title || s.fieldName;
|
|
4461
|
+
|
|
4462
|
+
// Translate direction
|
|
4463
|
+
const directionText = s.direction === 'ASC'
|
|
4464
|
+
? (messages.ascending || 'ascending')
|
|
4465
|
+
: (messages.descending || 'descending');
|
|
4466
|
+
|
|
4467
|
+
return `${title} (${directionText})`;
|
|
4468
|
+
}).join(', ');
|
|
4469
|
+
return sortingInfo;
|
|
4470
|
+
}
|
|
4471
|
+
|
|
4425
4472
|
renderSortingInfo() {
|
|
4426
4473
|
if (!this.options.sortingInfoSelector || !this.options.sorting) return;
|
|
4427
4474
|
|
|
@@ -4443,20 +4490,10 @@ class FTable extends FTableEventEmitter {
|
|
|
4443
4490
|
}
|
|
4444
4491
|
|
|
4445
4492
|
// Build sorted fields list with translated directions
|
|
4446
|
-
const
|
|
4447
|
-
const field = this.options.fields[s.fieldName];
|
|
4448
|
-
const title = field?.title || s.fieldName;
|
|
4449
|
-
|
|
4450
|
-
// Translate direction
|
|
4451
|
-
const directionText = s.direction === 'ASC'
|
|
4452
|
-
? (messages.ascending || 'ascending')
|
|
4453
|
-
: (messages.descending || 'descending');
|
|
4454
|
-
|
|
4455
|
-
return `${title} (${directionText})`;
|
|
4456
|
-
}).join(', ');
|
|
4493
|
+
const sortingInfo = this.getSortingInfo();
|
|
4457
4494
|
|
|
4458
4495
|
// Combine with prefix and suffix
|
|
4459
|
-
container.innerHTML = `${prefix}${
|
|
4496
|
+
container.innerHTML = `${prefix}${sortingInfo}${suffix}`;
|
|
4460
4497
|
|
|
4461
4498
|
// Add reset sorting button
|
|
4462
4499
|
if (this.state.sorting.length > 0) {
|
|
@@ -4747,3 +4784,5 @@ table.load();
|
|
|
4747
4784
|
*/
|
|
4748
4785
|
|
|
4749
4786
|
window.FTable = FTable;
|
|
4787
|
+
|
|
4788
|
+
export default FTable;
|