@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/CHANGES.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
= 1.1.3 (2025/08/03) =
|
|
2
|
+
* support fdatepicker
|
|
3
|
+
|
|
4
|
+
= 1.1.2 (2025/08/01) =
|
|
5
|
+
* support defaultDateLocale
|
|
6
|
+
|
|
7
|
+
= 1.1.1 (2025/08/01) =
|
|
8
|
+
* Correct build and include esm
|
|
9
|
+
|
|
1
10
|
= 1.1.0 (2025/08/01) =
|
|
2
11
|
* Make sure all missing options are added and doc wiki is more up to date
|
|
3
12
|
|
package/ftable.esm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
|
|
1
2
|
// Modern fTable - Vanilla JS Refactor
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
+
const FTABLE_DEFAULT_MESSAGES = {
|
|
4
5
|
serverCommunicationError: 'An error occurred while communicating to the server.',
|
|
5
6
|
loadingMessage: 'Loading records...',
|
|
6
7
|
noDataAvailable: 'No data available!',
|
|
@@ -903,6 +904,10 @@ class FTableFormBuilder {
|
|
|
903
904
|
case 'file':
|
|
904
905
|
input = this.createFileInput(fieldName, field, value);
|
|
905
906
|
break;
|
|
907
|
+
case 'date':
|
|
908
|
+
case 'datetime-local':
|
|
909
|
+
input = this.createDateInput(fieldName, field, value);
|
|
910
|
+
break;
|
|
906
911
|
default:
|
|
907
912
|
input = this.createTypedInput(fieldName, field, value);
|
|
908
913
|
}
|
|
@@ -947,14 +952,65 @@ class FTableFormBuilder {
|
|
|
947
952
|
return container;
|
|
948
953
|
}
|
|
949
954
|
|
|
955
|
+
createDateInput(fieldName, field, value) {
|
|
956
|
+
// Check if FDatepicker is available
|
|
957
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
958
|
+
const dateFormat = field.dateFormat || this.options.defaultDateFormat;
|
|
959
|
+
|
|
960
|
+
const container = document.createElement('div');
|
|
961
|
+
// Create hidden input
|
|
962
|
+
const hiddenInput = Object.assign(document.createElement('input'), {
|
|
963
|
+
id: 'real-' + fieldName,
|
|
964
|
+
type: 'hidden',
|
|
965
|
+
value: value || '',
|
|
966
|
+
name: fieldName
|
|
967
|
+
});
|
|
968
|
+
// Create visible input
|
|
969
|
+
const visibleInput = Object.assign(document.createElement('input'), {
|
|
970
|
+
className: field.inputClass || 'datepicker-input',
|
|
971
|
+
id: 'Edit-' + fieldName,
|
|
972
|
+
type: 'text',
|
|
973
|
+
'data-date': 'alt-' + fieldName,
|
|
974
|
+
value: value || '',
|
|
975
|
+
readOnly: true
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
if (value) {
|
|
979
|
+
hiddenInput.value = value;
|
|
980
|
+
visibleInput.dataset.date = value;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// Set any additional attributes
|
|
984
|
+
if (field.inputAttributes) {
|
|
985
|
+
Object.keys(field.inputAttributes).forEach(key => {
|
|
986
|
+
visibleInput.setAttribute(key, field.inputAttributes[key]);
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// Append both inputs
|
|
991
|
+
container.appendChild(hiddenInput);
|
|
992
|
+
container.appendChild(visibleInput);
|
|
993
|
+
|
|
994
|
+
// Apply FDatepicker
|
|
995
|
+
const picker = new FDatepicker(visibleInput, {
|
|
996
|
+
format: dateFormat,
|
|
997
|
+
altField: 'real-' + fieldName,
|
|
998
|
+
altFormat: 'Y-m-d'
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
return container;
|
|
1002
|
+
} else {
|
|
1003
|
+
return createTypedInput(fieldName, field, value);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
950
1007
|
createTypedInput(fieldName, field, value) {
|
|
951
1008
|
const inputType = field.type || 'text';
|
|
952
1009
|
const attributes = {
|
|
953
1010
|
type: inputType,
|
|
954
1011
|
id: `Edit-${fieldName}`,
|
|
955
1012
|
placeholder: field.placeholder || '',
|
|
956
|
-
value: value || ''
|
|
957
|
-
class: field.inputClass || ''
|
|
1013
|
+
value: value || ''
|
|
958
1014
|
};
|
|
959
1015
|
|
|
960
1016
|
// extra check for name and multiple
|
|
@@ -974,22 +1030,10 @@ class FTableFormBuilder {
|
|
|
974
1030
|
}
|
|
975
1031
|
attributes.name = name;
|
|
976
1032
|
|
|
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 });
|
|
1033
|
+
const input = FTableDOMHelper.create('input', {
|
|
1034
|
+
className: field.inputClass || '',
|
|
1035
|
+
attributes: attributes
|
|
1036
|
+
});
|
|
993
1037
|
|
|
994
1038
|
// Prevent form submit on Enter, trigger change instead
|
|
995
1039
|
input.addEventListener('keypress', (e) => {
|
|
@@ -1236,18 +1280,6 @@ class FTableFormBuilder {
|
|
|
1236
1280
|
return wrapper;
|
|
1237
1281
|
}
|
|
1238
1282
|
|
|
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
1283
|
populateSelectOptions(select, options, selectedValue) {
|
|
1252
1284
|
select.innerHTML = ''; // Clear existing options
|
|
1253
1285
|
|
|
@@ -1330,6 +1362,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1330
1362
|
}
|
|
1331
1363
|
|
|
1332
1364
|
this.options = this.mergeOptions(options);
|
|
1365
|
+
this.verifyOptions();
|
|
1333
1366
|
this.logger = new FTableLogger(this.options.logLevel);
|
|
1334
1367
|
this.userPrefs = new FTableUserPreferences('', this.options.saveUserPreferencesMethod);
|
|
1335
1368
|
this.formBuilder = new FTableFormBuilder(this.options, this);
|
|
@@ -1364,15 +1397,18 @@ class FTable extends FTableEventEmitter {
|
|
|
1364
1397
|
fields: {},
|
|
1365
1398
|
animationsEnabled: true,
|
|
1366
1399
|
loadingAnimationDelay: 1000,
|
|
1367
|
-
|
|
1400
|
+
defaultDateLocale: 'en',
|
|
1401
|
+
defaultDateFormat: 'm/d/Y',
|
|
1368
1402
|
saveUserPreferences: true,
|
|
1369
1403
|
saveUserPreferencesMethod: 'localStorage',
|
|
1370
1404
|
defaultSorting: '',
|
|
1405
|
+
tableReset: false,
|
|
1371
1406
|
|
|
1372
1407
|
// Paging
|
|
1373
1408
|
paging: false,
|
|
1374
1409
|
pageList: 'normal',
|
|
1375
1410
|
pageSize: 10,
|
|
1411
|
+
pageSizes: [10, 25, 50, 100],
|
|
1376
1412
|
gotoPageArea: 'combobox',
|
|
1377
1413
|
|
|
1378
1414
|
// Sorting
|
|
@@ -1396,7 +1432,7 @@ class FTable extends FTableEventEmitter {
|
|
|
1396
1432
|
listCache: 30000, // or listCache: 30000 (duration in ms)
|
|
1397
1433
|
|
|
1398
1434
|
// Messages
|
|
1399
|
-
messages: { ...
|
|
1435
|
+
messages: { ...FTABLE_DEFAULT_MESSAGES } // Safe copy
|
|
1400
1436
|
};
|
|
1401
1437
|
|
|
1402
1438
|
return this.deepMerge(defaults, options);
|
|
@@ -1416,9 +1452,15 @@ class FTable extends FTableEventEmitter {
|
|
|
1416
1452
|
return result;
|
|
1417
1453
|
}
|
|
1418
1454
|
|
|
1455
|
+
verifyOptions() {
|
|
1456
|
+
if (this.options.pageSize && !this.options.pageSizes.includes(this.options.pageSize)) {
|
|
1457
|
+
this.options.pageSize = this.options.pageSizes[0];
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1419
1461
|
// Public
|
|
1420
1462
|
static setMessages(customMessages) {
|
|
1421
|
-
Object.assign(
|
|
1463
|
+
Object.assign(FTABLE_DEFAULT_MESSAGES, customMessages);
|
|
1422
1464
|
}
|
|
1423
1465
|
|
|
1424
1466
|
init() {
|
|
@@ -1885,16 +1927,49 @@ class FTable extends FTableEventEmitter {
|
|
|
1885
1927
|
if (!field.type && field.options) {
|
|
1886
1928
|
field.type = 'select';
|
|
1887
1929
|
}
|
|
1930
|
+
const fieldSearchName = 'ftable-toolbarsearch-' + fieldName;
|
|
1888
1931
|
|
|
1889
1932
|
switch (field.type) {
|
|
1890
1933
|
case 'date':
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1934
|
+
case 'datetime-local':
|
|
1935
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
1936
|
+
const dateFormat = field.dateFormat || this.options.defaultDateFormat;
|
|
1937
|
+
input = document.createElement('div');
|
|
1938
|
+
// Create hidden input
|
|
1939
|
+
const hiddenInput = Object.assign(document.createElement('input'), {
|
|
1940
|
+
id: 'ftable-toolbarsearch-extra-' + fieldName,
|
|
1941
|
+
type: 'hidden',
|
|
1942
|
+
name: fieldName,
|
|
1943
|
+
className: 'ftable-toolbarsearch-extra'
|
|
1944
|
+
});
|
|
1945
|
+
// Create visible input
|
|
1946
|
+
const visibleInput = Object.assign(document.createElement('input'), {
|
|
1947
|
+
className: 'ftable-toolbarsearch',
|
|
1948
|
+
id: 'ftable-toolbarsearch-' + fieldName,
|
|
1949
|
+
type: 'text',
|
|
1950
|
+
readOnly: true
|
|
1951
|
+
});
|
|
1952
|
+
// Append both inputs
|
|
1953
|
+
input.appendChild(hiddenInput);
|
|
1954
|
+
input.appendChild(visibleInput);
|
|
1955
|
+
|
|
1956
|
+
// Apply FDatepicker
|
|
1957
|
+
const picker = new FDatepicker(visibleInput, {
|
|
1958
|
+
format: dateFormat,
|
|
1959
|
+
altField: 'ftable-toolbarsearch-extra-' + fieldName,
|
|
1960
|
+
altFormat: 'Y-m-d'
|
|
1961
|
+
});
|
|
1962
|
+
|
|
1963
|
+
} else {
|
|
1964
|
+
input = FTableDOMHelper.create('input', {
|
|
1965
|
+
className: 'ftable-toolbarsearch',
|
|
1966
|
+
attributes: {
|
|
1967
|
+
type: 'date',
|
|
1968
|
+
'data-field-name': fieldName,
|
|
1969
|
+
id: fieldSearchName,
|
|
1970
|
+
}
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1898
1973
|
break;
|
|
1899
1974
|
|
|
1900
1975
|
case 'checkbox':
|
|
@@ -1902,10 +1977,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1902
1977
|
input = await this.createSelectForSearch(fieldName, field, true);
|
|
1903
1978
|
} else {
|
|
1904
1979
|
input = FTableDOMHelper.create('input', {
|
|
1980
|
+
className: 'ftable-toolbarsearch',
|
|
1905
1981
|
attributes: {
|
|
1906
1982
|
type: 'text',
|
|
1907
1983
|
'data-field-name': fieldName,
|
|
1908
|
-
|
|
1984
|
+
id: fieldSearchName,
|
|
1909
1985
|
placeholder: 'Search...'
|
|
1910
1986
|
}
|
|
1911
1987
|
});
|
|
@@ -1917,10 +1993,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1917
1993
|
input = await this.createSelectForSearch(fieldName, field, false);
|
|
1918
1994
|
} else {
|
|
1919
1995
|
input = FTableDOMHelper.create('input', {
|
|
1996
|
+
className: 'ftable-toolbarsearch',
|
|
1920
1997
|
attributes: {
|
|
1921
1998
|
type: 'text',
|
|
1922
1999
|
'data-field-name': fieldName,
|
|
1923
|
-
|
|
2000
|
+
id: fieldSearchName,
|
|
1924
2001
|
placeholder: 'Search...'
|
|
1925
2002
|
}
|
|
1926
2003
|
});
|
|
@@ -1929,10 +2006,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1929
2006
|
|
|
1930
2007
|
default:
|
|
1931
2008
|
input = FTableDOMHelper.create('input', {
|
|
2009
|
+
className: 'ftable-toolbarsearch',
|
|
1932
2010
|
attributes: {
|
|
1933
2011
|
type: 'text',
|
|
1934
2012
|
'data-field-name': fieldName,
|
|
1935
|
-
|
|
2013
|
+
id: fieldSearchName,
|
|
1936
2014
|
placeholder: 'Search...'
|
|
1937
2015
|
}
|
|
1938
2016
|
});
|
|
@@ -1985,9 +2063,11 @@ class FTable extends FTableEventEmitter {
|
|
|
1985
2063
|
}
|
|
1986
2064
|
|
|
1987
2065
|
async createSelectForSearch(fieldName, field, isCheckboxValues) {
|
|
2066
|
+
const fieldSearchName = 'ftable-toolbarsearch-' + fieldName;
|
|
1988
2067
|
const select = FTableDOMHelper.create('select', {
|
|
1989
2068
|
attributes: {
|
|
1990
2069
|
'data-field-name': fieldName,
|
|
2070
|
+
id: fieldSearchName,
|
|
1991
2071
|
class: 'ftable-toolbarsearch'
|
|
1992
2072
|
}
|
|
1993
2073
|
});
|
|
@@ -2211,7 +2291,7 @@ class FTable extends FTableEventEmitter {
|
|
|
2211
2291
|
if (Array.isArray(state.sorting)) {
|
|
2212
2292
|
this.state.sorting = state.sorting;
|
|
2213
2293
|
}
|
|
2214
|
-
if (state.pageSize) {
|
|
2294
|
+
if (state.pageSize && this.options.pageSizes.includes(state.pageSize)) {
|
|
2215
2295
|
this.state.pageSize = state.pageSize;
|
|
2216
2296
|
}
|
|
2217
2297
|
} catch (error) {
|
|
@@ -2381,9 +2461,6 @@ class FTable extends FTableEventEmitter {
|
|
|
2381
2461
|
this.createToolbarButtons();
|
|
2382
2462
|
this.createCustomToolbarItems();
|
|
2383
2463
|
|
|
2384
|
-
// Handle window unload
|
|
2385
|
-
this.handlePageUnload();
|
|
2386
|
-
|
|
2387
2464
|
// Keyboard shortcuts
|
|
2388
2465
|
this.bindKeyboardEvents();
|
|
2389
2466
|
|
|
@@ -2670,20 +2747,6 @@ class FTable extends FTableEventEmitter {
|
|
|
2670
2747
|
});
|
|
2671
2748
|
}
|
|
2672
2749
|
|
|
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
2750
|
bindKeyboardEvents() {
|
|
2688
2751
|
if (this.options.selecting) {
|
|
2689
2752
|
this.shiftKeyDown = false;
|
|
@@ -3011,7 +3074,19 @@ class FTable extends FTableEventEmitter {
|
|
|
3011
3074
|
}
|
|
3012
3075
|
|
|
3013
3076
|
if (field.type === 'date' && value) {
|
|
3014
|
-
|
|
3077
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
3078
|
+
return FDatepicker.formatDate(this._parseDate(value), field.dateFormat || this.options.defaultDateFormat);
|
|
3079
|
+
} else {
|
|
3080
|
+
return this.formatDate(value, field.dateLocale || this.options.defaultDateLocale || 'en' );
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
if (field.type === 'datetime-local' && value) {
|
|
3085
|
+
if (typeof FDatepicker !== 'undefined') {
|
|
3086
|
+
return FDatepicker.formatDate(this._parseDate(value), field.dateFormat || this.options.defaultDateFormat);
|
|
3087
|
+
} else {
|
|
3088
|
+
return this.formatDateTime(value, field.dateLocale || this.options.defaultDateLocale || 'en' );
|
|
3089
|
+
}
|
|
3015
3090
|
}
|
|
3016
3091
|
|
|
3017
3092
|
if (field.type === 'checkbox') {
|
|
@@ -3026,18 +3101,53 @@ class FTable extends FTableEventEmitter {
|
|
|
3026
3101
|
return value || '';
|
|
3027
3102
|
}
|
|
3028
3103
|
|
|
3104
|
+
_parseDate(dateString) {
|
|
3105
|
+
if (dateString.includes('Date')) { // Format: /Date(1320259705710)/
|
|
3106
|
+
return new Date(
|
|
3107
|
+
parseInt(dateString.substr(6), 10)
|
|
3108
|
+
);
|
|
3109
|
+
} else if (dateString.length == 10) { // Format: 2011-01-01
|
|
3110
|
+
return new Date(
|
|
3111
|
+
parseInt(dateString.substr(0, 4), 10),
|
|
3112
|
+
parseInt(dateString.substr(5, 2), 10) - 1,
|
|
3113
|
+
parseInt(dateString.substr(8, 2), 10)
|
|
3114
|
+
);
|
|
3115
|
+
} else if (dateString.length == 19) { // Format: 2011-01-01 20:32:42
|
|
3116
|
+
return new Date(
|
|
3117
|
+
parseInt(dateString.substr(0, 4), 10),
|
|
3118
|
+
parseInt(dateString.substr(5, 2), 10) - 1,
|
|
3119
|
+
parseInt(dateString.substr(8, 2), 10),
|
|
3120
|
+
parseInt(dateString.substr(11, 2), 10),
|
|
3121
|
+
parseInt(dateString.substr(14, 2), 10),
|
|
3122
|
+
parseInt(dateString.substr(17, 2), 10)
|
|
3123
|
+
);
|
|
3124
|
+
} else {
|
|
3125
|
+
return new Date(dateString);
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
|
|
3029
3129
|
formatDate(dateValue, format) {
|
|
3030
3130
|
if (!dateValue) return '';
|
|
3031
|
-
|
|
3032
|
-
const date = new Date(dateValue);
|
|
3033
|
-
if (isNaN(date.getTime())) return dateValue;
|
|
3034
3131
|
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3132
|
+
const date = this._parseDate(dateValue);
|
|
3133
|
+
try {
|
|
3134
|
+
if (isNaN(date.getTime())) return dateValue;
|
|
3135
|
+
return date.toLocaleDateString(format,{ year: "numeric", month: "2-digit", day: "2-digit" });
|
|
3136
|
+
} catch {
|
|
3137
|
+
return dateValue;
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
formatDateTime(dateValue, format) {
|
|
3142
|
+
if (!dateValue) return '';
|
|
3143
|
+
|
|
3144
|
+
const date = this._parseDate(dateValue);
|
|
3145
|
+
try {
|
|
3146
|
+
if (isNaN(date.getTime())) return dateValue;
|
|
3147
|
+
return date.toLocaleString(format);
|
|
3148
|
+
} catch {
|
|
3149
|
+
return dateValue;
|
|
3150
|
+
}
|
|
3041
3151
|
}
|
|
3042
3152
|
|
|
3043
3153
|
getCheckboxText(fieldName, value) {
|
|
@@ -4059,55 +4169,6 @@ class FTable extends FTableEventEmitter {
|
|
|
4059
4169
|
});
|
|
4060
4170
|
}
|
|
4061
4171
|
|
|
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
4172
|
// Advanced search functionality
|
|
4112
4173
|
enableSearch(options = {}) {
|
|
4113
4174
|
const searchOptions = {
|
|
@@ -4783,3 +4844,5 @@ table.load();
|
|
|
4783
4844
|
*/
|
|
4784
4845
|
|
|
4785
4846
|
window.FTable = FTable;
|
|
4847
|
+
|
|
4848
|
+
export default FTable;
|