@liedekef/ftable 1.0.0 → 1.1.0
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 +5 -0
- package/ftable.esm.js +136 -100
- package/ftable.js +136 -100
- package/ftable.min.js +3 -3
- package/ftable.umd.js +136 -100
- package/package.json +1 -1
package/ftable.umd.js
CHANGED
|
@@ -654,10 +654,6 @@ class FTableFormBuilder {
|
|
|
654
654
|
}
|
|
655
655
|
});
|
|
656
656
|
|
|
657
|
-
/*if (this.options.formCreated) {
|
|
658
|
-
this.options.formCreated(form, formType, record);
|
|
659
|
-
}*/
|
|
660
|
-
|
|
661
657
|
// Set up dependency listeners after all fields are created
|
|
662
658
|
this.setupDependencyListeners(form);
|
|
663
659
|
|
|
@@ -1336,7 +1332,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1336
1332
|
|
|
1337
1333
|
this.options = this.mergeOptions(options);
|
|
1338
1334
|
this.logger = new FTableLogger(this.options.logLevel);
|
|
1339
|
-
this.userPrefs = new FTableUserPreferences('', this.options.
|
|
1335
|
+
this.userPrefs = new FTableUserPreferences('', this.options.saveUserPreferencesMethod);
|
|
1340
1336
|
this.formBuilder = new FTableFormBuilder(this.options, this);
|
|
1341
1337
|
|
|
1342
1338
|
this.state = {
|
|
@@ -1352,6 +1348,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1352
1348
|
this.elements = {};
|
|
1353
1349
|
this.modals = {};
|
|
1354
1350
|
this.searchTimeout = null; // For debouncing
|
|
1351
|
+
this.lastSortEvent = null;
|
|
1355
1352
|
this._recalculatedOnce = false;
|
|
1356
1353
|
|
|
1357
1354
|
// store it on the DOM too, so people can access it
|
|
@@ -1369,23 +1366,28 @@ class FTable extends FTableEventEmitter {
|
|
|
1369
1366
|
animationsEnabled: true,
|
|
1370
1367
|
loadingAnimationDelay: 1000,
|
|
1371
1368
|
defaultDateFormat: 'yyyy-mm-dd',
|
|
1372
|
-
|
|
1373
|
-
|
|
1369
|
+
saveUserPreferences: true,
|
|
1370
|
+
saveUserPreferencesMethod: 'localStorage',
|
|
1374
1371
|
defaultSorting: '',
|
|
1375
1372
|
|
|
1376
1373
|
// Paging
|
|
1377
1374
|
paging: false,
|
|
1375
|
+
pageList: 'normal',
|
|
1378
1376
|
pageSize: 10,
|
|
1379
1377
|
gotoPageArea: 'combobox',
|
|
1380
1378
|
|
|
1381
1379
|
// Sorting
|
|
1382
1380
|
sorting: false,
|
|
1383
1381
|
multiSorting: false,
|
|
1382
|
+
multiSortingCtrlKey: true,
|
|
1384
1383
|
|
|
1385
1384
|
// Selection
|
|
1386
1385
|
selecting: false,
|
|
1387
1386
|
multiselect: false,
|
|
1388
1387
|
|
|
1388
|
+
// child tables
|
|
1389
|
+
openChildAsAccordion: false,
|
|
1390
|
+
|
|
1389
1391
|
// Toolbar search
|
|
1390
1392
|
toolbarsearch: false, // Enable/disable toolbar search row
|
|
1391
1393
|
toolbarreset: true, // Show reset button
|
|
@@ -1622,6 +1624,9 @@ class FTable extends FTableEventEmitter {
|
|
|
1622
1624
|
if (field.list === undefined) {
|
|
1623
1625
|
field.list = true;
|
|
1624
1626
|
}
|
|
1627
|
+
if (field.sorting === undefined) {
|
|
1628
|
+
field.sorting = true;
|
|
1629
|
+
}
|
|
1625
1630
|
if (!field.hasOwnProperty('visibility')) {
|
|
1626
1631
|
field.visibility = 'visible';
|
|
1627
1632
|
}
|
|
@@ -1749,9 +1754,9 @@ class FTable extends FTableEventEmitter {
|
|
|
1749
1754
|
});
|
|
1750
1755
|
|
|
1751
1756
|
// Add selecting column if enabled
|
|
1752
|
-
if (this.options.selecting) {
|
|
1757
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
1753
1758
|
const selectHeader = FTableDOMHelper.create('th', {
|
|
1754
|
-
className:
|
|
1759
|
+
className: `ftable-column-header ftable-column-header-select`,
|
|
1755
1760
|
parent: headerRow
|
|
1756
1761
|
});
|
|
1757
1762
|
|
|
@@ -1771,7 +1776,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1771
1776
|
this.columnList.forEach(fieldName => {
|
|
1772
1777
|
const field = this.options.fields[fieldName];
|
|
1773
1778
|
const th = FTableDOMHelper.create('th', {
|
|
1774
|
-
className:
|
|
1779
|
+
className: `ftable-column-header ${field.listClass || ''} ${field.listClassHeader || ''}`,
|
|
1775
1780
|
attributes: { 'data-field-name': fieldName },
|
|
1776
1781
|
parent: headerRow
|
|
1777
1782
|
});
|
|
@@ -1786,6 +1791,10 @@ class FTable extends FTableEventEmitter {
|
|
|
1786
1791
|
parent: th
|
|
1787
1792
|
});
|
|
1788
1793
|
|
|
1794
|
+
if (field.tooltip) {
|
|
1795
|
+
container.setAttribute('title', field.tooltip);
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1789
1798
|
FTableDOMHelper.create('span', {
|
|
1790
1799
|
className: 'ftable-column-header-text',
|
|
1791
1800
|
text: field.title || fieldName,
|
|
@@ -1795,7 +1804,12 @@ class FTable extends FTableEventEmitter {
|
|
|
1795
1804
|
// Make sortable if enabled
|
|
1796
1805
|
if (this.options.sorting && field.sorting !== false) {
|
|
1797
1806
|
FTableDOMHelper.addClass(th, 'ftable-column-header-sortable');
|
|
1798
|
-
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
|
+
});
|
|
1799
1813
|
}
|
|
1800
1814
|
|
|
1801
1815
|
// Add resize handler if column resizing is enabled
|
|
@@ -1846,7 +1860,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1846
1860
|
});
|
|
1847
1861
|
|
|
1848
1862
|
// Add empty cell for selecting column if enabled
|
|
1849
|
-
if (this.options.selecting) {
|
|
1863
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
1850
1864
|
FTableDOMHelper.create('th', { parent: searchRow });
|
|
1851
1865
|
}
|
|
1852
1866
|
|
|
@@ -2132,14 +2146,14 @@ class FTable extends FTableEventEmitter {
|
|
|
2132
2146
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
2133
2147
|
|
|
2134
2148
|
// Save column width preference if enabled
|
|
2135
|
-
if (this.options.
|
|
2149
|
+
if (this.options.saveUserPreferences) {
|
|
2136
2150
|
this.saveColumnSettings();
|
|
2137
2151
|
}
|
|
2138
2152
|
};
|
|
2139
2153
|
}
|
|
2140
2154
|
|
|
2141
2155
|
saveColumnSettings() {
|
|
2142
|
-
if (!this.options.
|
|
2156
|
+
if (!this.options.saveUserPreferences) return;
|
|
2143
2157
|
|
|
2144
2158
|
const settings = {};
|
|
2145
2159
|
this.columnList.forEach(fieldName => {
|
|
@@ -2157,7 +2171,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2157
2171
|
}
|
|
2158
2172
|
|
|
2159
2173
|
saveState() {
|
|
2160
|
-
if (!this.options.
|
|
2174
|
+
if (!this.options.saveUserPreferences) return;
|
|
2161
2175
|
|
|
2162
2176
|
const state = {
|
|
2163
2177
|
sorting: this.state.sorting,
|
|
@@ -2168,7 +2182,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2168
2182
|
}
|
|
2169
2183
|
|
|
2170
2184
|
loadColumnSettings() {
|
|
2171
|
-
if (!this.options.
|
|
2185
|
+
if (!this.options.saveUserPreferences) return;
|
|
2172
2186
|
|
|
2173
2187
|
const settingsJson = this.userPrefs.get('column-settings');
|
|
2174
2188
|
if (!settingsJson) return;
|
|
@@ -2188,7 +2202,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2188
2202
|
}
|
|
2189
2203
|
|
|
2190
2204
|
loadState() {
|
|
2191
|
-
if (!this.options.
|
|
2205
|
+
if (!this.options.saveUserPreferences) return;
|
|
2192
2206
|
|
|
2193
2207
|
const stateJson = this.userPrefs.get('table-state');
|
|
2194
2208
|
if (!stateJson) return;
|
|
@@ -2267,9 +2281,6 @@ class FTable extends FTableEventEmitter {
|
|
|
2267
2281
|
onClick: () => {
|
|
2268
2282
|
this.modals.addRecord.close();
|
|
2269
2283
|
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
2284
|
}
|
|
2274
2285
|
},
|
|
2275
2286
|
{
|
|
@@ -2622,6 +2633,11 @@ class FTable extends FTableEventEmitter {
|
|
|
2622
2633
|
parent: this.elements.toolbarDiv
|
|
2623
2634
|
});
|
|
2624
2635
|
|
|
2636
|
+
// Add title/tooltip if provided
|
|
2637
|
+
if (item.tooltip) {
|
|
2638
|
+
button.setAttribute('title', item.tooltip);
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2625
2641
|
// Add icon if provided
|
|
2626
2642
|
if (item.icon) {
|
|
2627
2643
|
const img = FTableDOMHelper.create('img', {
|
|
@@ -2684,12 +2700,12 @@ class FTable extends FTableEventEmitter {
|
|
|
2684
2700
|
}
|
|
2685
2701
|
|
|
2686
2702
|
setupFTableUserPreferences() {
|
|
2687
|
-
if (this.options.
|
|
2703
|
+
if (this.options.saveUserPreferences) {
|
|
2688
2704
|
const prefix = this.userPrefs.generatePrefix(
|
|
2689
2705
|
this.options.tableId || '',
|
|
2690
2706
|
this.fieldList
|
|
2691
2707
|
);
|
|
2692
|
-
this.userPrefs = new FTableUserPreferences(prefix, this.options.
|
|
2708
|
+
this.userPrefs = new FTableUserPreferences(prefix, this.options.saveUserPreferencesMethod);
|
|
2693
2709
|
|
|
2694
2710
|
// Load saved column settings
|
|
2695
2711
|
this.loadState();
|
|
@@ -2861,7 +2877,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2861
2877
|
row.recordData = record;
|
|
2862
2878
|
|
|
2863
2879
|
// Add selecting checkbox if enabled
|
|
2864
|
-
if (this.options.selecting) {
|
|
2880
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
2865
2881
|
this.addSelectingCell(row);
|
|
2866
2882
|
}
|
|
2867
2883
|
|
|
@@ -3086,10 +3102,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3086
3102
|
this.modals.addRecord.close();
|
|
3087
3103
|
|
|
3088
3104
|
// Call formClosed
|
|
3089
|
-
|
|
3090
|
-
if (this.options.formClosed) {
|
|
3091
|
-
this.options.formClosed(this.currentForm, 'create', null);
|
|
3092
|
-
}
|
|
3105
|
+
this.emit('formClosed', { form: this.currentForm, formType: 'create', record: null });
|
|
3093
3106
|
|
|
3094
3107
|
if (result.Message) {
|
|
3095
3108
|
this.showInfo(result.Message);
|
|
@@ -3136,17 +3149,14 @@ class FTable extends FTableEventEmitter {
|
|
|
3136
3149
|
this.modals.editRecord.close();
|
|
3137
3150
|
|
|
3138
3151
|
// Call formClosed
|
|
3139
|
-
|
|
3140
|
-
if (this.options.formClosed) {
|
|
3141
|
-
this.options.formClosed(this.currentForm, 'edit', this.currentEditingRow.recordData);
|
|
3142
|
-
}
|
|
3152
|
+
this.emit('formClosed', { form: this.currentForm, formType: 'edit', record: this.currentEditingRow.recordData });
|
|
3143
3153
|
|
|
3144
3154
|
// Update the row with new data
|
|
3145
3155
|
this.updateRowData(this.currentEditingRow, result.Record || formData);
|
|
3146
3156
|
if (result.Message) {
|
|
3147
3157
|
this.showInfo(result.Message);
|
|
3148
3158
|
}
|
|
3149
|
-
this.emit('recordUpdated', { record: result.Record || formData });
|
|
3159
|
+
this.emit('recordUpdated', { record: result.Record || formData, row: this.currentEditingRow });
|
|
3150
3160
|
} else {
|
|
3151
3161
|
this.showError(result.Message || 'Update failed');
|
|
3152
3162
|
}
|
|
@@ -3452,25 +3462,42 @@ class FTable extends FTableEventEmitter {
|
|
|
3452
3462
|
|
|
3453
3463
|
// Sorting Methods
|
|
3454
3464
|
sortByColumn(fieldName) {
|
|
3465
|
+
const field = this.options.fields[fieldName];
|
|
3466
|
+
|
|
3467
|
+
if (!field || field.sorting === false) return;
|
|
3468
|
+
|
|
3455
3469
|
const existingSortIndex = this.state.sorting.findIndex(s => s.fieldName === fieldName);
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
this.state.sorting = [];
|
|
3459
|
-
}
|
|
3460
|
-
|
|
3470
|
+
let isSorted = true;
|
|
3471
|
+
let newDirection = 'ASC';
|
|
3461
3472
|
if (existingSortIndex >= 0) {
|
|
3462
|
-
const
|
|
3463
|
-
if (
|
|
3464
|
-
|
|
3473
|
+
const wasAsc = this.state.sorting[existingSortIndex].direction === 'ASC';
|
|
3474
|
+
if (wasAsc) {
|
|
3475
|
+
newDirection = 'DESC';
|
|
3476
|
+
this.state.sorting[existingSortIndex].direction = newDirection;
|
|
3465
3477
|
} else {
|
|
3466
|
-
this.state.sorting.splice(existingSortIndex,
|
|
3478
|
+
this.state.sorting.splice(existingSortIndex,1);
|
|
3479
|
+
isSorted = false;
|
|
3467
3480
|
}
|
|
3468
3481
|
} else {
|
|
3469
|
-
this.state.sorting.push({ fieldName, direction:
|
|
3482
|
+
this.state.sorting.push({ fieldName, direction: newDirection });
|
|
3470
3483
|
}
|
|
3471
|
-
|
|
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
|
+
|
|
3472
3499
|
this.updateSortingHeaders();
|
|
3473
|
-
this.load();
|
|
3500
|
+
this.load();
|
|
3474
3501
|
this.saveState();
|
|
3475
3502
|
}
|
|
3476
3503
|
|
|
@@ -3529,27 +3556,29 @@ class FTable extends FTableEventEmitter {
|
|
|
3529
3556
|
this.createPageButton('‹', this.state.currentPage - 1, this.state.currentPage === 1, 'ftable-page-number-previous');
|
|
3530
3557
|
|
|
3531
3558
|
// Page numbers
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
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
|
+
}
|
|
3553
3582
|
|
|
3554
3583
|
// Next and Last buttons
|
|
3555
3584
|
this.createPageButton('›', this.state.currentPage + 1, this.state.currentPage >= totalPages, 'ftable-page-number-next');
|
|
@@ -3957,7 +3986,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3957
3986
|
if (columnIndex >= 0) {
|
|
3958
3987
|
// Calculate actual column index (accounting for selecting column)
|
|
3959
3988
|
let actualIndex = columnIndex + 1; // CSS nth-child is 1-based
|
|
3960
|
-
if (this.options.selecting) {
|
|
3989
|
+
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
3961
3990
|
actualIndex += 1; // Account for selecting column
|
|
3962
3991
|
}
|
|
3963
3992
|
|
|
@@ -3974,7 +4003,7 @@ class FTable extends FTableEventEmitter {
|
|
|
3974
4003
|
}
|
|
3975
4004
|
|
|
3976
4005
|
// Save column settings
|
|
3977
|
-
if (this.options.
|
|
4006
|
+
if (this.options.saveUserPreferences) {
|
|
3978
4007
|
this.saveColumnSettings();
|
|
3979
4008
|
this.saveState(); // sorting might affect state
|
|
3980
4009
|
}
|
|
@@ -4172,27 +4201,6 @@ class FTable extends FTableEventEmitter {
|
|
|
4172
4201
|
});
|
|
4173
4202
|
}
|
|
4174
4203
|
|
|
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
4204
|
// Real-time updates via WebSocket
|
|
4197
4205
|
enableRealTimeUpdates(websocketUrl) {
|
|
4198
4206
|
if (!websocketUrl) return;
|
|
@@ -4316,6 +4324,15 @@ class FTable extends FTableEventEmitter {
|
|
|
4316
4324
|
return this;
|
|
4317
4325
|
}
|
|
4318
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
|
+
|
|
4319
4336
|
async editRecordViaAjax(recordId, url, params = {}) {
|
|
4320
4337
|
try {
|
|
4321
4338
|
// Get the actual key field name (e.g., 'asset_id', 'user_id', etc.)
|
|
@@ -4355,6 +4372,10 @@ class FTable extends FTableEventEmitter {
|
|
|
4355
4372
|
}
|
|
4356
4373
|
|
|
4357
4374
|
openChildTable(parentRow, childOptions, onInit) {
|
|
4375
|
+
// Close any open child tables if accordion mode
|
|
4376
|
+
if (this.options.openChildAsAccordion) {
|
|
4377
|
+
this.closeAllChildTables();
|
|
4378
|
+
}
|
|
4358
4379
|
// Prevent multiple child tables
|
|
4359
4380
|
this.closeChildTable(parentRow);
|
|
4360
4381
|
|
|
@@ -4423,6 +4444,31 @@ class FTable extends FTableEventEmitter {
|
|
|
4423
4444
|
}
|
|
4424
4445
|
}
|
|
4425
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
|
+
|
|
4426
4472
|
renderSortingInfo() {
|
|
4427
4473
|
if (!this.options.sortingInfoSelector || !this.options.sorting) return;
|
|
4428
4474
|
|
|
@@ -4444,20 +4490,10 @@ class FTable extends FTableEventEmitter {
|
|
|
4444
4490
|
}
|
|
4445
4491
|
|
|
4446
4492
|
// 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(', ');
|
|
4493
|
+
const sortingInfo = this.getSortingInfo();
|
|
4458
4494
|
|
|
4459
4495
|
// Combine with prefix and suffix
|
|
4460
|
-
container.innerHTML = `${prefix}${
|
|
4496
|
+
container.innerHTML = `${prefix}${sortingInfo}${suffix}`;
|
|
4461
4497
|
|
|
4462
4498
|
// Add reset sorting button
|
|
4463
4499
|
if (this.state.sorting.length > 0) {
|