@liedekef/ftable 1.1.5 → 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.
Files changed (39) hide show
  1. package/ftable.esm.js +43 -160
  2. package/ftable.js +44 -161
  3. package/ftable.min.js +3 -3
  4. package/ftable.umd.js +44 -161
  5. package/package.json +1 -1
  6. package/themes/basic/ftable_basic.css +25 -25
  7. package/themes/basic/ftable_basic.min.css +1 -1
  8. package/themes/ftable_theme_base.less +35 -35
  9. package/themes/lightcolor/blue/ftable.css +33 -33
  10. package/themes/lightcolor/blue/ftable.min.css +1 -1
  11. package/themes/lightcolor/ftable_lightcolor_base.less +6 -5
  12. package/themes/lightcolor/gray/ftable.css +33 -33
  13. package/themes/lightcolor/gray/ftable.min.css +1 -1
  14. package/themes/lightcolor/green/ftable.css +33 -33
  15. package/themes/lightcolor/green/ftable.min.css +1 -1
  16. package/themes/lightcolor/orange/ftable.css +33 -33
  17. package/themes/lightcolor/orange/ftable.min.css +1 -1
  18. package/themes/lightcolor/red/ftable.css +33 -33
  19. package/themes/lightcolor/red/ftable.min.css +1 -1
  20. package/themes/metro/blue/ftable.css +25 -25
  21. package/themes/metro/blue/ftable.min.css +1 -1
  22. package/themes/metro/brown/ftable.css +25 -25
  23. package/themes/metro/brown/ftable.min.css +1 -1
  24. package/themes/metro/crimson/ftable.css +25 -25
  25. package/themes/metro/crimson/ftable.min.css +1 -1
  26. package/themes/metro/darkgray/ftable.css +25 -25
  27. package/themes/metro/darkgray/ftable.min.css +1 -1
  28. package/themes/metro/darkorange/ftable.css +25 -25
  29. package/themes/metro/darkorange/ftable.min.css +1 -1
  30. package/themes/metro/green/ftable.css +25 -25
  31. package/themes/metro/green/ftable.min.css +1 -1
  32. package/themes/metro/lightgray/ftable.css +25 -25
  33. package/themes/metro/lightgray/ftable.min.css +1 -1
  34. package/themes/metro/pink/ftable.css +25 -25
  35. package/themes/metro/pink/ftable.min.css +1 -1
  36. package/themes/metro/purple/ftable.css +25 -25
  37. package/themes/metro/purple/ftable.min.css +1 -1
  38. package/themes/metro/red/ftable.css +25 -25
  39. 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 = await FTableHttpClient.get(url);
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
@@ -971,10 +971,10 @@ class FTableFormBuilder {
971
971
  const visibleInput = FTableDOMHelper.create('input', {
972
972
  className: field.inputClass || 'datepicker-input',
973
973
  attributes: {
974
- id: 'ftable-toolbarsearch-' + fieldName,
975
974
  id: 'Edit-' + fieldName,
976
975
  type: 'text',
977
976
  'data-date': value,
977
+ placeholder: field.placeholder || '',
978
978
  readOnly: true
979
979
  }
980
980
  });
@@ -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: '',
@@ -1949,6 +1954,7 @@ class FTable extends FTableEventEmitter {
1949
1954
  attributes: {
1950
1955
  id: 'ftable-toolbarsearch-' + fieldName,
1951
1956
  type: 'text',
1957
+ placeholder: field.placeholder || '',
1952
1958
  readOnly: true
1953
1959
  }
1954
1960
  });
