@liedekef/ftable 1.1.6 → 1.1.7
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/ftable.esm.js +41 -159
- package/ftable.js +42 -160
- package/ftable.min.js +3 -3
- package/ftable.umd.js +42 -160
- package/package.json +1 -1
- package/themes/basic/ftable_basic.css +25 -25
- package/themes/basic/ftable_basic.min.css +1 -1
- package/themes/ftable_theme_base.less +35 -35
- package/themes/lightcolor/blue/ftable.css +33 -33
- package/themes/lightcolor/blue/ftable.min.css +1 -1
- package/themes/lightcolor/ftable_lightcolor_base.less +6 -5
- package/themes/lightcolor/gray/ftable.css +33 -33
- package/themes/lightcolor/gray/ftable.min.css +1 -1
- package/themes/lightcolor/green/ftable.css +33 -33
- package/themes/lightcolor/green/ftable.min.css +1 -1
- package/themes/lightcolor/orange/ftable.css +33 -33
- package/themes/lightcolor/orange/ftable.min.css +1 -1
- package/themes/lightcolor/red/ftable.css +33 -33
- package/themes/lightcolor/red/ftable.min.css +1 -1
- package/themes/metro/blue/ftable.css +25 -25
- package/themes/metro/blue/ftable.min.css +1 -1
- package/themes/metro/brown/ftable.css +25 -25
- package/themes/metro/brown/ftable.min.css +1 -1
- package/themes/metro/crimson/ftable.css +25 -25
- package/themes/metro/crimson/ftable.min.css +1 -1
- package/themes/metro/darkgray/ftable.css +25 -25
- package/themes/metro/darkgray/ftable.min.css +1 -1
- package/themes/metro/darkorange/ftable.css +25 -25
- package/themes/metro/darkorange/ftable.min.css +1 -1
- package/themes/metro/green/ftable.css +25 -25
- package/themes/metro/green/ftable.min.css +1 -1
- package/themes/metro/lightgray/ftable.css +25 -25
- package/themes/metro/lightgray/ftable.min.css +1 -1
- package/themes/metro/pink/ftable.css +25 -25
- package/themes/metro/pink/ftable.min.css +1 -1
- package/themes/metro/purple/ftable.css +25 -25
- package/themes/metro/purple/ftable.min.css +1 -1
- package/themes/metro/red/ftable.css +25 -25
- package/themes/metro/red/ftable.min.css +1 -1
package/ftable.esm.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
// Modern fTable - Vanilla JS Refactor
|
|
3
|
-
|
|
4
2
|
const FTABLE_DEFAULT_MESSAGES = {
|
|
5
3
|
serverCommunicationError: 'An error occurred while communicating to the server.',
|
|
6
4
|
loadingMessage: 'Loading records...',
|
|
@@ -748,7 +746,9 @@ class FTableFormBuilder {
|
|
|
748
746
|
}
|
|
749
747
|
|
|
750
748
|
try {
|
|
751
|
-
const response =
|
|
749
|
+
const response = this.options.forcePost
|
|
750
|
+
? await FTableHttpClient.post(url)
|
|
751
|
+
: await FTableHttpClient.get(url);
|
|
752
752
|
const options = response.Options || response.options || response || [];
|
|
753
753
|
|
|
754
754
|
// Only cache if noCache is false
|
|
@@ -1354,10 +1354,14 @@ class FTable extends FTableEventEmitter {
|
|
|
1354
1354
|
this.element = typeof element === 'string' ?
|
|
1355
1355
|
document.querySelector(element) : element;
|
|
1356
1356
|
|
|
1357
|
+
if (!this.element) {
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1357
1361
|
// Prevent double initialization
|
|
1358
|
-
if (element.ftableInstance) {
|
|
1362
|
+
if (this.element.ftableInstance) {
|
|
1359
1363
|
//console.warn('FTable is already initialized on this element. Using that.');
|
|
1360
|
-
return element.ftableInstance;
|
|
1364
|
+
return this.element.ftableInstance;
|
|
1361
1365
|
}
|
|
1362
1366
|
|
|
1363
1367
|
this.options = this.mergeOptions(options);
|
|
@@ -1394,6 +1398,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1394
1398
|
logLevel: FTableLogger.LOG_LEVELS.WARN,
|
|
1395
1399
|
actions: {},
|
|
1396
1400
|
fields: {},
|
|
1401
|
+
forcePost: true,
|
|
1397
1402
|
animationsEnabled: true,
|
|
1398
1403
|
loadingAnimationDelay: 1000,
|
|
1399
1404
|
defaultDateLocale: '',
|
|
@@ -2520,13 +2525,15 @@ class FTable extends FTableEventEmitter {
|
|
|
2520
2525
|
// Create overlay to capture clicks outside menu
|
|
2521
2526
|
this.elements.columnSelectionOverlay = FTableDOMHelper.create('div', {
|
|
2522
2527
|
className: 'ftable-contextmenu-overlay',
|
|
2523
|
-
parent: this.elements.mainContainer
|
|
2528
|
+
//parent: this.elements.mainContainer
|
|
2529
|
+
parent: document.body
|
|
2524
2530
|
});
|
|
2525
2531
|
|
|
2526
2532
|
// Create the menu
|
|
2527
2533
|
this.elements.columnSelectionMenu = FTableDOMHelper.create('div', {
|
|
2528
2534
|
className: 'ftable-column-selection-container',
|
|
2529
|
-
parent: this.elements.columnSelectionOverlay
|
|
2535
|
+
//parent: this.elements.columnSelectionOverlay
|
|
2536
|
+
parent: document.body
|
|
2530
2537
|
});
|
|
2531
2538
|
|
|
2532
2539
|
// Populate menu with column options
|
|
@@ -2612,29 +2619,36 @@ class FTable extends FTableEventEmitter {
|
|
|
2612
2619
|
}
|
|
2613
2620
|
|
|
2614
2621
|
positionColumnSelectionMenu(e) {
|
|
2615
|
-
const
|
|
2616
|
-
const menuWidth = 200; // Approximate menu width
|
|
2617
|
-
const menuHeight = this.columnList.length * 30 + 20; // Approximate height
|
|
2622
|
+
const self = this;
|
|
2618
2623
|
|
|
2619
|
-
|
|
2620
|
-
let
|
|
2624
|
+
// Use clientX/clientY (relative to viewport)
|
|
2625
|
+
let left = e.clientX;
|
|
2626
|
+
let top = e.clientY;
|
|
2621
2627
|
|
|
2622
|
-
//
|
|
2623
|
-
|
|
2624
|
-
left = Math.max(0, containerRect.width - menuWidth);
|
|
2625
|
-
}
|
|
2628
|
+
// Define minimum width
|
|
2629
|
+
const minWidth = 100;
|
|
2626
2630
|
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
}
|
|
2631
|
+
// Position the menu
|
|
2632
|
+
self.elements.columnSelectionMenu.style.position = 'absolute';
|
|
2633
|
+
self.elements.columnSelectionMenu.style.left = `${left}px`;
|
|
2634
|
+
self.elements.columnSelectionMenu.style.top = `${top}px`;
|
|
2635
|
+
self.elements.columnSelectionMenu.style.minWidth = `${minWidth}px`;
|
|
2636
|
+
self.elements.columnSelectionMenu.style.boxSizing = 'border-box';
|
|
2637
|
+
|
|
2638
|
+
// Optional: Adjust if menu would overflow right edge
|
|
2639
|
+
const menuWidth = self.elements.columnSelectionMenu.offsetWidth;
|
|
2640
|
+
const windowWidth = window.innerWidth;
|
|
2630
2641
|
|
|
2631
|
-
|
|
2632
|
-
|
|
2642
|
+
if (left + menuWidth > windowWidth) {
|
|
2643
|
+
left = Math.max(10, windowWidth - menuWidth - 10); // 10px margin
|
|
2644
|
+
self.elements.columnSelectionMenu.style.left = `${left}px`;
|
|
2645
|
+
}
|
|
2633
2646
|
}
|
|
2634
2647
|
|
|
2635
2648
|
hideColumnSelectionMenu() {
|
|
2636
2649
|
if (this.elements.columnSelectionOverlay) {
|
|
2637
2650
|
this.elements.columnSelectionOverlay.remove();
|
|
2651
|
+
this.elements.columnSelectionMenu.remove();
|
|
2638
2652
|
this.elements.columnSelectionOverlay = null;
|
|
2639
2653
|
this.elements.columnSelectionMenu = null;
|
|
2640
2654
|
}
|
|
@@ -2877,7 +2891,9 @@ class FTable extends FTableEventEmitter {
|
|
|
2877
2891
|
if (typeof listAction === 'function') {
|
|
2878
2892
|
data = await listAction(params);
|
|
2879
2893
|
} else if (typeof listAction === 'string') {
|
|
2880
|
-
data =
|
|
2894
|
+
data = this.options.forcePost
|
|
2895
|
+
? await FTableHttpClient.post(listAction, params)
|
|
2896
|
+
: await FTableHttpClient.get(listAction, params);
|
|
2881
2897
|
} else {
|
|
2882
2898
|
throw new Error('No valid listAction provided');
|
|
2883
2899
|
}
|
|
@@ -4411,7 +4427,9 @@ class FTable extends FTableEventEmitter {
|
|
|
4411
4427
|
...params
|
|
4412
4428
|
};
|
|
4413
4429
|
|
|
4414
|
-
const response =
|
|
4430
|
+
const response = this.options.forcePost
|
|
4431
|
+
? await FTableHttpClient.post(url, fullParams)
|
|
4432
|
+
: await FTableHttpClient.get(url, fullParams);
|
|
4415
4433
|
|
|
4416
4434
|
if (!response || !response.Record) {
|
|
4417
4435
|
throw new Error('Invalid response or missing Record');
|
|
@@ -4713,140 +4731,4 @@ class FTable extends FTableEventEmitter {
|
|
|
4713
4731
|
}
|
|
4714
4732
|
}
|
|
4715
4733
|
|
|
4716
|
-
// Export for use
|
|
4717
|
-
//window.FTable = FTable;
|
|
4718
|
-
|
|
4719
|
-
// Usage example:
|
|
4720
|
-
/*
|
|
4721
|
-
const table = new FTable('#myTable', {
|
|
4722
|
-
title: 'My Data Table',
|
|
4723
|
-
paging: true,
|
|
4724
|
-
pageSize: 25,
|
|
4725
|
-
sorting: true,
|
|
4726
|
-
selecting: true,
|
|
4727
|
-
actions: {
|
|
4728
|
-
listAction: '/api/users',
|
|
4729
|
-
createAction: '/api/users',
|
|
4730
|
-
updateAction: '/api/users',
|
|
4731
|
-
deleteAction: '/api/users'
|
|
4732
|
-
},
|
|
4733
|
-
fields: {
|
|
4734
|
-
id: { key: true, list: false },
|
|
4735
|
-
name: {
|
|
4736
|
-
title: 'Name',
|
|
4737
|
-
type: 'text',
|
|
4738
|
-
inputAttributes: "maxlength=100 required"
|
|
4739
|
-
},
|
|
4740
|
-
email: {
|
|
4741
|
-
title: 'Email',
|
|
4742
|
-
type: 'email',
|
|
4743
|
-
width: '40%',
|
|
4744
|
-
inputAttributes: {
|
|
4745
|
-
pattern: '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$'
|
|
4746
|
-
}
|
|
4747
|
-
},
|
|
4748
|
-
created: { title: 'Created', type: 'date', width: '30%' }
|
|
4749
|
-
},
|
|
4750
|
-
toolbarsearch: true,
|
|
4751
|
-
childTable: {
|
|
4752
|
-
title: 'Child Records',
|
|
4753
|
-
actions: {
|
|
4754
|
-
listAction: '/api/users/{id}/orders', // {id} will be replaced with parent record id
|
|
4755
|
-
createAction: '/api/users/{id}/orders',
|
|
4756
|
-
updateAction: '/api/orders',
|
|
4757
|
-
deleteAction: '/api/orders'
|
|
4758
|
-
},
|
|
4759
|
-
fields: {
|
|
4760
|
-
orderId: { key: true, list: false },
|
|
4761
|
-
orderDate: { title: 'Date', type: 'date' },
|
|
4762
|
-
amount: { title: 'Amount', type: 'number' }
|
|
4763
|
-
}
|
|
4764
|
-
},
|
|
4765
|
-
childTableColumnsVisible: true,
|
|
4766
|
-
|
|
4767
|
-
});
|
|
4768
|
-
|
|
4769
|
-
// Or dynamic child table
|
|
4770
|
-
childTable: async function(parentRecord) {
|
|
4771
|
-
return {
|
|
4772
|
-
title: `Orders for ${parentRecord.name}`,
|
|
4773
|
-
actions: {
|
|
4774
|
-
listAction: `/api/users/${parentRecord.id}/orders`
|
|
4775
|
-
},
|
|
4776
|
-
fields: {
|
|
4777
|
-
// Dynamic fields based on parent
|
|
4778
|
-
}
|
|
4779
|
-
};
|
|
4780
|
-
}
|
|
4781
|
-
|
|
4782
|
-
// function for select options
|
|
4783
|
-
fields: {
|
|
4784
|
-
assignee: {
|
|
4785
|
-
title: 'Assigned To',
|
|
4786
|
-
type: 'select',
|
|
4787
|
-
options: async function(params) {
|
|
4788
|
-
// params contains dependsOnValue, dependsOnField, etc.
|
|
4789
|
-
const department = params.dependsOnValue;
|
|
4790
|
-
const response = await fetch(`/api/users?department=${department}`);
|
|
4791
|
-
return response.json();
|
|
4792
|
-
},
|
|
4793
|
-
dependsOn: 'department'
|
|
4794
|
-
}
|
|
4795
|
-
}
|
|
4796
|
-
|
|
4797
|
-
// child table:
|
|
4798
|
-
phoneNumbers: {
|
|
4799
|
-
title: 'Phones',
|
|
4800
|
-
display: (data) => {
|
|
4801
|
-
const img = document.createElement('img');
|
|
4802
|
-
img.className = 'child-opener-image';
|
|
4803
|
-
img.src = '/Content/images/Misc/phone.png';
|
|
4804
|
-
img.title = 'Edit phone numbers';
|
|
4805
|
-
img.style.cursor = 'pointer';
|
|
4806
|
-
|
|
4807
|
-
parentRow = img.closest('tr');
|
|
4808
|
-
img.addEventListener('click', () => {
|
|
4809
|
-
e.stopPropagation();
|
|
4810
|
-
if (parentRow.childRow) {
|
|
4811
|
-
myTable.closeChildTable(parentRow);
|
|
4812
|
-
} else {
|
|
4813
|
-
myTable.openChildTable( parentRow, {
|
|
4814
|
-
title: `${data.record.Name} - Phone numbers`,
|
|
4815
|
-
actions: {
|
|
4816
|
-
listAction: `/PagingPerson/PhoneList?PersonId=${data.record.PersonId}`,
|
|
4817
|
-
deleteAction: '/PagingPerson/DeletePhone',
|
|
4818
|
-
updateAction: '/PagingPerson/UpdatePhone',
|
|
4819
|
-
createAction: `/PagingPerson/CreatePhone?PersonId=${data.record.PersonId}`
|
|
4820
|
-
},
|
|
4821
|
-
fields: {
|
|
4822
|
-
PhoneId: { key: true },
|
|
4823
|
-
Number: { title: 'Number', type: 'text' },
|
|
4824
|
-
Type: { title: 'Type', options: { 0: 'Home', 1: 'Work', 2: 'Mobile' } }
|
|
4825
|
-
}
|
|
4826
|
-
}, (childTable) => {
|
|
4827
|
-
console.log('Child table created');
|
|
4828
|
-
};
|
|
4829
|
-
}
|
|
4830
|
-
});
|
|
4831
|
-
img.addEventListener('click', (e) => {
|
|
4832
|
-
e.stopPropagation();
|
|
4833
|
-
if (parentRow.childRow) {
|
|
4834
|
-
myTable.closeChildTable(parentRow);
|
|
4835
|
-
} else {
|
|
4836
|
-
myTable.openChildTable(parentRow, childOptions);
|
|
4837
|
-
}
|
|
4838
|
-
});
|
|
4839
|
-
|
|
4840
|
-
return img;
|
|
4841
|
-
}
|
|
4842
|
-
}
|
|
4843
|
-
|
|
4844
|
-
// Clear specific options cache
|
|
4845
|
-
table.clearOptionsCache('/api/countries');
|
|
4846
|
-
|
|
4847
|
-
table.load();
|
|
4848
|
-
*/
|
|
4849
|
-
|
|
4850
|
-
window.FTable = FTable;
|
|
4851
|
-
|
|
4852
4734
|
export default FTable;
|
package/ftable.js
CHANGED
|
@@ -4,9 +4,7 @@
|
|
|
4
4
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
5
5
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.FTable = factory());
|
|
6
6
|
}(this, (function () {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const FTABLE_DEFAULT_MESSAGES = {
|
|
7
|
+
const FTABLE_DEFAULT_MESSAGES = {
|
|
10
8
|
serverCommunicationError: 'An error occurred while communicating to the server.',
|
|
11
9
|
loadingMessage: 'Loading records...',
|
|
12
10
|
noDataAvailable: 'No data available!',
|
|
@@ -753,7 +751,9 @@ class FTableFormBuilder {
|
|
|
753
751
|
}
|
|
754
752
|
|
|
755
753
|
try {
|
|
756
|
-
const response =
|
|
754
|
+
const response = this.options.forcePost
|
|
755
|
+
? await FTableHttpClient.post(url)
|
|
756
|
+
: await FTableHttpClient.get(url);
|
|
757
757
|
const options = response.Options || response.options || response || [];
|
|
758
758
|
|
|
759
759
|
// Only cache if noCache is false
|
|
@@ -1359,10 +1359,14 @@ class FTable extends FTableEventEmitter {
|
|
|
1359
1359
|
this.element = typeof element === 'string' ?
|
|
1360
1360
|
document.querySelector(element) : element;
|
|
1361
1361
|
|
|
1362
|
+
if (!this.element) {
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1362
1366
|
// Prevent double initialization
|
|
1363
|
-
if (element.ftableInstance) {
|
|
1367
|
+
if (this.element.ftableInstance) {
|
|
1364
1368
|
//console.warn('FTable is already initialized on this element. Using that.');
|
|
1365
|
-
return element.ftableInstance;
|
|
1369
|
+
return this.element.ftableInstance;
|
|
1366
1370
|
}
|
|
1367
1371
|
|
|
1368
1372
|
this.options = this.mergeOptions(options);
|
|
@@ -1399,6 +1403,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1399
1403
|
logLevel: FTableLogger.LOG_LEVELS.WARN,
|
|
1400
1404
|
actions: {},
|
|
1401
1405
|
fields: {},
|
|
1406
|
+
forcePost: true,
|
|
1402
1407
|
animationsEnabled: true,
|
|
1403
1408
|
loadingAnimationDelay: 1000,
|
|
1404
1409
|
defaultDateLocale: '',
|
|
@@ -2525,13 +2530,15 @@ class FTable extends FTableEventEmitter {
|
|
|
2525
2530
|
// Create overlay to capture clicks outside menu
|
|
2526
2531
|
this.elements.columnSelectionOverlay = FTableDOMHelper.create('div', {
|
|
2527
2532
|
className: 'ftable-contextmenu-overlay',
|
|
2528
|
-
parent: this.elements.mainContainer
|
|
2533
|
+
//parent: this.elements.mainContainer
|
|
2534
|
+
parent: document.body
|
|
2529
2535
|
});
|
|
2530
2536
|
|
|
2531
2537
|
// Create the menu
|
|
2532
2538
|
this.elements.columnSelectionMenu = FTableDOMHelper.create('div', {
|
|
2533
2539
|
className: 'ftable-column-selection-container',
|
|
2534
|
-
parent: this.elements.columnSelectionOverlay
|
|
2540
|
+
//parent: this.elements.columnSelectionOverlay
|
|
2541
|
+
parent: document.body
|
|
2535
2542
|
});
|
|
2536
2543
|
|
|
2537
2544
|
// Populate menu with column options
|
|
@@ -2617,29 +2624,36 @@ class FTable extends FTableEventEmitter {
|
|
|
2617
2624
|
}
|
|
2618
2625
|
|
|
2619
2626
|
positionColumnSelectionMenu(e) {
|
|
2620
|
-
const
|
|
2621
|
-
const menuWidth = 200; // Approximate menu width
|
|
2622
|
-
const menuHeight = this.columnList.length * 30 + 20; // Approximate height
|
|
2627
|
+
const self = this;
|
|
2623
2628
|
|
|
2624
|
-
|
|
2625
|
-
let
|
|
2629
|
+
// Use clientX/clientY (relative to viewport)
|
|
2630
|
+
let left = e.clientX;
|
|
2631
|
+
let top = e.clientY;
|
|
2626
2632
|
|
|
2627
|
-
//
|
|
2628
|
-
|
|
2629
|
-
left = Math.max(0, containerRect.width - menuWidth);
|
|
2630
|
-
}
|
|
2633
|
+
// Define minimum width
|
|
2634
|
+
const minWidth = 100;
|
|
2631
2635
|
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
}
|
|
2636
|
+
// Position the menu
|
|
2637
|
+
self.elements.columnSelectionMenu.style.position = 'absolute';
|
|
2638
|
+
self.elements.columnSelectionMenu.style.left = `${left}px`;
|
|
2639
|
+
self.elements.columnSelectionMenu.style.top = `${top}px`;
|
|
2640
|
+
self.elements.columnSelectionMenu.style.minWidth = `${minWidth}px`;
|
|
2641
|
+
self.elements.columnSelectionMenu.style.boxSizing = 'border-box';
|
|
2642
|
+
|
|
2643
|
+
// Optional: Adjust if menu would overflow right edge
|
|
2644
|
+
const menuWidth = self.elements.columnSelectionMenu.offsetWidth;
|
|
2645
|
+
const windowWidth = window.innerWidth;
|
|
2635
2646
|
|
|
2636
|
-
|
|
2637
|
-
|
|
2647
|
+
if (left + menuWidth > windowWidth) {
|
|
2648
|
+
left = Math.max(10, windowWidth - menuWidth - 10); // 10px margin
|
|
2649
|
+
self.elements.columnSelectionMenu.style.left = `${left}px`;
|
|
2650
|
+
}
|
|
2638
2651
|
}
|
|
2639
2652
|
|
|
2640
2653
|
hideColumnSelectionMenu() {
|
|
2641
2654
|
if (this.elements.columnSelectionOverlay) {
|
|
2642
2655
|
this.elements.columnSelectionOverlay.remove();
|
|
2656
|
+
this.elements.columnSelectionMenu.remove();
|
|
2643
2657
|
this.elements.columnSelectionOverlay = null;
|
|
2644
2658
|
this.elements.columnSelectionMenu = null;
|
|
2645
2659
|
}
|
|
@@ -2882,7 +2896,9 @@ class FTable extends FTableEventEmitter {
|
|
|
2882
2896
|
if (typeof listAction === 'function') {
|
|
2883
2897
|
data = await listAction(params);
|
|
2884
2898
|
} else if (typeof listAction === 'string') {
|
|
2885
|
-
data =
|
|
2899
|
+
data = this.options.forcePost
|
|
2900
|
+
? await FTableHttpClient.post(listAction, params)
|
|
2901
|
+
: await FTableHttpClient.get(listAction, params);
|
|
2886
2902
|
} else {
|
|
2887
2903
|
throw new Error('No valid listAction provided');
|
|
2888
2904
|
}
|
|
@@ -4416,7 +4432,9 @@ class FTable extends FTableEventEmitter {
|
|
|
4416
4432
|
...params
|
|
4417
4433
|
};
|
|
4418
4434
|
|
|
4419
|
-
const response =
|
|
4435
|
+
const response = this.options.forcePost
|
|
4436
|
+
? await FTableHttpClient.post(url, fullParams)
|
|
4437
|
+
: await FTableHttpClient.get(url, fullParams);
|
|
4420
4438
|
|
|
4421
4439
|
if (!response || !response.Record) {
|
|
4422
4440
|
throw new Error('Invalid response or missing Record');
|
|
@@ -4718,141 +4736,5 @@ class FTable extends FTableEventEmitter {
|
|
|
4718
4736
|
}
|
|
4719
4737
|
}
|
|
4720
4738
|
|
|
4721
|
-
// Export for use
|
|
4722
|
-
//window.FTable = FTable;
|
|
4723
|
-
|
|
4724
|
-
// Usage example:
|
|
4725
|
-
/*
|
|
4726
|
-
const table = new FTable('#myTable', {
|
|
4727
|
-
title: 'My Data Table',
|
|
4728
|
-
paging: true,
|
|
4729
|
-
pageSize: 25,
|
|
4730
|
-
sorting: true,
|
|
4731
|
-
selecting: true,
|
|
4732
|
-
actions: {
|
|
4733
|
-
listAction: '/api/users',
|
|
4734
|
-
createAction: '/api/users',
|
|
4735
|
-
updateAction: '/api/users',
|
|
4736
|
-
deleteAction: '/api/users'
|
|
4737
|
-
},
|
|
4738
|
-
fields: {
|
|
4739
|
-
id: { key: true, list: false },
|
|
4740
|
-
name: {
|
|
4741
|
-
title: 'Name',
|
|
4742
|
-
type: 'text',
|
|
4743
|
-
inputAttributes: "maxlength=100 required"
|
|
4744
|
-
},
|
|
4745
|
-
email: {
|
|
4746
|
-
title: 'Email',
|
|
4747
|
-
type: 'email',
|
|
4748
|
-
width: '40%',
|
|
4749
|
-
inputAttributes: {
|
|
4750
|
-
pattern: '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$'
|
|
4751
|
-
}
|
|
4752
|
-
},
|
|
4753
|
-
created: { title: 'Created', type: 'date', width: '30%' }
|
|
4754
|
-
},
|
|
4755
|
-
toolbarsearch: true,
|
|
4756
|
-
childTable: {
|
|
4757
|
-
title: 'Child Records',
|
|
4758
|
-
actions: {
|
|
4759
|
-
listAction: '/api/users/{id}/orders', // {id} will be replaced with parent record id
|
|
4760
|
-
createAction: '/api/users/{id}/orders',
|
|
4761
|
-
updateAction: '/api/orders',
|
|
4762
|
-
deleteAction: '/api/orders'
|
|
4763
|
-
},
|
|
4764
|
-
fields: {
|
|
4765
|
-
orderId: { key: true, list: false },
|
|
4766
|
-
orderDate: { title: 'Date', type: 'date' },
|
|
4767
|
-
amount: { title: 'Amount', type: 'number' }
|
|
4768
|
-
}
|
|
4769
|
-
},
|
|
4770
|
-
childTableColumnsVisible: true,
|
|
4771
|
-
|
|
4772
|
-
});
|
|
4773
|
-
|
|
4774
|
-
// Or dynamic child table
|
|
4775
|
-
childTable: async function(parentRecord) {
|
|
4776
|
-
return {
|
|
4777
|
-
title: `Orders for ${parentRecord.name}`,
|
|
4778
|
-
actions: {
|
|
4779
|
-
listAction: `/api/users/${parentRecord.id}/orders`
|
|
4780
|
-
},
|
|
4781
|
-
fields: {
|
|
4782
|
-
// Dynamic fields based on parent
|
|
4783
|
-
}
|
|
4784
|
-
};
|
|
4785
|
-
}
|
|
4786
|
-
|
|
4787
|
-
// function for select options
|
|
4788
|
-
fields: {
|
|
4789
|
-
assignee: {
|
|
4790
|
-
title: 'Assigned To',
|
|
4791
|
-
type: 'select',
|
|
4792
|
-
options: async function(params) {
|
|
4793
|
-
// params contains dependsOnValue, dependsOnField, etc.
|
|
4794
|
-
const department = params.dependsOnValue;
|
|
4795
|
-
const response = await fetch(`/api/users?department=${department}`);
|
|
4796
|
-
return response.json();
|
|
4797
|
-
},
|
|
4798
|
-
dependsOn: 'department'
|
|
4799
|
-
}
|
|
4800
|
-
}
|
|
4801
|
-
|
|
4802
|
-
// child table:
|
|
4803
|
-
phoneNumbers: {
|
|
4804
|
-
title: 'Phones',
|
|
4805
|
-
display: (data) => {
|
|
4806
|
-
const img = document.createElement('img');
|
|
4807
|
-
img.className = 'child-opener-image';
|
|
4808
|
-
img.src = '/Content/images/Misc/phone.png';
|
|
4809
|
-
img.title = 'Edit phone numbers';
|
|
4810
|
-
img.style.cursor = 'pointer';
|
|
4811
|
-
|
|
4812
|
-
parentRow = img.closest('tr');
|
|
4813
|
-
img.addEventListener('click', () => {
|
|
4814
|
-
e.stopPropagation();
|
|
4815
|
-
if (parentRow.childRow) {
|
|
4816
|
-
myTable.closeChildTable(parentRow);
|
|
4817
|
-
} else {
|
|
4818
|
-
myTable.openChildTable( parentRow, {
|
|
4819
|
-
title: `${data.record.Name} - Phone numbers`,
|
|
4820
|
-
actions: {
|
|
4821
|
-
listAction: `/PagingPerson/PhoneList?PersonId=${data.record.PersonId}`,
|
|
4822
|
-
deleteAction: '/PagingPerson/DeletePhone',
|
|
4823
|
-
updateAction: '/PagingPerson/UpdatePhone',
|
|
4824
|
-
createAction: `/PagingPerson/CreatePhone?PersonId=${data.record.PersonId}`
|
|
4825
|
-
},
|
|
4826
|
-
fields: {
|
|
4827
|
-
PhoneId: { key: true },
|
|
4828
|
-
Number: { title: 'Number', type: 'text' },
|
|
4829
|
-
Type: { title: 'Type', options: { 0: 'Home', 1: 'Work', 2: 'Mobile' } }
|
|
4830
|
-
}
|
|
4831
|
-
}, (childTable) => {
|
|
4832
|
-
console.log('Child table created');
|
|
4833
|
-
};
|
|
4834
|
-
}
|
|
4835
|
-
});
|
|
4836
|
-
img.addEventListener('click', (e) => {
|
|
4837
|
-
e.stopPropagation();
|
|
4838
|
-
if (parentRow.childRow) {
|
|
4839
|
-
myTable.closeChildTable(parentRow);
|
|
4840
|
-
} else {
|
|
4841
|
-
myTable.openChildTable(parentRow, childOptions);
|
|
4842
|
-
}
|
|
4843
|
-
});
|
|
4844
|
-
|
|
4845
|
-
return img;
|
|
4846
|
-
}
|
|
4847
|
-
}
|
|
4848
|
-
|
|
4849
|
-
// Clear specific options cache
|
|
4850
|
-
table.clearOptionsCache('/api/countries');
|
|
4851
|
-
|
|
4852
|
-
table.load();
|
|
4853
|
-
*/
|
|
4854
|
-
|
|
4855
|
-
window.FTable = FTable;
|
|
4856
|
-
|
|
4857
4739
|
return FTable;
|
|
4858
4740
|
})));
|