@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,484 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { Internationalization } from '@syncfusion/ej2-base';
|
|
13
|
+
import { DataManager, Query, UrlAdaptor, WebApiAdaptor, ODataV4Adaptor } from '@syncfusion/ej2-data';
|
|
14
|
+
import { ConditionalRuleEngine } from './conditional-rule-engine';
|
|
15
|
+
import { UI_TYPE_TO_SEMANTIC_TYPE } from './json-converter';
|
|
16
|
+
import { ExpressionEngine } from './expressions/expression-engine';
|
|
17
|
+
/**
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
export var VALIDATION_REGEX = {
|
|
21
|
+
EMAIL: /^(?!.*\.\.)[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
|
|
22
|
+
// eslint-disable-next-line security/detect-unsafe-regex
|
|
23
|
+
URL: /^(https?:\/\/)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(\/[^\s]*)?$/,
|
|
24
|
+
DATE_ISO: /^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/,
|
|
25
|
+
DIGITS: /^[0-9]*$/,
|
|
26
|
+
PHONE: /^[+]?[0-9]{9,13}$/,
|
|
27
|
+
CREDIT_CARD: /^\d{13,16}$/
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Maps button style to Syncfusion CSS classes
|
|
31
|
+
* @param style - Button style ('primary' | 'flat' | 'information' | 'error' | 'success' | 'warning')
|
|
32
|
+
* @returns Space-separated CSS class string
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
export var mapButtonStyleToClass = function (style) {
|
|
36
|
+
var styleMap = {
|
|
37
|
+
'primary': 'e-primary',
|
|
38
|
+
'flat': 'e-flat',
|
|
39
|
+
'information': 'e-info',
|
|
40
|
+
'error': 'e-danger',
|
|
41
|
+
'success': 'e-success',
|
|
42
|
+
'warning': 'e-warning'
|
|
43
|
+
};
|
|
44
|
+
return styleMap[style || 'primary'] || 'e-primary';
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Resolves button type to valid HTML button type
|
|
48
|
+
* @param type - Button type ('submit' | 'reset' | 'button')
|
|
49
|
+
* @returns Resolved button type
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
export var resolveButtonType = function (type) {
|
|
53
|
+
return (type === 'submit' || type === 'reset') ? type : 'button';
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Maps button position to CSS justifyContent value
|
|
57
|
+
* @param position - Button position ('Left' | 'Right' | 'Center')
|
|
58
|
+
* @returns CSS justifyContent value
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
export var mapPositionToJustifyContent = function (position) {
|
|
62
|
+
var positionMap = {
|
|
63
|
+
'Left': 'flex-start',
|
|
64
|
+
'Right': 'flex-end',
|
|
65
|
+
'Center': 'center'
|
|
66
|
+
};
|
|
67
|
+
return positionMap[position || 'Left'] || 'flex-start';
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
export function splitWidths(input) {
|
|
73
|
+
var result = input.map(function (v) { return (v === null ? NaN : Number(v)); });
|
|
74
|
+
var sumKnown = result.reduce(function (s, v) { return s + (isNaN(v) ? 0 : v); }, 0);
|
|
75
|
+
// If knowns already >= 100, unknowns become 0
|
|
76
|
+
var remainingInt = Math.max(0, Math.round(100 - sumKnown));
|
|
77
|
+
var unknownIndexes = result.map(function (v, i) { return (isNaN(v) ? i : -1); }).filter(function (i) { return i >= 0; });
|
|
78
|
+
var k = unknownIndexes.length;
|
|
79
|
+
if (k === 0) {
|
|
80
|
+
// nothing to split; just clamp/round knowns so they sum to 100 if you prefer, but return as-is
|
|
81
|
+
return result.map(function (v) { return Math.round(v); });
|
|
82
|
+
}
|
|
83
|
+
// Distribute integer percentage points to avoid fractional rounding problems
|
|
84
|
+
var base = Math.floor(remainingInt / k);
|
|
85
|
+
var remainder = remainingInt - base * k;
|
|
86
|
+
// Fill unknowns with base + 1 for first `remainder` items
|
|
87
|
+
unknownIndexes.forEach(function (idx) {
|
|
88
|
+
var add = remainder > 0 ? base + 1 : base;
|
|
89
|
+
result[idx] = add;
|
|
90
|
+
remainder = Math.max(0, remainder - 1);
|
|
91
|
+
});
|
|
92
|
+
// Convert any NaN (shouldn't remain) to 0 and round knowns
|
|
93
|
+
return result.map(function (v) { return (isNaN(v) ? 0 : Math.round(v)); });
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* @private
|
|
97
|
+
*/
|
|
98
|
+
export function extractAllDescendantIds(component) {
|
|
99
|
+
var childIds = [];
|
|
100
|
+
function traverse(comps) {
|
|
101
|
+
for (var _i = 0, comps_1 = comps; _i < comps_1.length; _i++) {
|
|
102
|
+
var comp = comps_1[_i];
|
|
103
|
+
childIds.push(comp.id);
|
|
104
|
+
// Recursively traverse nested structures
|
|
105
|
+
if (comp.children && Array.isArray(comp.children)) {
|
|
106
|
+
traverse(comp.children);
|
|
107
|
+
}
|
|
108
|
+
// Handle table cells
|
|
109
|
+
if (comp.tableCells && Array.isArray(comp.tableCells)) {
|
|
110
|
+
comp.tableCells.forEach(function (row) {
|
|
111
|
+
if (Array.isArray(row)) {
|
|
112
|
+
row.forEach(function (cell) {
|
|
113
|
+
if (Array.isArray(cell)) {
|
|
114
|
+
traverse(cell);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
// Handle tab items
|
|
121
|
+
if (comp.tabItems && Array.isArray(comp.tabItems)) {
|
|
122
|
+
comp.tabItems.forEach(function (tabItem) {
|
|
123
|
+
if (tabItem.content && Array.isArray(tabItem.content)) {
|
|
124
|
+
traverse(tabItem.content);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Start with direct children
|
|
131
|
+
if (component.children && Array.isArray(component.children)) {
|
|
132
|
+
traverse(component.children);
|
|
133
|
+
}
|
|
134
|
+
// Handle table cells
|
|
135
|
+
if (component.tableCells && Array.isArray(component.tableCells)) {
|
|
136
|
+
component.tableCells.forEach(function (row) {
|
|
137
|
+
if (Array.isArray(row)) {
|
|
138
|
+
row.forEach(function (cell) {
|
|
139
|
+
if (Array.isArray(cell)) {
|
|
140
|
+
traverse(cell);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// Handle tab items
|
|
147
|
+
if (component.tabItems && Array.isArray(component.tabItems)) {
|
|
148
|
+
component.tabItems.forEach(function (tabItem) {
|
|
149
|
+
if (tabItem.content && Array.isArray(tabItem.content)) {
|
|
150
|
+
traverse(tabItem.content);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return childIds;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
export function formatDateValues(component, value) {
|
|
160
|
+
var intl = new Internationalization();
|
|
161
|
+
var dFormatter = intl.getDateFormat({
|
|
162
|
+
format: 'MM/dd/yyyy',
|
|
163
|
+
type: 'date'
|
|
164
|
+
});
|
|
165
|
+
if (component.type === 'date') {
|
|
166
|
+
value = dFormatter(new Date(value));
|
|
167
|
+
}
|
|
168
|
+
if (component.type === 'time') {
|
|
169
|
+
dFormatter = intl.getDateFormat({
|
|
170
|
+
format: 'hh:mm a',
|
|
171
|
+
type: 'time'
|
|
172
|
+
});
|
|
173
|
+
value = dFormatter(new Date(value));
|
|
174
|
+
}
|
|
175
|
+
if (component.type === 'dateTime') {
|
|
176
|
+
dFormatter = intl.getDateFormat({
|
|
177
|
+
format: 'MM/dd/yyyy hh:mm a',
|
|
178
|
+
type: 'dateTime'
|
|
179
|
+
});
|
|
180
|
+
value = dFormatter(new Date(value));
|
|
181
|
+
}
|
|
182
|
+
if (component.type === 'dateRange' && Array.isArray(value)) {
|
|
183
|
+
value = value.map(function (date) {
|
|
184
|
+
return date ? dFormatter(new Date(date)) : null;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* @private
|
|
191
|
+
*/
|
|
192
|
+
export var getComponentFromSchema = function (id, formSchema) {
|
|
193
|
+
if (!id || !formSchema)
|
|
194
|
+
return null;
|
|
195
|
+
var findInComponents = function (components) {
|
|
196
|
+
for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
|
|
197
|
+
var comp = components_1[_i];
|
|
198
|
+
if (comp.id === id || comp.name === id)
|
|
199
|
+
return comp;
|
|
200
|
+
if (comp.children) {
|
|
201
|
+
var found = findInComponents(comp.children);
|
|
202
|
+
if (found)
|
|
203
|
+
return found;
|
|
204
|
+
}
|
|
205
|
+
if (comp.tableCells) {
|
|
206
|
+
for (var _a = 0, _b = comp.tableCells; _a < _b.length; _a++) {
|
|
207
|
+
var row = _b[_a];
|
|
208
|
+
for (var _c = 0, row_1 = row; _c < row_1.length; _c++) {
|
|
209
|
+
var cell = row_1[_c];
|
|
210
|
+
var found = findInComponents(cell);
|
|
211
|
+
if (found)
|
|
212
|
+
return found;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (comp.tabItems) {
|
|
217
|
+
for (var _d = 0, _e = comp.tabItems; _d < _e.length; _d++) {
|
|
218
|
+
var tab = _e[_d];
|
|
219
|
+
if (tab.content) {
|
|
220
|
+
var found = findInComponents(tab.content);
|
|
221
|
+
if (found)
|
|
222
|
+
return found;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
};
|
|
229
|
+
return findInComponents(formSchema.components || []);
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Helper function to get the appropriate adaptor instance
|
|
233
|
+
* @param adaptorType - Type of adaptor ('WebApiAdaptor' | 'UrlAdaptor' | 'ODataV4Adaptor')
|
|
234
|
+
* @returns Adaptor instance
|
|
235
|
+
* @private
|
|
236
|
+
*/
|
|
237
|
+
export var getAdaptorInstance = function (adaptorType) {
|
|
238
|
+
switch (adaptorType) {
|
|
239
|
+
case 'WebApiAdaptor':
|
|
240
|
+
return new WebApiAdaptor();
|
|
241
|
+
case 'ODataV4Adaptor':
|
|
242
|
+
return new ODataV4Adaptor();
|
|
243
|
+
case 'UrlAdaptor':
|
|
244
|
+
default:
|
|
245
|
+
return new UrlAdaptor();
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Extracts data from a nested path using dot notation and array indices
|
|
250
|
+
* @param data - The data object or array
|
|
251
|
+
* @param path - Path to the data (e.g., 'results.items', '[0].data', 'response[0].values')
|
|
252
|
+
* @returns Extracted data or empty array
|
|
253
|
+
* @private
|
|
254
|
+
*/
|
|
255
|
+
export var extractDataFromPath = function (data, path) {
|
|
256
|
+
if (!path || data === null || data === undefined)
|
|
257
|
+
return data;
|
|
258
|
+
// Split by dots but preserve array indices
|
|
259
|
+
var parts = path.split(/\.(?![^\[]*\])/); // Split by dots not inside brackets
|
|
260
|
+
var current = data;
|
|
261
|
+
for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
|
|
262
|
+
var part = parts_1[_i];
|
|
263
|
+
if (current === null || current === undefined) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
// Handle array index notation like [0] or results[0]
|
|
267
|
+
var arrayMatch = part.match(/^(\w*)\[(\d+)\]$/);
|
|
268
|
+
if (arrayMatch) {
|
|
269
|
+
var propName = arrayMatch[1];
|
|
270
|
+
var index = parseInt(arrayMatch[2]);
|
|
271
|
+
// If propName is empty, current should be an array
|
|
272
|
+
if (!propName) {
|
|
273
|
+
current = current[index];
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
current = current[propName] && current[propName][index];
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// Regular property access
|
|
281
|
+
current = current[part];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return current;
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Build name-indexed context from ID-indexed formValues
|
|
288
|
+
* Simple traversal to map field names to their values
|
|
289
|
+
* @private
|
|
290
|
+
*/
|
|
291
|
+
var buildNameContext = function (formValues, components) {
|
|
292
|
+
var context = {};
|
|
293
|
+
var traverse = function (comps) {
|
|
294
|
+
comps.forEach(function (comp) {
|
|
295
|
+
// Map name -> value from formValues (keyed by ID)
|
|
296
|
+
if (comp.name && comp.id in formValues) {
|
|
297
|
+
context[comp.name] = formValues[comp.id];
|
|
298
|
+
}
|
|
299
|
+
if (comp.children)
|
|
300
|
+
traverse(comp.children);
|
|
301
|
+
if (comp.tabItems)
|
|
302
|
+
comp.tabItems.forEach(function (t) { return t.content && traverse(t.content); });
|
|
303
|
+
if (comp.tableCells)
|
|
304
|
+
comp.tableCells.forEach(function (row) { return row.forEach(function (cell) { return traverse(cell); }); });
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
traverse(components);
|
|
308
|
+
return context;
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* @private
|
|
312
|
+
*/
|
|
313
|
+
var sharedFieldBindingEngine = new ExpressionEngine();
|
|
314
|
+
/**
|
|
315
|
+
* @private
|
|
316
|
+
*/
|
|
317
|
+
export var resolveFieldBinding = function (value, formValues, components) {
|
|
318
|
+
if (typeof value !== 'string' || !/{[^}]+}/.test(value)) {
|
|
319
|
+
return value; // No field references
|
|
320
|
+
}
|
|
321
|
+
// Build context: map field names to values from ID-keyed formValues
|
|
322
|
+
var context = components
|
|
323
|
+
? buildNameContext(formValues, components)
|
|
324
|
+
: formValues;
|
|
325
|
+
try {
|
|
326
|
+
var result = sharedFieldBindingEngine.evaluate(value, context);
|
|
327
|
+
return result !== null && result !== undefined ? String(result) : '';
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
return value; // Return original on error
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* @private
|
|
335
|
+
* (useFetchOptions is NOT located here — see ./option-fetcher.ts)
|
|
336
|
+
* (useFetchLookupOptions is NOT located here — see ./option-fetcher.ts)
|
|
337
|
+
*/
|
|
338
|
+
export var resolveOptions = function (options, fetchedOptions, fetchedLookupDataSource) {
|
|
339
|
+
// If lookup type with fetched data, return fetched lookup records
|
|
340
|
+
if (options && typeof options === 'object' && !Array.isArray(options) && options.type === 'lookup' && fetchedLookupDataSource) {
|
|
341
|
+
return fetchedLookupDataSource && fetchedLookupDataSource.length > 0 ? fetchedLookupDataSource : [];
|
|
342
|
+
}
|
|
343
|
+
// If URL type with fetched data, return fetched options
|
|
344
|
+
if (options && typeof options === 'object' && !Array.isArray(options) && options.type === 'url') {
|
|
345
|
+
return fetchedOptions.length > 0 ? fetchedOptions : [];
|
|
346
|
+
}
|
|
347
|
+
// If already an array, return as-is
|
|
348
|
+
if (Array.isArray(options)) {
|
|
349
|
+
return options;
|
|
350
|
+
}
|
|
351
|
+
// If it's raw data type
|
|
352
|
+
if (options && typeof options === 'object' && !Array.isArray(options) && options.type === 'raw') {
|
|
353
|
+
return Array.isArray(options.data) ? options.data : [];
|
|
354
|
+
}
|
|
355
|
+
return [];
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* @private
|
|
359
|
+
*/
|
|
360
|
+
export var collectAvailableFieldNames = function (components) {
|
|
361
|
+
var fieldNames = [];
|
|
362
|
+
var traverse = function (comps) {
|
|
363
|
+
comps.forEach(function (comp) {
|
|
364
|
+
// Only add fields that have a name and aren't layout components
|
|
365
|
+
if (comp.name && ['panel', 'table', 'tabs', 'card', 'message', 'button', 'splitButton', 'staticHtml'].indexOf(comp.type) === -1) {
|
|
366
|
+
// Get semantic type mapping for this component
|
|
367
|
+
var semanticType = UI_TYPE_TO_SEMANTIC_TYPE[comp.type];
|
|
368
|
+
if (semanticType) {
|
|
369
|
+
fieldNames.push(__assign({ name: comp.name, type: semanticType.type }, (semanticType.format && { format: semanticType.format })));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// Traverse nested components
|
|
373
|
+
if (comp.children)
|
|
374
|
+
traverse(comp.children);
|
|
375
|
+
if (comp.tabItems) {
|
|
376
|
+
comp.tabItems.forEach(function (tab) {
|
|
377
|
+
if (tab.content)
|
|
378
|
+
traverse(tab.content);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
if (comp.tableCells) {
|
|
382
|
+
comp.tableCells.forEach(function (row) {
|
|
383
|
+
row.forEach(function (cell) { return traverse(cell); });
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
};
|
|
388
|
+
traverse(components);
|
|
389
|
+
return fieldNames;
|
|
390
|
+
};
|
|
391
|
+
/**
|
|
392
|
+
* Resolve conditional data for a DataGrid component
|
|
393
|
+
* Evaluates all conditionalData rules and applies the first matching one
|
|
394
|
+
* Returns both dataSource and custom columns if defined
|
|
395
|
+
*
|
|
396
|
+
* @param conditions - Component conditions including conditional data rules
|
|
397
|
+
* @param formValues - Current form field values
|
|
398
|
+
* @returns Object with dataSource and columns, or undefined if no condition matches
|
|
399
|
+
* @private
|
|
400
|
+
*/
|
|
401
|
+
export var resolveConditionalData = function (conditions, formValues) {
|
|
402
|
+
if (!conditions || !conditions.conditionalData || !Array.isArray(conditions.conditionalData)) {
|
|
403
|
+
return undefined;
|
|
404
|
+
}
|
|
405
|
+
// Evaluate each conditional data rule in order
|
|
406
|
+
for (var _i = 0, _a = conditions.conditionalData; _i < _a.length; _i++) {
|
|
407
|
+
var rule = _a[_i];
|
|
408
|
+
if (ConditionalRuleEngine.evaluateCondition(rule.condition, formValues)) {
|
|
409
|
+
// Condition is met - resolve and return both data source and columns
|
|
410
|
+
return {
|
|
411
|
+
dataSource: rule.dataSource,
|
|
412
|
+
columns: rule.columns && rule.columns.length > 0 ? rule.columns : undefined
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return undefined;
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* Reads the current builder mode from the URL `mode` query parameter.
|
|
420
|
+
* @returns 'Simple' | 'Developer' | undefined if not present or invalid
|
|
421
|
+
* @private
|
|
422
|
+
*/
|
|
423
|
+
export var getCurrentMode = function () {
|
|
424
|
+
if (typeof window === 'undefined')
|
|
425
|
+
return undefined;
|
|
426
|
+
var urlMode = new URLSearchParams(window.location.search).get('mode');
|
|
427
|
+
if (urlMode === 'developer')
|
|
428
|
+
return 'Developer';
|
|
429
|
+
if (urlMode === 'simple')
|
|
430
|
+
return 'Simple';
|
|
431
|
+
return undefined;
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
* Navigates to a URL while preserving the current `mode` query parameter.
|
|
435
|
+
* - If `mode` is already in target, it is kept as-is.
|
|
436
|
+
* - If `mode` is present in the current URL, it is appended to the target.
|
|
437
|
+
*
|
|
438
|
+
* @param target - Target path (may include existing query params), e.g. '/?sample=builder&formId=123'
|
|
439
|
+
* @private
|
|
440
|
+
*/
|
|
441
|
+
export var navigateTo = function (target) {
|
|
442
|
+
if (typeof window === 'undefined') {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
try {
|
|
446
|
+
var url = new URL('/demo' + target, window.location.origin);
|
|
447
|
+
window.location.href = url.toString();
|
|
448
|
+
}
|
|
449
|
+
catch (_a) {
|
|
450
|
+
window.location.href = '/demo' + target;
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
/**
|
|
454
|
+
* @private
|
|
455
|
+
*/
|
|
456
|
+
export function sanitizeId(rawId, fallback) {
|
|
457
|
+
var MAX_ID_LEN = 100;
|
|
458
|
+
var safeFallback = typeof fallback === 'string' && fallback ? fallback : "field_" + Date.now() + "_" + Math.floor(Math.random() * 1000);
|
|
459
|
+
if (rawId === null || rawId === undefined)
|
|
460
|
+
return safeFallback;
|
|
461
|
+
var id = String(rawId).trim();
|
|
462
|
+
// Reject obvious prototype/constructor keys outright
|
|
463
|
+
if (!id || id === '__proto__' || id === 'prototype' || id === 'constructor') {
|
|
464
|
+
return safeFallback;
|
|
465
|
+
}
|
|
466
|
+
// Replace any character that is not alnum, dash, or underscore with underscore.
|
|
467
|
+
id = id.replace(/[^A-Za-z0-9_-]/g, '_');
|
|
468
|
+
// Ensure it starts with a letter or underscore (prepend if necessary).
|
|
469
|
+
if (!/^[A-Za-z_]/.test(id)) {
|
|
470
|
+
id = "f_" + id;
|
|
471
|
+
}
|
|
472
|
+
// Truncate to a reasonable max length
|
|
473
|
+
if (id.length > MAX_ID_LEN) {
|
|
474
|
+
id = id.slice(0, MAX_ID_LEN);
|
|
475
|
+
}
|
|
476
|
+
// Final guard: avoid reserved names
|
|
477
|
+
if (id === '__proto__' || id === 'prototype' || id === 'constructor') {
|
|
478
|
+
return safeFallback;
|
|
479
|
+
}
|
|
480
|
+
return id;
|
|
481
|
+
}
|
|
482
|
+
// Exported EJ2 data symbols re-exported for downstream consumers (form-renderer option fetcher).
|
|
483
|
+
// `DataManager` / `Query` are used by OptionFetcher (see ./option-fetcher.ts).
|
|
484
|
+
export { DataManager, Query };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Component, Property, Event, EmitType, NotifyPropertyChanges, enableRipple, createElement, isNullOrUndefined, L10n, getComponent, addClass } from '@syncfusion/ej2-base';import { Tab, Toolbar } from '@syncfusion/ej2-navigations';import { Tooltip } from '@syncfusion/ej2-popups';import { FormValidator, Signature } from '@syncfusion/ej2-inputs';import { FormLayout, FormNode, Schema } from './types/form-schema';import { renderFormField } from './render-form-field';import { mergeSchema, UnifiedSchema } from '../common/json-converter';import { UniversalJsonParser } from '../common/parser';import { VALIDATION_REGEX, formatDateValues, splitWidths } from '../common/utils';import StaticHtmlRenderer from '../common/static-html-renderer';import { ConditionalRuleEngine, FormValueType } from '../common/conditional-rule-engine';import { ExpressionEngine, DependencyGraph } from '../common/expressions/expression-engine';import { MinMaxRuleEngine } from '../common/minmax-rule-engine';import { CustomValidationEngine } from '../common/custom-validation-engine';import { RichTextEditor } from '@syncfusion/ej2-richtexteditor';import { ImageEditor } from '@syncfusion/ej2-image-editor';
|
|
2
|
+
import {SubmitEventArgs,ChangeEventArgs,ButtonClickEventArgs,FailureEventArgs} from "./form-renderer";
|
|
3
|
+
import {ComponentModel} from '@syncfusion/ej2-base';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Interface for a class FormRenderer
|
|
7
|
+
*/
|
|
8
|
+
export interface FormRendererModel extends ComponentModel{
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Specifies the data schema of the form that needs to be rendered in the Form Renderer.
|
|
12
|
+
*/
|
|
13
|
+
schema?: Schema | string | Record<string, unknown> | null;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Specifies the form layout configuration (only applies when layout details are NOT available in the schema). Determines how form fields are arranged in columns.
|
|
17
|
+
*
|
|
18
|
+
* @default 'SingleColumn'
|
|
19
|
+
*/
|
|
20
|
+
layout?: FormLayout | string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Specifies the CSS class name to apply to the root form container element. This property supports space-separated multiple classes.
|
|
24
|
+
*
|
|
25
|
+
* @default ""
|
|
26
|
+
*/
|
|
27
|
+
className?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Event triggered when the form is submitted.
|
|
31
|
+
* This event provides form data and validation status in the event argument.
|
|
32
|
+
*
|
|
33
|
+
* @event
|
|
34
|
+
*/
|
|
35
|
+
submit?: EmitType<SubmitEventArgs>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Event triggered when any form field value changes. Fired on user input for tracked fields.
|
|
39
|
+
*
|
|
40
|
+
* @event
|
|
41
|
+
*/
|
|
42
|
+
change?: EmitType<ChangeEventArgs>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Event triggered when a button in the form is clicked. Applies to all button types (button, submit, splitButton).
|
|
46
|
+
*
|
|
47
|
+
* @event
|
|
48
|
+
*/
|
|
49
|
+
buttonClick?: EmitType<ButtonClickEventArgs>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Event triggered when an error is thrown in the form rendering or schema parsing.
|
|
53
|
+
*
|
|
54
|
+
* @event
|
|
55
|
+
*/
|
|
56
|
+
failure?: EmitType<FailureEventArgs>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Event triggered when all form elements are rendered and ready for interaction. Useful for performing post-render initialization or setup.
|
|
60
|
+
*
|
|
61
|
+
* @event
|
|
62
|
+
*/
|
|
63
|
+
created?: EmitType<Object>;
|
|
64
|
+
|
|
65
|
+
}
|