@liedekef/ftable 1.1.0 → 1.1.3
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 +9 -0
- package/ftable.esm.js +184 -121
- package/ftable.js +191 -122
- package/ftable.min.js +3 -3
- package/ftable.umd.js +191 -123
- package/package.json +3 -4
package/ftable.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
// Modern fTable - Vanilla JS Refactor
|
|
2
1
|
|
|
3
|
-
|
|
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
|
|
8
|
+
|
|
9
|
+
const FTABLE_DEFAULT_MESSAGES = {
|
|
4
10
|
serverCommunicationError: 'An error occurred while communicating to the server.',
|
|
5
11
|
loadingMessage: 'Loading records...',
|
|
6
12
|
noDataAvailable: 'No data available!',
|
|
@@ -903,6 +909,10 @@ class FTableFormBuilder {
|
|
|
903
909
|
case 'file':
|
|
904
910
|
input = this.createFileInput(fieldName, field, value);
|
|
905
911
|
break;
|
|
912
|
+
case 'date':
|
|
913
|
+
case 'datetime-local':
|
|
914
|
+
input = this.createDateInput(fieldName, field, value);
|
|
915
|
+
break;
|
|
906
916
|
default:
|
|
907
917
|
input = this.createTypedInput(fieldName, field, value);
|
|
908
918
|
}
|
|
@@ -947,14 +957,65 @@ class FTableFormBuilder {
|
|
|
947
957
|
return container;
|
|
948
958
|
}
|
|
949
959
|
|
|
960
|
+
createDateInput(fieldName, field, value) {
|
|
961
|
+
// Check if FDatepicker is available
|
|
962
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
963
|
+
const dateFormat = field.dateFormat || this.options.defaultDateFormat;
|
|
964
|
+
|
|
965
|
+
const container = document.createElement('div');
|
|
966
|
+
// Create hidden input
|
|
967
|
+
const hiddenInput = Object.assign(document.createElement('input'), {
|
|
968
|
+
id: 'real-' + fieldName,
|
|
969
|
+
type: 'hidden',
|
|
970
|
+
value: value || '',
|
|
971
|
+
name: fieldName
|
|
972
|
+
});
|
|
973
|
+
// Create visible input
|
|
974
|
+
const visibleInput = Object.assign(document.createElement('input'), {
|
|
975
|
+
className: field.inputClass || 'datepicker-input',
|
|
976
|
+
id: 'Edit-' + fieldName,
|
|
977
|
+
type: 'text',
|
|
978
|
+
'data-date': 'alt-' + fieldName,
|
|
979
|
+
value: value || '',
|
|
980
|
+
readOnly: true
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
if (value) {
|
|
984
|
+
hiddenInput.value = value;
|
|
985
|
+
visibleInput.dataset.date = value;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// Set any additional attributes
|
|
989
|
+
if (field.inputAttributes) {
|
|
990
|
+
Object.keys(field.inputAttributes).forEach(key => {
|
|
991
|
+
visibleInput.setAttribute(key, field.inputAttributes[key]);
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
// Append both inputs
|
|
996
|
+
container.appendChild(hiddenInput);
|
|
997
|
+
container.appendChild(visibleInput);
|
|
998
|
+
|
|
999
|
+
// Apply FDatepicker
|
|
1000
|
+
const picker = new FDatepicker(visibleInput, {
|
|
1001
|
+
format: dateFormat,
|
|
1002
|
+
altField: 'real-' + fieldName,
|
|
1003
|
+
altFormat: 'Y-m-d'
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
return container;
|
|
1007
|
+
} else {
|
|
1008
|
+
return createTypedInput(fieldName, field, value);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
950
1012
|
createTypedInput(fieldName, field, value) {
|
|
951
1013
|
const inputType = field.type || 'text';
|
|
952
1014
|
const attributes = {
|
|
953
1015
|
type: inputType,
|
|
954
1016
|
id: `Edit-${fieldName}`,
|
|
955
1017
|
placeholder: field.placeholder || '',
|
|
956
|
-
value: value || ''
|
|
957
|
-
class: field.inputClass || ''
|
|
1018
|
+
value: value || ''
|
|
958
1019
|
};
|
|
959
1020
|
|
|
960
1021
|
// extra check for name and multiple
|
|
@@ -974,22 +1035,10 @@ class FTableFormBuilder {
|
|
|
974
1035
|
}
|
|
975
1036
|
attributes.name = name;
|
|
976
1037
|
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
attributes
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
// Handle readonly attribute
|
|
983
|
-
if (field.readonly) {
|
|
984
|
-
attributes.readonly = 'readonly';
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// Handle disabled attribute
|
|
988
|
-
if (field.disabled) {
|
|
989
|
-
attributes.disabled = 'disabled';
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
const input = FTableDOMHelper.create('input', { attributes });
|
|
1038
|
+
const input = FTableDOMHelper.create('input', {
|
|
1039
|
+
className: field.inputClass || '',
|
|
1040
|
+
attributes: attributes
|
|
1041
|
+
});
|
|
993
1042
|
|
|
994
1043
|
// Prevent form submit on Enter, trigger change instead
|
|
995
1044
|
input.addEventListener('keypress', (e) => {
|
|
@@ -1236,18 +1285,6 @@ class FTableFormBuilder {
|
|
|
1236
1285
|
return wrapper;
|
|
1237
1286
|
}
|
|
1238
1287
|
|
|
1239
|
-
createDateInput(fieldName, field, value) {
|
|
1240
|
-
return FTableDOMHelper.create('input', {
|
|
1241
|
-
attributes: {
|
|
1242
|
-
type: 'date',
|
|
1243
|
-
name: fieldName,
|
|
1244
|
-
id: `Edit-${fieldName}`,
|
|
1245
|
-
class: field.inputClass || '',
|
|
1246
|
-
value: value || ''
|
|
1247
|
-
}
|
|
1248
|
-
});
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
1288
|
populateSelectOptions(select, options, selectedValue) {
|
|
1252
1289
|
select.innerHTML = ''; // Clear existing options
|
|
1253
1290
|
|
|
@@ -1330,6 +1367,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1330
1367
|
}
|
|
1331
1368
|
|
|
1332
1369
|
this.options = this.mergeOptions(options);
|
|
1370
|
+
this.verifyOptions();
|
|
1333
1371
|
this.logger = new FTableLogger(this.options.logLevel);
|
|
1334
1372
|
this.userPrefs = new FTableUserPreferences('', this.options.saveUserPreferencesMethod);
|
|
1335
1373
|
this.formBuilder = new FTableFormBuilder(this.options, this);
|
|
@@ -1364,15 +1402,18 @@ class FTable extends FTableEventEmitter {
|
|
|
1364
1402
|
fields: {},
|
|
1365
1403
|
animationsEnabled: true,
|
|
1366
1404
|
loadingAnimationDelay: 1000,
|
|
1367
|
-
|
|
1405
|
+
defaultDateLocale: 'en',
|
|
1406
|
+
defaultDateFormat: 'm/d/Y',
|
|
1368
1407
|
saveUserPreferences: true,
|
|
1369
1408
|
saveUserPreferencesMethod: 'localStorage',
|
|
1370
1409
|
defaultSorting: '',
|
|
1410
|
+
tableReset: false,
|
|
1371
1411
|
|
|
1372
1412
|
// Paging
|
|
1373
1413
|
paging: false,
|
|
1374
1414
|
pageList: 'normal',
|
|
1375
1415
|
pageSize: 10,
|
|
1416
|
+
pageSizes: [10, 25, 50, 100],
|
|
1376
1417
|
gotoPageArea: 'combobox',
|
|
1377
1418
|
|
|
1378
1419
|
// Sorting
|
|
@@ -1396,7 +1437,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1396
1437
|
listCache: 30000, // or listCache: 30000 (duration in ms)
|
|
1397
1438
|
|
|
1398
1439
|
// Messages
|
|
1399
|
-
messages: { ...
|
|
1440
|
+
messages: { ...FTABLE_DEFAULT_MESSAGES } // Safe copy
|
|
1400
1441
|
};
|
|
1401
1442
|
|
|
1402
1443
|
return this.deepMerge(defaults, options);
|
|
@@ -1416,9 +1457,15 @@ class FTable extends FTableEventEmitter {
|
|
|
1416
1457
|
return result;
|
|
1417
1458
|
}
|
|
1418
1459
|
|
|
1460
|
+
verifyOptions() {
|
|
1461
|
+
if (this.options.pageSize && !this.options.pageSizes.includes(this.options.pageSize)) {
|
|
1462
|
+
this.options.pageSize = this.options.pageSizes[0];
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1419
1466
|
// Public
|
|
1420
1467
|
static setMessages(customMessages) {
|
|
1421
|
-
Object.assign(
|
|
1468
|
+
Object.assign(FTABLE_DEFAULT_MESSAGES, customMessages);
|
|
1422
1469
|
}
|
|
1423
1470
|
|
|
1424
1471
|
init() {
|
|
@@ -1885,16 +1932,49 @@ class FTable extends FTableEventEmitter {
|
|
|
1885
1932
|
if (!field.type && field.options) {
|
|
1886
1933
|
field.type = 'select';
|
|
1887
1934
|
}
|
|
1935
|
+
const fieldSearchName = 'ftable-toolbarsearch-' + fieldName;
|
|
1888
1936
|
|
|
1889
1937
|
switch (field.type) {
|
|
1890
1938
|
case 'date':
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1939
|
+
case 'datetime-local':
|
|
1940
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
1941
|
+
const dateFormat = field.dateFormat || this.options.defaultDateFormat;
|
|
1942
|
+
input = document.createElement('div');
|
|
1943
|
+
// Create hidden input
|
|
1944
|
+
const hiddenInput = Object.assign(document.createElement('input'), {
|
|
1945
|
+
id: 'ftable-toolbarsearch-extra-' + fieldName,
|
|
1946
|
+
type: 'hidden',
|
|
1947
|
+
name: fieldName,
|
|
1948
|
+
className: 'ftable-toolbarsearch-extra'
|
|
1949
|
+
});
|
|
1950
|
+
// Create visible input
|
|
1951
|
+
const visibleInput = Object.assign(document.createElement('input'), {
|
|
1952
|
+
className: 'ftable-toolbarsearch',
|
|
1953
|
+
id: 'ftable-toolbarsearch-' + fieldName,
|
|
1954
|
+
type: 'text',
|
|
1955
|
+
readOnly: true
|
|
1956
|
+
});
|
|
1957
|
+
// Append both inputs
|
|
1958
|
+
input.appendChild(hiddenInput);
|
|
1959
|
+
input.appendChild(visibleInput);
|
|
1960
|
+
|
|
1961
|
+
// Apply FDatepicker
|
|
1962
|
+
const picker = new FDatepicker(visibleInput, {
|
|
1963
|
+
format: dateFormat,
|
|
1964
|
+
altField: 'ftable-toolbarsearch-extra-' + fieldName,
|
|
1965
|
+
altFormat: 'Y-m-d'
|
|
1966
|
+
});
|
|
1967
|
+
|
|
1968
|
+
} else {
|
|
1969
|
+
input = FTableDOMHelper.create('input', {
|
|
1970
|
+
className: 'ftable-toolbarsearch',
|
|
1971
|
+
attributes: {
|
|
1972
|
+
type: 'date',
|
|
1973
|
+
'data-field-name': fieldName,
|
|
1974
|
+
id: fieldSearchName,
|
|
1975
|
+
}
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1898
1978
|
break;
|
|
1899
1979
|
|
|
1900
1980
|
case 'checkbox':
|
|
@@ -1902,10 +1982,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1902
1982
|
input = await this.createSelectForSearch(fieldName, field, true);
|
|
1903
1983
|
} else {
|
|
1904
1984
|
input = FTableDOMHelper.create('input', {
|
|
1985
|
+
className: 'ftable-toolbarsearch',
|
|
1905
1986
|
attributes: {
|
|
1906
1987
|
type: 'text',
|
|
1907
1988
|
'data-field-name': fieldName,
|
|
1908
|
-
|
|
1989
|
+
id: fieldSearchName,
|
|
1909
1990
|
placeholder: 'Search...'
|
|
1910
1991
|
}
|
|
1911
1992
|
});
|
|
@@ -1917,10 +1998,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1917
1998
|
input = await this.createSelectForSearch(fieldName, field, false);
|
|
1918
1999
|
} else {
|
|
1919
2000
|
input = FTableDOMHelper.create('input', {
|
|
2001
|
+
className: 'ftable-toolbarsearch',
|
|
1920
2002
|
attributes: {
|
|
1921
2003
|
type: 'text',
|
|
1922
2004
|
'data-field-name': fieldName,
|
|
1923
|
-
|
|
2005
|
+
id: fieldSearchName,
|
|
1924
2006
|
placeholder: 'Search...'
|
|
1925
2007
|
}
|
|
1926
2008
|
});
|
|
@@ -1929,10 +2011,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1929
2011
|
|
|
1930
2012
|
default:
|
|
1931
2013
|
input = FTableDOMHelper.create('input', {
|
|
2014
|
+
className: 'ftable-toolbarsearch',
|
|
1932
2015
|
attributes: {
|
|
1933
2016
|
type: 'text',
|
|
1934
2017
|
'data-field-name': fieldName,
|
|
1935
|
-
|
|
2018
|
+
id: fieldSearchName,
|
|
1936
2019
|
placeholder: 'Search...'
|
|
1937
2020
|
}
|
|
1938
2021
|
});
|
|
@@ -1985,9 +2068,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1985
2068
|
}
|
|
1986
2069
|
|
|
1987
2070
|
async createSelectForSearch(fieldName, field, isCheckboxValues) {
|
|
2071
|
+
const fieldSearchName = 'ftable-toolbarsearch-' + fieldName;
|
|
1988
2072
|
const select = FTableDOMHelper.create('select', {
|
|
1989
2073
|
attributes: {
|
|
1990
2074
|
'data-field-name': fieldName,
|
|
2075
|
+
id: fieldSearchName,
|
|
1991
2076
|
class: 'ftable-toolbarsearch'
|
|
1992
2077
|
}
|
|
1993
2078
|
});
|
|
@@ -2211,7 +2296,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2211
2296
|
if (Array.isArray(state.sorting)) {
|
|
2212
2297
|
this.state.sorting = state.sorting;
|
|
2213
2298
|
}
|
|
2214
|
-
if (state.pageSize) {
|
|
2299
|
+
if (state.pageSize && this.options.pageSizes.includes(state.pageSize)) {
|
|
2215
2300
|
this.state.pageSize = state.pageSize;
|
|
2216
2301
|
}
|
|
2217
2302
|
} catch (error) {
|
|
@@ -2381,9 +2466,6 @@ class FTable extends FTableEventEmitter {
|
|
|
2381
2466
|
this.createToolbarButtons();
|
|
2382
2467
|
this.createCustomToolbarItems();
|
|
2383
2468
|
|
|
2384
|
-
// Handle window unload
|
|
2385
|
-
this.handlePageUnload();
|
|
2386
|
-
|
|
2387
2469
|
// Keyboard shortcuts
|
|
2388
2470
|
this.bindKeyboardEvents();
|
|
2389
2471
|
|
|
@@ -2670,20 +2752,6 @@ class FTable extends FTableEventEmitter {
|
|
|
2670
2752
|
});
|
|
2671
2753
|
}
|
|
2672
2754
|
|
|
2673
|
-
handlePageUnload() {
|
|
2674
|
-
let unloadingPage = false;
|
|
2675
|
-
|
|
2676
|
-
window.addEventListener('beforeunload', () => {
|
|
2677
|
-
unloadingPage = true;
|
|
2678
|
-
});
|
|
2679
|
-
|
|
2680
|
-
window.addEventListener('unload', () => {
|
|
2681
|
-
unloadingPage = false;
|
|
2682
|
-
});
|
|
2683
|
-
|
|
2684
|
-
this.unloadingPage = () => unloadingPage;
|
|
2685
|
-
}
|
|
2686
|
-
|
|
2687
2755
|
bindKeyboardEvents() {
|
|
2688
2756
|
if (this.options.selecting) {
|
|
2689
2757
|
this.shiftKeyDown = false;
|
|
@@ -3011,7 +3079,19 @@ class FTable extends FTableEventEmitter {
|
|
|
3011
3079
|
}
|
|
3012
3080
|
|
|
3013
3081
|
if (field.type === 'date' && value) {
|
|
3014
|
-
|
|
3082
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
3083
|
+
return FDatepicker.formatDate(this._parseDate(value), field.dateFormat || this.options.defaultDateFormat);
|
|
3084
|
+
} else {
|
|
3085
|
+
return this.formatDate(value, field.dateLocale || this.options.defaultDateLocale || 'en' );
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
|
|
3089
|
+
if (field.type === 'datetime-local' && value) {
|
|
3090
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
3091
|
+
return FDatepicker.formatDate(this._parseDate(value), field.dateFormat || this.options.defaultDateFormat);
|
|
3092
|
+
} else {
|
|
3093
|
+
return this.formatDateTime(value, field.dateLocale || this.options.defaultDateLocale || 'en' );
|
|
3094
|
+
}
|
|
3015
3095
|
}
|
|
3016
3096
|
|
|
3017
3097
|
if (field.type === 'checkbox') {
|
|
@@ -3026,18 +3106,53 @@ class FTable extends FTableEventEmitter {
|
|
|
3026
3106
|
return value || '';
|
|
3027
3107
|
}
|
|
3028
3108
|
|
|
3109
|
+
_parseDate(dateString) {
|
|
3110
|
+
if (dateString.includes('Date')) { // Format: /Date(1320259705710)/
|
|
3111
|
+
return new Date(
|
|
3112
|
+
parseInt(dateString.substr(6), 10)
|
|
3113
|
+
);
|
|
3114
|
+
} else if (dateString.length == 10) { // Format: 2011-01-01
|
|
3115
|
+
return new Date(
|
|
3116
|
+
parseInt(dateString.substr(0, 4), 10),
|
|
3117
|
+
parseInt(dateString.substr(5, 2), 10) - 1,
|
|
3118
|
+
parseInt(dateString.substr(8, 2), 10)
|
|
3119
|
+
);
|
|
3120
|
+
} else if (dateString.length == 19) { // Format: 2011-01-01 20:32:42
|
|
3121
|
+
return new Date(
|
|
3122
|
+
parseInt(dateString.substr(0, 4), 10),
|
|
3123
|
+
parseInt(dateString.substr(5, 2), 10) - 1,
|
|
3124
|
+
parseInt(dateString.substr(8, 2), 10),
|
|
3125
|
+
parseInt(dateString.substr(11, 2), 10),
|
|
3126
|
+
parseInt(dateString.substr(14, 2), 10),
|
|
3127
|
+
parseInt(dateString.substr(17, 2), 10)
|
|
3128
|
+
);
|
|
3129
|
+
} else {
|
|
3130
|
+
return new Date(dateString);
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
|
|
3029
3134
|
formatDate(dateValue, format) {
|
|
3030
3135
|
if (!dateValue) return '';
|
|
3031
|
-
|
|
3032
|
-
const date = new Date(dateValue);
|
|
3033
|
-
if (isNaN(date.getTime())) return dateValue;
|
|
3034
3136
|
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3137
|
+
const date = this._parseDate(dateValue);
|
|
3138
|
+
try {
|
|
3139
|
+
if (isNaN(date.getTime())) return dateValue;
|
|
3140
|
+
return date.toLocaleDateString(format,{ year: "numeric", month: "2-digit", day: "2-digit" });
|
|
3141
|
+
} catch {
|
|
3142
|
+
return dateValue;
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
formatDateTime(dateValue, format) {
|
|
3147
|
+
if (!dateValue) return '';
|
|
3148
|
+
|
|
3149
|
+
const date = this._parseDate(dateValue);
|
|
3150
|
+
try {
|
|
3151
|
+
if (isNaN(date.getTime())) return dateValue;
|
|
3152
|
+
return date.toLocaleString(format);
|
|
3153
|
+
} catch {
|
|
3154
|
+
return dateValue;
|
|
3155
|
+
}
|
|
3041
3156
|
}
|
|
3042
3157
|
|
|
3043
3158
|
getCheckboxText(fieldName, value) {
|
|
@@ -4059,55 +4174,6 @@ class FTable extends FTableEventEmitter {
|
|
|
4059
4174
|
});
|
|
4060
4175
|
}
|
|
4061
4176
|
|
|
4062
|
-
// Data validation
|
|
4063
|
-
validateRecord(record, operation = 'create') {
|
|
4064
|
-
const errors = [];
|
|
4065
|
-
|
|
4066
|
-
Object.entries(this.options.fields).forEach(([fieldName, field]) => {
|
|
4067
|
-
const value = record[fieldName];
|
|
4068
|
-
|
|
4069
|
-
// Required field validation
|
|
4070
|
-
if (field.required && (!value || value.toString().trim() === '')) {
|
|
4071
|
-
errors.push(`${field.title || fieldName} is required`);
|
|
4072
|
-
}
|
|
4073
|
-
|
|
4074
|
-
// Type validation
|
|
4075
|
-
if (value && field.validate && typeof field.validate === 'function') {
|
|
4076
|
-
const validationResult = field.validate(value, record);
|
|
4077
|
-
if (validationResult !== true) {
|
|
4078
|
-
errors.push(validationResult || `${field.title || fieldName} is invalid`);
|
|
4079
|
-
}
|
|
4080
|
-
}
|
|
4081
|
-
|
|
4082
|
-
// Built-in type validations
|
|
4083
|
-
if (value) {
|
|
4084
|
-
switch (field.type) {
|
|
4085
|
-
case 'email':
|
|
4086
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
4087
|
-
if (!emailRegex.test(value)) {
|
|
4088
|
-
errors.push(`${field.title || fieldName} must be a valid email`);
|
|
4089
|
-
}
|
|
4090
|
-
break;
|
|
4091
|
-
case 'number':
|
|
4092
|
-
if (isNaN(value)) {
|
|
4093
|
-
errors.push(`${field.title || fieldName} must be a number`);
|
|
4094
|
-
}
|
|
4095
|
-
break;
|
|
4096
|
-
case 'date':
|
|
4097
|
-
if (isNaN(new Date(value).getTime())) {
|
|
4098
|
-
errors.push(`${field.title || fieldName} must be a valid date`);
|
|
4099
|
-
}
|
|
4100
|
-
break;
|
|
4101
|
-
}
|
|
4102
|
-
}
|
|
4103
|
-
});
|
|
4104
|
-
|
|
4105
|
-
return {
|
|
4106
|
-
isValid: errors.length === 0,
|
|
4107
|
-
errors
|
|
4108
|
-
};
|
|
4109
|
-
}
|
|
4110
|
-
|
|
4111
4177
|
// Advanced search functionality
|
|
4112
4178
|
enableSearch(options = {}) {
|
|
4113
4179
|
const searchOptions = {
|
|
@@ -4783,3 +4849,6 @@ table.load();
|
|
|
4783
4849
|
*/
|
|
4784
4850
|
|
|
4785
4851
|
window.FTable = FTable;
|
|
4852
|
+
|
|
4853
|
+
return FTable;
|
|
4854
|
+
})));
|