@@ -2519,13 +2525,15 @@ class FTable extends FTableEventEmitter {
2519
2525
  // Create overlay to capture clicks outside menu
2520
2526
  this.elements.columnSelectionOverlay = FTableDOMHelper.create('div', {
2521
2527
  className: 'ftable-contextmenu-overlay',
2522
- parent: this.elements.mainContainer
2528
+ //parent: this.elements.mainContainer
2529
+ parent: document.body
2523
2530
  });
2524
2531
 
2525
2532
  // Create the menu
2526
2533
  this.elements.columnSelectionMenu = FTableDOMHelper.create('div', {
2527
2534
  className: 'ftable-column-selection-container',
2528
- parent: this.elements.columnSelectionOverlay
2535
+ //parent: this.elements.columnSelectionOverlay
2536
+ parent: document.body
2529
2537
  });
2530
2538
 
2531
2539
  // Populate menu with column options
@@ -2611,29 +2619,36 @@ class FTable extends FTableEventEmitter {
2611
2619
  }
2612
2620
 
2613
2621
  positionColumnSelectionMenu(e) {
2614
- const containerRect = this.elements.mainContainer.getBoundingClientRect();
2615
- const menuWidth = 200; // Approximate menu width
2616
- const menuHeight = this.columnList.length * 30 + 20; // Approximate height
2622
+ const self = this;
2617
2623
 
2618
- let left = e.clientX - containerRect.left;
2619
- let top = e.clientY - containerRect.top;
2624
+ // Use clientX/clientY (relative to viewport)
2625
+ let left = e.clientX;
2626
+ let top = e.clientY;
2620
2627
 
2621
- // Adjust position to keep menu within container bounds
2622
- if (left + menuWidth > containerRect.width) {
2623
- left = Math.max(0, containerRect.width - menuWidth);
2624
- }
2628
+ // Define minimum width
2629
+ const minWidth = 100;
2625
2630
 
2626
- if (top + menuHeight > containerRect.height) {
2627
- top = Math.max(0, containerRect.height - menuHeight);
2628
- }
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;
2629
2641
 
2630
- this.elements.columnSelectionMenu.style.left = left + 'px';
2631
- this.elements.columnSelectionMenu.style.top = top + 'px';
2642
+ if (left + menuWidth > windowWidth) {
2643
+ left = Math.max(10, windowWidth - menuWidth - 10); // 10px margin
2644
+ self.elements.columnSelectionMenu.style.left = `${left}px`;
2645
+ }
2632
2646
  }
2633
2647
 
2634
2648
  hideColumnSelectionMenu() {
2635
2649
  if (this.elements.columnSelectionOverlay) {
2636
2650
  this.elements.columnSelectionOverlay.remove();
2651
+ this.elements.columnSelectionMenu.remove();
2637
2652
  this.elements.columnSelectionOverlay = null;
2638
2653
  this.elements.columnSelectionMenu = null;
2639
2654
  }
@@ -2876,7 +2891,9 @@ class FTable extends FTableEventEmitter {
2876
2891
  if (typeof listAction === 'function') {
2877
2892
  data = await listAction(params);
2878
2893
  } else if (typeof listAction === 'string') {
2879
- data = await FTableHttpClient.get(listAction, params);
2894
+ data = this.options.forcePost
2895
+ ? await FTableHttpClient.post(listAction, params)
2896
+ : await FTableHttpClient.get(listAction, params);
2880
2897
  } else {
2881
2898
  throw new Error('No valid listAction provided');
2882
2899
  }
@@ -4410,7 +4427,9 @@ class FTable extends FTableEventEmitter {
4410
4427
  ...params
4411
4428
  };
4412
4429
 
4413
- const response = await FTableHttpClient.get(url, fullParams);
4430
+ const response = this.options.forcePost
4431
+ ? await FTableHttpClient.post(url, fullParams)
4432
+ : await FTableHttpClient.get(url, fullParams);
4414
4433
 
4415
4434
  if (!response || !response.Record) {
4416
4435
  throw new Error('Invalid response or missing Record');
@@ -4712,140 +4731,4 @@ class FTable extends FTableEventEmitter {
4712
4731
  }
4713
4732
  }
4714
4733
 
4715
- // Export for use
4716
- //window.FTable = FTable;
4717
-
4718
- // Usage example:
4719
- /*
4720
- const table = new FTable('#myTable', {
4721
- title: 'My Data Table',
4722
- paging: true,
4723
- pageSize: 25,
4724
- sorting: true,
4725
- selecting: true,
4726
- actions: {
4727
- listAction: '/api/users',
4728
- createAction: '/api/users',
4729
- updateAction: '/api/users',
4730
- deleteAction: '/api/users'
4731
- },
4732
- fields: {
4733
- id: { key: true, list: false },
4734
- name: {
4735
- title: 'Name',
4736
- type: 'text',
4737
- inputAttributes: "maxlength=100 required"
4738
- },
4739
- email: {
4740
- title: 'Email',
4741
- type: 'email',
4742
- width: '40%',
4743
- inputAttributes: {
4744
- pattern: '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$'
4745
- }
4746
- },
4747
- created: { title: 'Created', type: 'date', width: '30%' }
4748
- },
4749
- toolbarsearch: true,
4750
- childTable: {
4751
- title: 'Child Records',
4752
- actions: {
4753
- listAction: '/api/users/{id}/orders', // {id} will be replaced with parent record id
4754
- createAction: '/api/users/{id}/orders',
4755
- updateAction: '/api/orders',
4756
- deleteAction: '/api/orders'
4757
- },
4758
- fields: {
4759
- orderId: { key: true, list: false },
4760
- orderDate: { title: 'Date', type: 'date' },
4761
- amount: { title: 'Amount', type: 'number' }
4762
- }
4763
- },
4764
- childTableColumnsVisible: true,
4765
-
4766
- });
4767
-
4768
- // Or dynamic child table
4769
- childTable: async function(parentRecord) {
4770
- return {
4771
- title: `Orders for ${parentRecord.name}`,
4772
- actions: {
4773
- listAction: `/api/users/${parentRecord.id}/orders`
4774
- },
4775
- fields: {
4776
- // Dynamic fields based on parent
4777
- }
4778
- };
4779
- }
4780
-
4781
- // function for select options
4782
- fields: {
4783
- assignee: {
4784
- title: 'Assigned To',
4785
- type: 'select',
4786
- options: async function(params) {
4787
- // params contains dependsOnValue, dependsOnField, etc.
4788
- const department = params.dependsOnValue;
4789
- const response = await fetch(`/api/users?department=${department}`);
4790
- return response.json();
4791
- },
4792
- dependsOn: 'department'
4793
- }
4794
- }
4795
-
4796
- // child table:
4797
- phoneNumbers: {
4798
- title: 'Phones',
4799
- display: (data) => {
4800
- const img = document.createElement('img');
4801
- img.className = 'child-opener-image';
4802
- img.src = '/Content/images/Misc/phone.png';
4803
- img.title = 'Edit phone numbers';
4804
- img.style.cursor = 'pointer';
4805
-
4806
- parentRow = img.closest('tr');
4807
- img.addEventListener('click', () => {
4808
- e.stopPropagation();
4809
- if (parentRow.childRow) {
4810
- myTable.closeChildTable(parentRow);
4811
- } else {
4812
- myTable.openChildTable( parentRow, {
4813
- title: `${data.record.Name} - Phone numbers`,
4814
- actions: {
4815
- listAction: `/PagingPerson/PhoneList?PersonId=${data.record.PersonId}`,
4816
- deleteAction: '/PagingPerson/DeletePhone',
4817
- updateAction: '/PagingPerson/UpdatePhone',
4818
- createAction: `/PagingPerson/CreatePhone?PersonId=${data.record.PersonId}`
4819
- },
4820
- fields: {
4821
- PhoneId: { key: true },
4822
- Number: { title: 'Number', type: 'text' },
4823
- Type: { title: 'Type', options: { 0: 'Home', 1: 'Work', 2: 'Mobile' } }
4824
- }
4825
- }, (childTable) => {
4826
- console.log('Child table created');
4827
- };
4828
- }
4829
- });
4830
- img.addEventListener('click', (e) => {
4831
- e.stopPropagation();
4832
- if (parentRow.childRow) {
4833
- myTable.closeChildTable(parentRow);
4834
- } else {
4835
- myTable.openChildTable(parentRow, childOptions);
4836
- }
4837
- });
4838
-
4839
- return img;
4840
- }
4841
- }
4842
-
4843
- // Clear specific options cache
4844
- table.clearOptionsCache('/api/countries');
4845
-
4846
- table.load();
4847
- */
4848
-
4849
- window.FTable = FTable;
4850
-
4851
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
- // Modern fTable - Vanilla JS Refactor
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 = await FTableHttpClient.get(url);
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
@@ -976,10 +976,10 @@ class FTableFormBuilder {
976
976
  const visibleInput = FTableDOMHelper.create('input', {
977
977
  className: field.inputClass || 'datepicker-input',
978
978
  attributes: {
979
- id: 'ftable-toolbarsearch-' + fieldName,
980
979
  id: 'Edit-' + fieldName,
981
980
  type: 'text',
982
981
  'data-date': value,
982
+ placeholder: field.placeholder || '',
983
983
  readOnly: true
984
984
  }
985
985
  });
@@ -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: '',
@@ -1954,6 +1959,7 @@ class FTable extends FTableEventEmitter {
1954
1959
  attributes: {
1955
1960
  id: 'ftable-toolbarsearch-' + fieldName,
1956
1961
  type: 'text',
1962
+ placeholder: field.placeholder || '',
1957
1963
  readOnly: true
1958
1964
  }
1959
1965
  });
@@ -2524,13 +2530,15 @@ class FTable extends FTableEventEmitter {
2524
2530
  // Create overlay to capture clicks outside menu
2525
2531
  this.elements.columnSelectionOverlay = FTableDOMHelper.create('div', {
2526
2532
  className: 'ftable-contextmenu-overlay',
2527
- parent: this.elements.mainContainer
2533
+ //parent: this.elements.mainContainer
2534
+ parent: document.body
2528
2535
  });
2529
2536
 
2530
2537
  // Create the menu
2531
2538
  this.elements.columnSelectionMenu = FTableDOMHelper.create('div', {
2532
2539
  className: 'ftable-column-selection-container',
2533
- parent: this.elements.columnSelectionOverlay
2540
+ //parent: this.elements.columnSelectionOverlay
2541
+ parent: document.body
2534
2542
  });
2535
2543
 
2536
2544
  // Populate menu with column options
@@ -2616,29 +2624,36 @@ class FTable extends FTableEventEmitter {
2616
2624
  }
2617
2625
 
2618
2626
  positionColumnSelectionMenu(e) {
2619
- const containerRect = this.elements.mainContainer.getBoundingClientRect();
2620
- const menuWidth = 200; // Approximate menu width
2621
- const menuHeight = this.columnList.length * 30 + 20; // Approximate height
2627
+ const self = this;
2622
2628
 
2623
- let left = e.clientX - containerRect.left;
2624
- let top = e.clientY - containerRect.top;
2629
+ // Use clientX/clientY (relative to viewport)
2630
+ let left = e.clientX;
2631
+ let top = e.clientY;
2625
2632
 
2626
- // Adjust position to keep menu within container bounds
2627
- if (left + menuWidth > containerRect.width) {
2628
- left = Math.max(0, containerRect.width - menuWidth);
2629
- }
2633
+ // Define minimum width
2634
+ const minWidth = 100;
2630
2635
 
2631
- if (top + menuHeight > containerRect.height) {
2632
- top = Math.max(0, containerRect.height - menuHeight);
2633
- }
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;
2634
2646
 
2635
- this.elements.columnSelectionMenu.style.left = left + 'px';
2636
- this.elements.columnSelectionMenu.style.top = top + 'px';
2647
+ if (left + menuWidth > windowWidth) {
2648
+ left = Math.max(10, windowWidth - menuWidth - 10); // 10px margin
2649
+ self.elements.columnSelectionMenu.style.left = `${left}px`;
2650
+ }
2637
2651
  }
2638
2652
 
2639
2653
  hideColumnSelectionMenu() {
2640
2654
  if (this.elements.columnSelectionOverlay) {
2641
2655
  this.elements.columnSelectionOverlay.remove();
2656
+ this.elements.columnSelectionMenu.remove();
2642
2657
  this.elements.columnSelectionOverlay = null;
2643
2658
  this.elements.columnSelectionMenu = null;
2644
2659
  }
@@ -2881,7 +2896,9 @@ class FTable extends FTableEventEmitter {
2881
2896
  if (typeof listAction === 'function') {
2882
2897
  data = await listAction(params);
2883
2898
  } else if (typeof listAction === 'string') {
2884
- data = await FTableHttpClient.get(listAction, params);
2899
+ data = this.options.forcePost
2900
+ ? await FTableHttpClient.post(listAction, params)
2901
+ : await FTableHttpClient.get(listAction, params);
2885
2902
  } else {
2886
2903
  throw new Error('No valid listAction provided');
2887
2904
  }
@@ -4415,7 +4432,9 @@ class FTable extends FTableEventEmitter {
4415
4432
  ...params
4416
4433
  };
4417
4434
 
4418
- const response = await FTableHttpClient.get(url, fullParams);
4435
+ const response = this.options.forcePost
4436
+ ? await FTableHttpClient.post(url, fullParams)
4437
+ : await FTableHttpClient.get(url, fullParams);
4419
4438
 
4420
4439
  if (!response || !response.Record) {
4421
4440
  throw new Error('Invalid response or missing Record');
@@ -4717,141 +4736,5 @@ class FTable extends FTableEventEmitter {
4717
4736
  }
4718
4737
  }
4719
4738
 
4720
- // Export for use
4721
- //window.FTable = FTable;
4722
-
4723
- // Usage example:
4724
- /*
4725
- const table = new FTable('#myTable', {
4726
- title: 'My Data Table',
4727
- paging: true,
4728
- pageSize: 25,
4729
- sorting: true,
4730
- selecting: true,
4731
- actions: {
4732
- listAction: '/api/users',
4733
- createAction: '/api/users',
4734
- updateAction: '/api/users',
4735
- deleteAction: '/api/users'
4736
- },
4737
- fields: {
4738
- id: { key: true, list: false },
4739
- name: {
4740
- title: 'Name',
4741
- type: 'text',
4742
- inputAttributes: "maxlength=100 required"
4743
- },
4744
- email: {
4745
- title: 'Email',
4746
- type: 'email',
4747
- width: '40%',
4748
- inputAttributes: {
4749
- pattern: '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$'
4750
- }
4751
- },
4752
- created: { title: 'Created', type: 'date', width: '30%' }
4753
- },
4754
- toolbarsearch: true,
4755
- childTable: {
4756
- title: 'Child Records',
4757
- actions: {
4758
- listAction: '/api/users/{id}/orders', // {id} will be replaced with parent record id
4759
- createAction: '/api/users/{id}/orders',
4760
- updateAction: '/api/orders',
4761
- deleteAction: '/api/orders'
4762
- },
4763
- fields: {
4764
- orderId: { key: true, list: false },
4765
- orderDate: { title: 'Date', type: 'date' },
4766
- amount: { title: 'Amount', type: 'number' }
4767
- }
4768
- },
4769
- childTableColumnsVisible: true,
4770
-
4771
- });
4772
-
4773
- // Or dynamic child table
4774
- childTable: async function(parentRecord) {
4775
- return {
4776
- title: `Orders for ${parentRecord.name}`,
4777
- actions: {
4778
- listAction: `/api/users/${parentRecord.id}/orders`
4779
- },
4780
- fields: {
4781
- // Dynamic fields based on parent
4782
- }
4783
- };
4784
- }
4785
-
4786
- // function for select options
4787
- fields: {
4788
- assignee: {
4789
- title: 'Assigned To',
4790
- type: 'select',
4791
- options: async function(params) {
4792
- // params contains dependsOnValue, dependsOnField, etc.
4793
- const department = params.dependsOnValue;
4794
- const response = await fetch(`/api/users?department=${department}`);
4795
- return response.json();
4796
- },
4797
- dependsOn: 'department'
4798
- }
4799
- }
4800
-
4801
- // child table:
4802
- phoneNumbers: {
4803
- title: 'Phones',
4804
- display: (data) => {
4805
- const img = document.createElement('img');
4806
- img.className = 'child-opener-image';
4807
- img.src = '/Content/images/Misc/phone.png';
4808
- img.title = 'Edit phone numbers';
4809
- img.style.cursor = 'pointer';
4810
-
4811
- parentRow = img.closest('tr');
4812
- img.addEventListener('click', () => {
4813
- e.stopPropagation();
4814
- if (parentRow.childRow) {
4815
- myTable.closeChildTable(parentRow);
4816
- } else {
4817
- myTable.openChildTable( parentRow, {
4818
- title: `${data.record.Name} - Phone numbers`,
4819
- actions: {
4820
- listAction: `/PagingPerson/PhoneList?PersonId=${data.record.PersonId}`,
4821
- deleteAction: '/PagingPerson/DeletePhone',
4822
- updateAction: '/PagingPerson/UpdatePhone',
4823
- createAction: `/PagingPerson/CreatePhone?PersonId=${data.record.PersonId}`
4824
- },
4825
- fields: {
4826
- PhoneId: { key: true },
4827
- Number: { title: 'Number', type: 'text' },
4828
- Type: { title: 'Type', options: { 0: 'Home', 1: 'Work', 2: 'Mobile' } }
4829
- }
4830
- }, (childTable) => {
4831
- console.log('Child table created');
4832
- };
4833
- }
4834
- });
4835
- img.addEventListener('click', (e) => {
4836
- e.stopPropagation();
4837
- if (parentRow.childRow) {
4838
- myTable.closeChildTable(parentRow);
4839
- } else {
4840
- myTable.openChildTable(parentRow, childOptions);
4841
- }
4842
- });
4843
-
4844
- return img;
4845
- }
4846
- }
4847
-
4848
- // Clear specific options cache
4849
- table.clearOptionsCache('/api/countries');
4850
-
4851
- table.load();
4852
- */
4853
-
4854
- window.FTable = FTable;
4855
-
4856
4739
  return FTable;
4857
4740
  })));