@syncfusion/ej2-form-renderer 34.2.2
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/README.md +60 -0
- package/common.d.ts +4 -0
- package/common.js +4 -0
- package/dist/ej2-form-renderer.umd.min.js +11 -0
- package/dist/ej2-form-renderer.umd.min.js.map +1 -0
- package/dist/es6/ej2-form-renderer.es2015.js +6787 -0
- package/dist/es6/ej2-form-renderer.es2015.js.map +1 -0
- package/dist/es6/ej2-form-renderer.es5.js +7055 -0
- package/dist/es6/ej2-form-renderer.es5.js.map +1 -0
- package/dist/global/ej2-form-renderer.min.js +11 -0
- package/dist/global/ej2-form-renderer.min.js.map +1 -0
- package/dist/global/index.d.ts +14 -0
- package/form-renderer.d.ts +4 -0
- package/form-renderer.js +4 -0
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/license +10 -0
- package/package.json +41 -0
- package/src/common/checkbox-group.d.ts +55 -0
- package/src/common/checkbox-group.js +241 -0
- package/src/common/conditional-rule-engine.d.ts +241 -0
- package/src/common/conditional-rule-engine.js +505 -0
- package/src/common/custom-validation-engine.d.ts +57 -0
- package/src/common/custom-validation-engine.js +152 -0
- package/src/common/datagrid-component.d.ts +156 -0
- package/src/common/datagrid-component.js +410 -0
- package/src/common/expressions/dependency-tracker.d.ts +29 -0
- package/src/common/expressions/dependency-tracker.js +137 -0
- package/src/common/expressions/expression-engine.d.ts +94 -0
- package/src/common/expressions/expression-engine.js +514 -0
- package/src/common/expressions/expression-parser.d.ts +40 -0
- package/src/common/expressions/expression-parser.js +270 -0
- package/src/common/expressions/grid-expressions.d.ts +24 -0
- package/src/common/expressions/grid-expressions.js +92 -0
- package/src/common/expressions/index.d.ts +4 -0
- package/src/common/expressions/index.js +4 -0
- package/src/common/index.d.ts +10 -0
- package/src/common/index.js +10 -0
- package/src/common/json-converter.d.ts +945 -0
- package/src/common/json-converter.js +1110 -0
- package/src/common/minmax-rule-engine.d.ts +105 -0
- package/src/common/minmax-rule-engine.js +380 -0
- package/src/common/option-fetcher.d.ts +30 -0
- package/src/common/option-fetcher.js +139 -0
- package/src/common/parser.d.ts +98 -0
- package/src/common/parser.js +788 -0
- package/src/common/static-html-renderer.d.ts +45 -0
- package/src/common/static-html-renderer.js +77 -0
- package/src/common/utils.d.ts +116 -0
- package/src/common/utils.js +484 -0
- package/src/form-renderer/form-renderer-model.d.ts +65 -0
- package/src/form-renderer/form-renderer.d.ts +425 -0
- package/src/form-renderer/form-renderer.js +2277 -0
- package/src/form-renderer/index.d.ts +6 -0
- package/src/form-renderer/index.js +5 -0
- package/src/form-renderer/render-form-field.d.ts +31 -0
- package/src/form-renderer/render-form-field.js +816 -0
- package/src/form-renderer/types/form-schema.d.ts +452 -0
- package/src/form-renderer/types/form-schema.js +32 -0
- package/src/global.js +1 -0
- package/src/index.d.ts +4 -0
- package/src/index.js +4 -0
- package/styles/bds-lite.css +599 -0
- package/styles/bds-lite.scss +2 -0
- package/styles/bds.css +599 -0
- package/styles/bds.scss +2 -0
- package/styles/bootstrap-dark-lite.css +608 -0
- package/styles/bootstrap-dark-lite.scss +2 -0
- package/styles/bootstrap-dark.css +608 -0
- package/styles/bootstrap-dark.scss +2 -0
- package/styles/bootstrap-lite.css +595 -0
- package/styles/bootstrap-lite.scss +2 -0
- package/styles/bootstrap.css +595 -0
- package/styles/bootstrap.scss +2 -0
- package/styles/bootstrap4-lite.css +595 -0
- package/styles/bootstrap4-lite.scss +2 -0
- package/styles/bootstrap4.css +595 -0
- package/styles/bootstrap4.scss +2 -0
- package/styles/bootstrap5-dark-lite.css +595 -0
- package/styles/bootstrap5-dark-lite.scss +2 -0
- package/styles/bootstrap5-dark.css +595 -0
- package/styles/bootstrap5-dark.scss +2 -0
- package/styles/bootstrap5-lite.css +595 -0
- package/styles/bootstrap5-lite.scss +2 -0
- package/styles/bootstrap5.3-lite.css +679 -0
- package/styles/bootstrap5.3-lite.scss +2 -0
- package/styles/bootstrap5.3.css +679 -0
- package/styles/bootstrap5.3.scss +2 -0
- package/styles/bootstrap5.css +595 -0
- package/styles/bootstrap5.scss +2 -0
- package/styles/fabric-dark-lite.css +608 -0
- package/styles/fabric-dark-lite.scss +2 -0
- package/styles/fabric-dark.css +608 -0
- package/styles/fabric-dark.scss +2 -0
- package/styles/fabric-lite.css +595 -0
- package/styles/fabric-lite.scss +2 -0
- package/styles/fabric.css +595 -0
- package/styles/fabric.scss +2 -0
- package/styles/fluent-dark-lite.css +595 -0
- package/styles/fluent-dark-lite.scss +2 -0
- package/styles/fluent-dark.css +595 -0
- package/styles/fluent-dark.scss +2 -0
- package/styles/fluent-lite.css +595 -0
- package/styles/fluent-lite.scss +2 -0
- package/styles/fluent.css +595 -0
- package/styles/fluent.scss +2 -0
- package/styles/fluent2-lite.css +681 -0
- package/styles/fluent2-lite.scss +2 -0
- package/styles/fluent2.css +681 -0
- package/styles/fluent2.scss +2 -0
- package/styles/form-renderer/_all.scss +2 -0
- package/styles/form-renderer/_bds-definition.scss +8 -0
- package/styles/form-renderer/_bootstrap-dark-definition.scss +8 -0
- package/styles/form-renderer/_bootstrap-definition.scss +8 -0
- package/styles/form-renderer/_bootstrap4-definition.scss +8 -0
- package/styles/form-renderer/_bootstrap5-dark-definition.scss +8 -0
- package/styles/form-renderer/_bootstrap5-definition.scss +8 -0
- package/styles/form-renderer/_bootstrap5.3-definition.scss +8 -0
- package/styles/form-renderer/_fabric-dark-definition.scss +8 -0
- package/styles/form-renderer/_fabric-definition.scss +8 -0
- package/styles/form-renderer/_fluent-dark-definition.scss +8 -0
- package/styles/form-renderer/_fluent-definition.scss +8 -0
- package/styles/form-renderer/_fluent2-definition.scss +8 -0
- package/styles/form-renderer/_highcontrast-definition.scss +8 -0
- package/styles/form-renderer/_highcontrast-light-definition.scss +8 -0
- package/styles/form-renderer/_layout.scss +480 -0
- package/styles/form-renderer/_material-dark-definition.scss +8 -0
- package/styles/form-renderer/_material-definition.scss +8 -0
- package/styles/form-renderer/_material3-dark-definition.scss +8 -0
- package/styles/form-renderer/_material3-definition.scss +8 -0
- package/styles/form-renderer/_mixin.scss +26 -0
- package/styles/form-renderer/_tailwind-dark-definition.scss +8 -0
- package/styles/form-renderer/_tailwind-definition.scss +8 -0
- package/styles/form-renderer/_tailwind3-definition.scss +8 -0
- package/styles/form-renderer/_theme.scss +69 -0
- package/styles/form-renderer/_variables.scss +2 -0
- package/styles/form-renderer/bds.css +599 -0
- package/styles/form-renderer/bds.scss +2 -0
- package/styles/form-renderer/bootstrap-dark.css +608 -0
- package/styles/form-renderer/bootstrap-dark.scss +2 -0
- package/styles/form-renderer/bootstrap.css +595 -0
- package/styles/form-renderer/bootstrap.scss +2 -0
- package/styles/form-renderer/bootstrap4.css +595 -0
- package/styles/form-renderer/bootstrap4.scss +2 -0
- package/styles/form-renderer/bootstrap5-dark.css +595 -0
- package/styles/form-renderer/bootstrap5-dark.scss +2 -0
- package/styles/form-renderer/bootstrap5.3.css +679 -0
- package/styles/form-renderer/bootstrap5.3.scss +2 -0
- package/styles/form-renderer/bootstrap5.css +595 -0
- package/styles/form-renderer/bootstrap5.scss +2 -0
- package/styles/form-renderer/fabric-dark.css +608 -0
- package/styles/form-renderer/fabric-dark.scss +2 -0
- package/styles/form-renderer/fabric.css +595 -0
- package/styles/form-renderer/fabric.scss +2 -0
- package/styles/form-renderer/fluent-dark.css +595 -0
- package/styles/form-renderer/fluent-dark.scss +2 -0
- package/styles/form-renderer/fluent.css +595 -0
- package/styles/form-renderer/fluent.scss +2 -0
- package/styles/form-renderer/fluent2.css +681 -0
- package/styles/form-renderer/fluent2.scss +2 -0
- package/styles/form-renderer/highcontrast-light.css +595 -0
- package/styles/form-renderer/highcontrast-light.scss +2 -0
- package/styles/form-renderer/highcontrast.css +608 -0
- package/styles/form-renderer/highcontrast.scss +2 -0
- package/styles/form-renderer/material-dark.css +608 -0
- package/styles/form-renderer/material-dark.scss +2 -0
- package/styles/form-renderer/material.css +595 -0
- package/styles/form-renderer/material.scss +2 -0
- package/styles/form-renderer/material3-dark.css +677 -0
- package/styles/form-renderer/material3-dark.scss +2 -0
- package/styles/form-renderer/material3.css +679 -0
- package/styles/form-renderer/material3.scss +2 -0
- package/styles/form-renderer/tailwind-dark.css +595 -0
- package/styles/form-renderer/tailwind-dark.scss +2 -0
- package/styles/form-renderer/tailwind.css +595 -0
- package/styles/form-renderer/tailwind.scss +2 -0
- package/styles/form-renderer/tailwind3.css +669 -0
- package/styles/form-renderer/tailwind3.scss +2 -0
- package/styles/highcontrast-light-lite.css +595 -0
- package/styles/highcontrast-light-lite.scss +2 -0
- package/styles/highcontrast-light.css +595 -0
- package/styles/highcontrast-light.scss +2 -0
- package/styles/highcontrast-lite.css +608 -0
- package/styles/highcontrast-lite.scss +2 -0
- package/styles/highcontrast.css +608 -0
- package/styles/highcontrast.scss +2 -0
- package/styles/material-dark-lite.css +608 -0
- package/styles/material-dark-lite.scss +2 -0
- package/styles/material-dark.css +608 -0
- package/styles/material-dark.scss +2 -0
- package/styles/material-lite.css +595 -0
- package/styles/material-lite.scss +2 -0
- package/styles/material.css +595 -0
- package/styles/material.scss +2 -0
- package/styles/material3-dark-lite.css +677 -0
- package/styles/material3-dark-lite.scss +2 -0
- package/styles/material3-dark.css +677 -0
- package/styles/material3-dark.scss +2 -0
- package/styles/material3-lite.css +679 -0
- package/styles/material3-lite.scss +2 -0
- package/styles/material3.css +679 -0
- package/styles/material3.scss +2 -0
- package/styles/tailwind-dark-lite.css +595 -0
- package/styles/tailwind-dark-lite.scss +2 -0
- package/styles/tailwind-dark.css +595 -0
- package/styles/tailwind-dark.scss +2 -0
- package/styles/tailwind-lite.css +595 -0
- package/styles/tailwind-lite.scss +2 -0
- package/styles/tailwind.css +595 -0
- package/styles/tailwind.scss +2 -0
- package/styles/tailwind3-lite.css +669 -0
- package/styles/tailwind3-lite.scss +2 -0
- package/styles/tailwind3.css +669 -0
- package/styles/tailwind3.scss +2 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @private
|
|
3
|
+
*/
|
|
4
|
+
export interface MinMaxRangeItem {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
minValue?: number | string | {
|
|
7
|
+
field: string;
|
|
8
|
+
};
|
|
9
|
+
maxValue?: number | string | {
|
|
10
|
+
field: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
export interface MinMaxConstraints {
|
|
17
|
+
minValue?: number | string;
|
|
18
|
+
maxValue?: number | string;
|
|
19
|
+
minDate?: string;
|
|
20
|
+
maxDate?: string;
|
|
21
|
+
minTime?: string;
|
|
22
|
+
maxTime?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Extract min/max constraints from minMaxRange array
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
export declare class MinMaxRuleEngine {
|
|
29
|
+
/**
|
|
30
|
+
* Extract min/max constraints from minMaxRange array
|
|
31
|
+
* Handles three cases:
|
|
32
|
+
* 1. Direct values (enabled: false)
|
|
33
|
+
* 2. Single field reference (enabled: true, 1 range)
|
|
34
|
+
* 3. Multiple ranges (enabled: true, 2+ ranges) - takes UTMOST
|
|
35
|
+
* @private
|
|
36
|
+
* @param minMaxRange - Array of range configurations
|
|
37
|
+
* @param formValues - Current form state values (id → value)
|
|
38
|
+
* @param componentType - 'number' | 'date' | 'dateRange'
|
|
39
|
+
* @returns Constraints object with appropriate keys
|
|
40
|
+
*/
|
|
41
|
+
static getConstraints(minMaxRange: MinMaxRangeItem[] | undefined, formValues: Record<string, any>, componentType?: string): MinMaxConstraints;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a single value - either direct or field reference
|
|
44
|
+
*
|
|
45
|
+
* @param value - Direct value or field reference object
|
|
46
|
+
* @param formValues - Form state values for field lookup
|
|
47
|
+
* @returns Resolved value or undefined
|
|
48
|
+
*/
|
|
49
|
+
private static resolveValue;
|
|
50
|
+
/**
|
|
51
|
+
* Get the most permissive (widest) minimum value
|
|
52
|
+
* For numbers: MIN of all mins
|
|
53
|
+
* For dates: earliest date (MIN string comparison on ISO format)
|
|
54
|
+
* For times: earliest time (MIN string comparison on 24-hour format)
|
|
55
|
+
*
|
|
56
|
+
* @param ranges - Array of {min, max} values
|
|
57
|
+
* @param componentType - Type of component
|
|
58
|
+
* @returns Most permissive minimum value
|
|
59
|
+
*/
|
|
60
|
+
private static getPermissiveMin;
|
|
61
|
+
/**
|
|
62
|
+
* Get the most permissive (widest) maximum value
|
|
63
|
+
* For numbers: MAX of all maxs
|
|
64
|
+
* For dates: latest date (MAX string comparison on ISO format)
|
|
65
|
+
* For times: latest time (MAX string comparison on 24-hour format)
|
|
66
|
+
*
|
|
67
|
+
* @param ranges - Array of {min, max} values
|
|
68
|
+
* @param componentType - Type of component
|
|
69
|
+
* @returns Most permissive maximum value
|
|
70
|
+
*/
|
|
71
|
+
private static getPermissiveMax;
|
|
72
|
+
/**
|
|
73
|
+
* Convert MM/DD/YYYY date format to ISO (YYYY-MM-DD) for comparison
|
|
74
|
+
* Handles both formats gracefully
|
|
75
|
+
*
|
|
76
|
+
* @param dateString - Date in MM/DD/YYYY or ISO format
|
|
77
|
+
* @returns ISO date string (YYYY-MM-DD)
|
|
78
|
+
*/
|
|
79
|
+
private static convertToISO;
|
|
80
|
+
/**
|
|
81
|
+
* Convert 12-hour time format to 24-hour format for comparison
|
|
82
|
+
* Handles both 12-hour (hh:mm a) and 24-hour (HH:mm) formats
|
|
83
|
+
*
|
|
84
|
+
* @param timeString - Time in 12-hour (hh:mm a/p) or 24-hour (HH:mm) format
|
|
85
|
+
* @returns 24-hour format time string (HH:mm)
|
|
86
|
+
*/
|
|
87
|
+
private static convertTimeTo24Hour;
|
|
88
|
+
/**
|
|
89
|
+
* Get empty constraints object based on component type
|
|
90
|
+
*/
|
|
91
|
+
private static getEmptyConstraints;
|
|
92
|
+
/**
|
|
93
|
+
* Validate if a value passes all min/max constraints (optional)
|
|
94
|
+
* Can be used for client-side validation before submission
|
|
95
|
+
*
|
|
96
|
+
* @param value - Value to validate
|
|
97
|
+
* @param constraints - Constraints to check against
|
|
98
|
+
* @param componentType - Type of component
|
|
99
|
+
* @returns Validation result with error message if invalid
|
|
100
|
+
*/
|
|
101
|
+
static validateValue(value: any, constraints: MinMaxConstraints, componentType: string): {
|
|
102
|
+
isValid: boolean;
|
|
103
|
+
error?: string;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract min/max constraints from minMaxRange array
|
|
3
|
+
* @private
|
|
4
|
+
*/
|
|
5
|
+
var MinMaxRuleEngine = /** @class */ (function () {
|
|
6
|
+
function MinMaxRuleEngine() {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Extract min/max constraints from minMaxRange array
|
|
10
|
+
* Handles three cases:
|
|
11
|
+
* 1. Direct values (enabled: false)
|
|
12
|
+
* 2. Single field reference (enabled: true, 1 range)
|
|
13
|
+
* 3. Multiple ranges (enabled: true, 2+ ranges) - takes UTMOST
|
|
14
|
+
* @private
|
|
15
|
+
* @param minMaxRange - Array of range configurations
|
|
16
|
+
* @param formValues - Current form state values (id → value)
|
|
17
|
+
* @param componentType - 'number' | 'date' | 'dateRange'
|
|
18
|
+
* @returns Constraints object with appropriate keys
|
|
19
|
+
*/
|
|
20
|
+
MinMaxRuleEngine.getConstraints = function (minMaxRange, formValues, componentType) {
|
|
21
|
+
var _this = this;
|
|
22
|
+
if (componentType === void 0) { componentType = 'number'; }
|
|
23
|
+
// No ranges provided
|
|
24
|
+
if (!minMaxRange || minMaxRange.length === 0) {
|
|
25
|
+
return this.getEmptyConstraints(componentType);
|
|
26
|
+
}
|
|
27
|
+
// First, check for CASE 1: Direct values (enabled: false)
|
|
28
|
+
var directValueRange = minMaxRange.find(function (range) { return range.enabled === false; });
|
|
29
|
+
if (directValueRange) {
|
|
30
|
+
// Use direct values without field lookup
|
|
31
|
+
var minValue = this.resolveValue(directValueRange.minValue, {});
|
|
32
|
+
var maxValue = this.resolveValue(directValueRange.maxValue, {});
|
|
33
|
+
if (componentType === 'date' || componentType === 'dateRange') {
|
|
34
|
+
return {
|
|
35
|
+
minValue: undefined,
|
|
36
|
+
maxValue: undefined,
|
|
37
|
+
minDate: minValue,
|
|
38
|
+
maxDate: maxValue,
|
|
39
|
+
minTime: undefined,
|
|
40
|
+
maxTime: undefined
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (componentType === 'time') {
|
|
44
|
+
return {
|
|
45
|
+
minValue: undefined,
|
|
46
|
+
maxValue: undefined,
|
|
47
|
+
minDate: undefined,
|
|
48
|
+
maxDate: undefined,
|
|
49
|
+
minTime: minValue,
|
|
50
|
+
maxTime: maxValue
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
minValue: minValue,
|
|
55
|
+
maxValue: maxValue,
|
|
56
|
+
minDate: undefined,
|
|
57
|
+
maxDate: undefined,
|
|
58
|
+
minTime: undefined,
|
|
59
|
+
maxTime: undefined
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// CASE 2 & 3: Field references (enabled: true)
|
|
63
|
+
var enabledRanges = minMaxRange.filter(function (range) { return range.enabled === true; });
|
|
64
|
+
// No enabled ranges - return empty
|
|
65
|
+
if (enabledRanges.length === 0) {
|
|
66
|
+
return this.getEmptyConstraints(componentType);
|
|
67
|
+
}
|
|
68
|
+
// Extract resolved values from each enabled range
|
|
69
|
+
var resolvedRanges = enabledRanges
|
|
70
|
+
.map(function (range) { return ({
|
|
71
|
+
min: _this.resolveValue(range.minValue, formValues),
|
|
72
|
+
max: _this.resolveValue(range.maxValue, formValues)
|
|
73
|
+
}); })
|
|
74
|
+
.filter(function (range) { return range.min !== undefined || range.max !== undefined; });
|
|
75
|
+
// No valid ranges
|
|
76
|
+
if (resolvedRanges.length === 0) {
|
|
77
|
+
return this.getEmptyConstraints(componentType);
|
|
78
|
+
}
|
|
79
|
+
// Combine multiple ranges using UTMOST (most permissive)
|
|
80
|
+
var finalMin = this.getPermissiveMin(resolvedRanges, componentType);
|
|
81
|
+
var finalMax = this.getPermissiveMax(resolvedRanges, componentType);
|
|
82
|
+
// Return appropriate keys based on component type
|
|
83
|
+
if (componentType === 'date' || componentType === 'dateRange') {
|
|
84
|
+
return {
|
|
85
|
+
minValue: undefined,
|
|
86
|
+
maxValue: undefined,
|
|
87
|
+
minDate: finalMin,
|
|
88
|
+
maxDate: finalMax,
|
|
89
|
+
minTime: undefined,
|
|
90
|
+
maxTime: undefined
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (componentType === 'time') {
|
|
94
|
+
return {
|
|
95
|
+
minValue: undefined,
|
|
96
|
+
maxValue: undefined,
|
|
97
|
+
minDate: undefined,
|
|
98
|
+
maxDate: undefined,
|
|
99
|
+
minTime: finalMin,
|
|
100
|
+
maxTime: finalMax
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
minValue: finalMin,
|
|
105
|
+
maxValue: finalMax,
|
|
106
|
+
minDate: undefined,
|
|
107
|
+
maxDate: undefined,
|
|
108
|
+
minTime: undefined,
|
|
109
|
+
maxTime: undefined
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Resolve a single value - either direct or field reference
|
|
114
|
+
*
|
|
115
|
+
* @param value - Direct value or field reference object
|
|
116
|
+
* @param formValues - Form state values for field lookup
|
|
117
|
+
* @returns Resolved value or undefined
|
|
118
|
+
*/
|
|
119
|
+
MinMaxRuleEngine.resolveValue = function (value, formValues) {
|
|
120
|
+
// Direct value (number or string)
|
|
121
|
+
if (typeof value === 'number') {
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
if (typeof value === 'string') {
|
|
125
|
+
return value;
|
|
126
|
+
}
|
|
127
|
+
// Field reference object
|
|
128
|
+
if (value && typeof value === 'object' && value.field) {
|
|
129
|
+
var fieldId = value.field;
|
|
130
|
+
var fieldValue = formValues[fieldId];
|
|
131
|
+
return fieldValue !== undefined ? fieldValue : undefined;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Get the most permissive (widest) minimum value
|
|
137
|
+
* For numbers: MIN of all mins
|
|
138
|
+
* For dates: earliest date (MIN string comparison on ISO format)
|
|
139
|
+
* For times: earliest time (MIN string comparison on 24-hour format)
|
|
140
|
+
*
|
|
141
|
+
* @param ranges - Array of {min, max} values
|
|
142
|
+
* @param componentType - Type of component
|
|
143
|
+
* @returns Most permissive minimum value
|
|
144
|
+
*/
|
|
145
|
+
MinMaxRuleEngine.getPermissiveMin = function (ranges, componentType) {
|
|
146
|
+
var _this = this;
|
|
147
|
+
if (ranges.length === 0)
|
|
148
|
+
return undefined;
|
|
149
|
+
if (componentType === 'date' || componentType === 'dateRange') {
|
|
150
|
+
// For dates, find earliest (minimum) date
|
|
151
|
+
return ranges.reduce(function (earliest, current) {
|
|
152
|
+
if (!current.min)
|
|
153
|
+
return earliest;
|
|
154
|
+
if (!earliest)
|
|
155
|
+
return current.min;
|
|
156
|
+
var earliestIso = _this.convertToISO(earliest);
|
|
157
|
+
var currentIso = _this.convertToISO(current.min);
|
|
158
|
+
return currentIso < earliestIso ? current.min : earliest;
|
|
159
|
+
}, undefined);
|
|
160
|
+
}
|
|
161
|
+
if (componentType === 'time') {
|
|
162
|
+
// For times, find earliest (minimum) time
|
|
163
|
+
return ranges.reduce(function (earliest, current) {
|
|
164
|
+
if (!current.min)
|
|
165
|
+
return earliest;
|
|
166
|
+
if (!earliest)
|
|
167
|
+
return current.min;
|
|
168
|
+
var earliest24 = _this.convertTimeTo24Hour(earliest);
|
|
169
|
+
var current24 = _this.convertTimeTo24Hour(current.min);
|
|
170
|
+
return current24 < earliest24 ? current.min : earliest;
|
|
171
|
+
}, undefined);
|
|
172
|
+
}
|
|
173
|
+
// For numbers, find minimum (skip undefined values)
|
|
174
|
+
var minValues = ranges.map(function (r) { return r.min; }).filter(function (v) { return v !== undefined; });
|
|
175
|
+
return minValues.length > 0 ? Math.min.apply(Math, minValues) : undefined;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Get the most permissive (widest) maximum value
|
|
179
|
+
* For numbers: MAX of all maxs
|
|
180
|
+
* For dates: latest date (MAX string comparison on ISO format)
|
|
181
|
+
* For times: latest time (MAX string comparison on 24-hour format)
|
|
182
|
+
*
|
|
183
|
+
* @param ranges - Array of {min, max} values
|
|
184
|
+
* @param componentType - Type of component
|
|
185
|
+
* @returns Most permissive maximum value
|
|
186
|
+
*/
|
|
187
|
+
MinMaxRuleEngine.getPermissiveMax = function (ranges, componentType) {
|
|
188
|
+
var _this = this;
|
|
189
|
+
if (ranges.length === 0)
|
|
190
|
+
return undefined;
|
|
191
|
+
if (componentType === 'date' || componentType === 'dateRange') {
|
|
192
|
+
// For dates, find latest (maximum) date
|
|
193
|
+
return ranges.reduce(function (latest, current) {
|
|
194
|
+
if (!current.max)
|
|
195
|
+
return latest;
|
|
196
|
+
if (!latest)
|
|
197
|
+
return current.max;
|
|
198
|
+
var latestIso = _this.convertToISO(latest);
|
|
199
|
+
var currentIso = _this.convertToISO(current.max);
|
|
200
|
+
return currentIso > latestIso ? current.max : latest;
|
|
201
|
+
}, undefined);
|
|
202
|
+
}
|
|
203
|
+
if (componentType === 'time') {
|
|
204
|
+
// For times, find latest (maximum) time
|
|
205
|
+
return ranges.reduce(function (latest, current) {
|
|
206
|
+
if (!current.max)
|
|
207
|
+
return latest;
|
|
208
|
+
if (!latest)
|
|
209
|
+
return current.max;
|
|
210
|
+
var latest24 = _this.convertTimeTo24Hour(latest);
|
|
211
|
+
var current24 = _this.convertTimeTo24Hour(current.max);
|
|
212
|
+
return current24 > latest24 ? current.max : latest;
|
|
213
|
+
}, undefined);
|
|
214
|
+
}
|
|
215
|
+
// For numbers, find maximum (skip undefined values)
|
|
216
|
+
var maxValues = ranges.map(function (r) { return r.max; }).filter(function (v) { return v !== undefined; });
|
|
217
|
+
return maxValues.length > 0 ? Math.max.apply(Math, maxValues) : undefined;
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Convert MM/DD/YYYY date format to ISO (YYYY-MM-DD) for comparison
|
|
221
|
+
* Handles both formats gracefully
|
|
222
|
+
*
|
|
223
|
+
* @param dateString - Date in MM/DD/YYYY or ISO format
|
|
224
|
+
* @returns ISO date string (YYYY-MM-DD)
|
|
225
|
+
*/
|
|
226
|
+
MinMaxRuleEngine.convertToISO = function (dateString) {
|
|
227
|
+
if (!dateString)
|
|
228
|
+
return '';
|
|
229
|
+
// Already ISO format (YYYY-MM-DD)
|
|
230
|
+
if (dateString.includes('-') && dateString.length === 10) {
|
|
231
|
+
return dateString;
|
|
232
|
+
}
|
|
233
|
+
// MM/DD/YYYY format
|
|
234
|
+
if (dateString.indexOf('/') !== -1) {
|
|
235
|
+
var parts = dateString.split('/');
|
|
236
|
+
var month = parts[0];
|
|
237
|
+
var day = parts[1];
|
|
238
|
+
var year = parts[2];
|
|
239
|
+
if (!month || !day || !year)
|
|
240
|
+
return dateString;
|
|
241
|
+
var monthPadded = month.length < 2 ? '0' + month : month;
|
|
242
|
+
var dayPadded = day.length < 2 ? '0' + day : day;
|
|
243
|
+
return year + "-" + monthPadded + "-" + dayPadded;
|
|
244
|
+
}
|
|
245
|
+
return dateString;
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* Convert 12-hour time format to 24-hour format for comparison
|
|
249
|
+
* Handles both 12-hour (hh:mm a) and 24-hour (HH:mm) formats
|
|
250
|
+
*
|
|
251
|
+
* @param timeString - Time in 12-hour (hh:mm a/p) or 24-hour (HH:mm) format
|
|
252
|
+
* @returns 24-hour format time string (HH:mm)
|
|
253
|
+
*/
|
|
254
|
+
MinMaxRuleEngine.convertTimeTo24Hour = function (timeString) {
|
|
255
|
+
if (!timeString)
|
|
256
|
+
return '';
|
|
257
|
+
// Check if it contains AM/PM (12-hour format)
|
|
258
|
+
var isPM = /PM/i.test(timeString);
|
|
259
|
+
var isAM = /AM/i.test(timeString);
|
|
260
|
+
if (isAM || isPM) {
|
|
261
|
+
// Extract time part (before AM/PM)
|
|
262
|
+
var timePart = timeString.replace(/\s*(AM|PM)/i, '').trim();
|
|
263
|
+
var _a = timePart.split(':'), hours = _a[0], minutes = _a[1];
|
|
264
|
+
if (!hours || !minutes)
|
|
265
|
+
return timeString;
|
|
266
|
+
var hour = parseInt(hours, 10);
|
|
267
|
+
if (isPM && hour !== 12) {
|
|
268
|
+
hour += 12; // Convert PM hours (except 12) to 24-hour
|
|
269
|
+
}
|
|
270
|
+
else if (isAM && hour === 12) {
|
|
271
|
+
hour = 0; // Convert 12 AM to 00:00
|
|
272
|
+
}
|
|
273
|
+
var hourStr = String(hour);
|
|
274
|
+
var hourPadded = hourStr.length < 2 ? '0' + hourStr : hourStr;
|
|
275
|
+
return hourPadded + ":" + minutes;
|
|
276
|
+
}
|
|
277
|
+
// Already in 24-hour format or unknown format
|
|
278
|
+
return timeString;
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* Get empty constraints object based on component type
|
|
282
|
+
*/
|
|
283
|
+
MinMaxRuleEngine.getEmptyConstraints = function (componentType) {
|
|
284
|
+
if (componentType === 'date' || componentType === 'dateRange') {
|
|
285
|
+
return {
|
|
286
|
+
minValue: undefined,
|
|
287
|
+
maxValue: undefined,
|
|
288
|
+
minDate: undefined,
|
|
289
|
+
maxDate: undefined,
|
|
290
|
+
minTime: undefined,
|
|
291
|
+
maxTime: undefined
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
if (componentType === 'time') {
|
|
295
|
+
return {
|
|
296
|
+
minValue: undefined,
|
|
297
|
+
maxValue: undefined,
|
|
298
|
+
minDate: undefined,
|
|
299
|
+
maxDate: undefined,
|
|
300
|
+
minTime: undefined,
|
|
301
|
+
maxTime: undefined
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
minValue: undefined,
|
|
306
|
+
maxValue: undefined,
|
|
307
|
+
minDate: undefined,
|
|
308
|
+
maxDate: undefined,
|
|
309
|
+
minTime: undefined,
|
|
310
|
+
maxTime: undefined
|
|
311
|
+
};
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Validate if a value passes all min/max constraints (optional)
|
|
315
|
+
* Can be used for client-side validation before submission
|
|
316
|
+
*
|
|
317
|
+
* @param value - Value to validate
|
|
318
|
+
* @param constraints - Constraints to check against
|
|
319
|
+
* @param componentType - Type of component
|
|
320
|
+
* @returns Validation result with error message if invalid
|
|
321
|
+
*/
|
|
322
|
+
MinMaxRuleEngine.validateValue = function (value, constraints, componentType) {
|
|
323
|
+
if (value === undefined || value === null || value === '') {
|
|
324
|
+
return { isValid: true }; // Empty values pass (required handled separately)
|
|
325
|
+
}
|
|
326
|
+
if (componentType === 'date' || componentType === 'dateRange') {
|
|
327
|
+
if (constraints.minDate) {
|
|
328
|
+
var minIso = this.convertToISO(constraints.minDate);
|
|
329
|
+
var valueIso = this.convertToISO(value);
|
|
330
|
+
if (valueIso < minIso) {
|
|
331
|
+
return { isValid: false, error: "Date must be on or after " + constraints.minDate };
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (constraints.maxDate) {
|
|
335
|
+
var maxIso = this.convertToISO(constraints.maxDate);
|
|
336
|
+
var valueIso = this.convertToISO(value);
|
|
337
|
+
if (valueIso > maxIso) {
|
|
338
|
+
return { isValid: false, error: "Date must be on or before " + constraints.maxDate };
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
else if (componentType === 'time') {
|
|
343
|
+
if (constraints.minTime) {
|
|
344
|
+
if (value < constraints.minTime) {
|
|
345
|
+
return { isValid: false, error: "Time must be on or after " + constraints.minTime };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (constraints.maxTime) {
|
|
349
|
+
if (value > constraints.maxTime) {
|
|
350
|
+
return { isValid: false, error: "Time must be on or before " + constraints.maxTime };
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
// Number type
|
|
356
|
+
var numValue = Number(value);
|
|
357
|
+
if (constraints.minValue !== undefined) {
|
|
358
|
+
var minNum = Number(constraints.minValue);
|
|
359
|
+
if (numValue < minNum) {
|
|
360
|
+
return {
|
|
361
|
+
isValid: false,
|
|
362
|
+
error: "Value must be at least " + constraints.minValue
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (constraints.maxValue !== undefined) {
|
|
367
|
+
var maxNum = Number(constraints.maxValue);
|
|
368
|
+
if (numValue > maxNum) {
|
|
369
|
+
return {
|
|
370
|
+
isValid: false,
|
|
371
|
+
error: "Value must be at most " + constraints.maxValue
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return { isValid: true };
|
|
377
|
+
};
|
|
378
|
+
return MinMaxRuleEngine;
|
|
379
|
+
}());
|
|
380
|
+
export { MinMaxRuleEngine };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FormNode } from '../form-renderer/types/form-schema';
|
|
2
|
+
/**
|
|
3
|
+
* @private
|
|
4
|
+
*/
|
|
5
|
+
export declare class OptionFetcher {
|
|
6
|
+
/**
|
|
7
|
+
* Fetch option data via `DataManager` + `Query`, supporting
|
|
8
|
+
* search/sort/filter/paging/queryParams, with `resolveFieldBinding`
|
|
9
|
+
* used to resolve `{field}` references in search keys and filter
|
|
10
|
+
* values, and `extractDataFromPath` used to project the result.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors `useFetchOptions` (utils.tsx lines 359–471).
|
|
13
|
+
*
|
|
14
|
+
* @param componentOptions - Options config (array fallback handled by
|
|
15
|
+
* caller; this method only handles `type==='url'` objects).
|
|
16
|
+
* @param componentId - Id of the requesting component (for stale
|
|
17
|
+
* avoidance by the caller). Not used internally beyond tagging.
|
|
18
|
+
* @param formValues - Current form values (id-keyed) used to resolve
|
|
19
|
+
* `{field}` references when `components` is provided.
|
|
20
|
+
* @param components - Schema components used to map name-keyed context
|
|
21
|
+
* from id-keyed `formValues`.
|
|
22
|
+
* @returns Promise resolving to the option array (or empty array on
|
|
23
|
+
* error / non-url config). Never rejects — errors are caught and return `[]`.
|
|
24
|
+
*/
|
|
25
|
+
static fetch(componentOptions: any, componentId: string, formValues?: Record<string, any>, components?: FormNode[]): Promise<{
|
|
26
|
+
id: string;
|
|
27
|
+
options: string[];
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
export default OptionFetcher;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { DataManager, Query } from '@syncfusion/ej2-data';
|
|
2
|
+
import { resolveFieldBinding, getAdaptorInstance, extractDataFromPath } from './utils';
|
|
3
|
+
/**
|
|
4
|
+
* @private
|
|
5
|
+
*/
|
|
6
|
+
var OptionFetcher = /** @class */ (function () {
|
|
7
|
+
function OptionFetcher() {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Fetch option data via `DataManager` + `Query`, supporting
|
|
11
|
+
* search/sort/filter/paging/queryParams, with `resolveFieldBinding`
|
|
12
|
+
* used to resolve `{field}` references in search keys and filter
|
|
13
|
+
* values, and `extractDataFromPath` used to project the result.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors `useFetchOptions` (utils.tsx lines 359–471).
|
|
16
|
+
*
|
|
17
|
+
* @param componentOptions - Options config (array fallback handled by
|
|
18
|
+
* caller; this method only handles `type==='url'` objects).
|
|
19
|
+
* @param componentId - Id of the requesting component (for stale
|
|
20
|
+
* avoidance by the caller). Not used internally beyond tagging.
|
|
21
|
+
* @param formValues - Current form values (id-keyed) used to resolve
|
|
22
|
+
* `{field}` references when `components` is provided.
|
|
23
|
+
* @param components - Schema components used to map name-keyed context
|
|
24
|
+
* from id-keyed `formValues`.
|
|
25
|
+
* @returns Promise resolving to the option array (or empty array on
|
|
26
|
+
* error / non-url config). Never rejects — errors are caught and return `[]`.
|
|
27
|
+
*/
|
|
28
|
+
OptionFetcher.fetch = function (componentOptions, componentId, formValues, components) {
|
|
29
|
+
var isUrlType = componentOptions &&
|
|
30
|
+
typeof componentOptions === 'object' &&
|
|
31
|
+
!Array.isArray(componentOptions) &&
|
|
32
|
+
componentOptions.type === 'url' &&
|
|
33
|
+
componentOptions.url;
|
|
34
|
+
if (!isUrlType) {
|
|
35
|
+
return Promise.resolve({ id: componentId, options: [] });
|
|
36
|
+
}
|
|
37
|
+
var urlConfig = componentOptions;
|
|
38
|
+
return new Promise(function (resolve) {
|
|
39
|
+
try {
|
|
40
|
+
var headers_1 = {};
|
|
41
|
+
if (urlConfig.headers && Array.isArray(urlConfig.headers)) {
|
|
42
|
+
urlConfig.headers.forEach(function (h) {
|
|
43
|
+
if (h.key && h.key.trim()) {
|
|
44
|
+
headers_1[h.key] = h.value;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Create DataManager with selected adaptor
|
|
49
|
+
var dataManager = new DataManager({
|
|
50
|
+
url: urlConfig.url,
|
|
51
|
+
adaptor: getAdaptorInstance(urlConfig.adaptorType),
|
|
52
|
+
headers: Object.keys(headers_1).length ? headers_1 : undefined
|
|
53
|
+
});
|
|
54
|
+
// Build Query (dynamic support)
|
|
55
|
+
var query_1 = new Query();
|
|
56
|
+
if (urlConfig.search && urlConfig.search.enabled && urlConfig.search.fields && urlConfig.search.fields.length > 0) {
|
|
57
|
+
var searchKey = urlConfig.search.key || 'search';
|
|
58
|
+
// Resolve field bindings in search value
|
|
59
|
+
var resolvedSearchValue = formValues
|
|
60
|
+
? resolveFieldBinding(searchKey, formValues, components)
|
|
61
|
+
: /[{}]/.test(searchKey) ? '' : searchKey;
|
|
62
|
+
query_1 = query_1.search(resolvedSearchValue, urlConfig.search.fields);
|
|
63
|
+
}
|
|
64
|
+
// Apply sort query
|
|
65
|
+
if (urlConfig.sort && urlConfig.sort.enabled && urlConfig.sort.field) {
|
|
66
|
+
var sortDirection = urlConfig.sort.direction === 'descending' ? 'descending' : 'ascending';
|
|
67
|
+
query_1 = query_1.sortBy(urlConfig.sort.field, sortDirection);
|
|
68
|
+
}
|
|
69
|
+
// Apply filter queries with field binding resolution
|
|
70
|
+
if (urlConfig.filters && Array.isArray(urlConfig.filters) && urlConfig.filters.length > 0) {
|
|
71
|
+
urlConfig.filters.forEach(function (f) {
|
|
72
|
+
if (f.field && f.operator && f.value !== undefined && f.value !== '') {
|
|
73
|
+
var resolvedFilterValue = formValues
|
|
74
|
+
? resolveFieldBinding(f.value, formValues, components)
|
|
75
|
+
: /[{}]/.test(f.value) ? '' : f.value;
|
|
76
|
+
if (resolvedFilterValue !== '') {
|
|
77
|
+
query_1 = query_1.where(f.field, f.operator, resolvedFilterValue);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// Add params (query string)
|
|
83
|
+
if (urlConfig.queryParams) {
|
|
84
|
+
Object.keys(urlConfig.queryParams).forEach(function (key) {
|
|
85
|
+
query_1 = query_1.addParams(key, urlConfig.queryParams[key]);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Paging
|
|
89
|
+
if (urlConfig.skip) {
|
|
90
|
+
query_1 = query_1.skip(urlConfig.skip);
|
|
91
|
+
}
|
|
92
|
+
if (urlConfig.take) {
|
|
93
|
+
query_1 = query_1.take(urlConfig.take);
|
|
94
|
+
}
|
|
95
|
+
var timeoutMs = 15000;
|
|
96
|
+
var timedOut_1 = false;
|
|
97
|
+
var timeoutHandle_1 = setTimeout(function () {
|
|
98
|
+
timedOut_1 = true;
|
|
99
|
+
resolve({ id: componentId, options: [] });
|
|
100
|
+
}, timeoutMs);
|
|
101
|
+
dataManager.executeQuery(query_1).then(function (res) {
|
|
102
|
+
if (timedOut_1) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
clearTimeout(timeoutHandle_1);
|
|
106
|
+
var data = res.result;
|
|
107
|
+
if (urlConfig.dataPath) {
|
|
108
|
+
data = extractDataFromPath(data, urlConfig.dataPath);
|
|
109
|
+
}
|
|
110
|
+
var options;
|
|
111
|
+
if (Array.isArray(data)) {
|
|
112
|
+
options = data;
|
|
113
|
+
}
|
|
114
|
+
else if (typeof data === 'string') {
|
|
115
|
+
options = [data];
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
options = [];
|
|
119
|
+
}
|
|
120
|
+
resolve({ id: componentId, options: options });
|
|
121
|
+
}).catch(function (err) {
|
|
122
|
+
if (timedOut_1) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
clearTimeout(timeoutHandle_1);
|
|
126
|
+
// console.error('Fetch error:', err);
|
|
127
|
+
resolve({ id: componentId, options: [] });
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
// console.error('Setup error:', err);
|
|
132
|
+
resolve({ id: componentId, options: [] });
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
return OptionFetcher;
|
|
137
|
+
}());
|
|
138
|
+
export { OptionFetcher };
|
|
139
|
+
export default OptionFetcher;
|