@daracl/form 0.0.4 → 0.0.5
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/dist/193.daracl.form.min.js +7 -0
- package/dist/193.daracl.form.min.js.LICENSE.txt +5 -0
- package/dist/193.daracl.form.min.js.map +1 -0
- package/dist/dara.datetimepicker.js +304 -0
- package/dist/dara.datetimepicker.js.LICENSE.txt +5 -0
- package/dist/dara.datetimepicker.js.map +1 -0
- package/dist/daracl.form.js +52 -26
- package/dist/daracl.form.js.map +1 -1
- package/dist/daracl.form.min.css +2 -2
- package/dist/daracl.form.min.css.map +1 -1
- package/dist/daracl.form.min.js +2 -2
- package/dist/daracl.form.min.js.LICENSE.txt +1 -1
- package/dist/daracl.form.min.js.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +2 -2
- package/dist/index.css.map +2 -2
- package/dist/index.js +5 -1
- package/dist/index.js.map +2 -2
- package/dist/util/utils.d.ts +1 -1
- package/dist/vendors-node_modules_daracl_datetimepicker_dist_index_js.daracl.form.js +1477 -0
- package/dist/vendors-node_modules_daracl_datetimepicker_dist_index_js.daracl.form.js.map +1 -0
- package/package.json +11 -8
- package/src/DaraForm.ts +431 -0
- package/src/FieldInfoMap.ts +356 -0
- package/src/FormTemplate.ts +207 -0
- package/src/constants.ts +100 -0
- package/src/event/renderEvents.ts +41 -0
- package/src/index copy.html +591 -0
- package/src/index-grid.html +655 -0
- package/src/index-tab.html +639 -0
- package/src/index.html +483 -0
- package/src/renderer/ButtonRender.ts +51 -0
- package/src/renderer/CheckboxRender.ts +214 -0
- package/src/renderer/CustomRender.ts +100 -0
- package/src/renderer/DateRender.ts +103 -0
- package/src/renderer/DropdownRender.ts +149 -0
- package/src/renderer/FileRender.ts +239 -0
- package/src/renderer/GridRender.ts +289 -0
- package/src/renderer/GroupRender.ts +47 -0
- package/src/renderer/HiddenRender.ts +36 -0
- package/src/renderer/NumberRender.ts +68 -0
- package/src/renderer/PasswordRender.ts +69 -0
- package/src/renderer/RadioRender.ts +191 -0
- package/src/renderer/RangeRender.ts +79 -0
- package/src/renderer/Render.ts +194 -0
- package/src/renderer/TabRender.ts +229 -0
- package/src/renderer/TextAreaRender.ts +72 -0
- package/src/renderer/TextRender.ts +68 -0
- package/src/rule/fileValidator.ts +26 -0
- package/src/rule/numberValidator.ts +96 -0
- package/src/rule/regexpValidator.ts +45 -0
- package/src/rule/stringValidator.ts +64 -0
- package/src/rule/validator.ts +49 -0
- package/src/types/DataMap.d.ts +17 -0
- package/src/types/FormField.d.ts +129 -0
- package/src/types/FormOptions.d.ts +91 -0
- package/src/types/Message.d.ts +40 -0
- package/src/types/ValidResult.d.ts +9 -0
- package/src/util/Lanauage.ts +127 -0
- package/src/util/renderFactory.ts +26 -0
- package/src/util/styleUtils.ts +85 -0
- package/src/util/utils.ts +283 -0
- package/src/util/validUtils.ts +53 -0
- package/style/daracl.form.scss +2 -1
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { FIELD_PREFIX } from "src/constants";
|
|
2
|
+
import { FormField } from "./types/FormField";
|
|
3
|
+
import { ValidResult } from "./types/ValidResult";
|
|
4
|
+
import { getRenderer } from "./util/renderFactory";
|
|
5
|
+
import Lanauage from "./util/Lanauage";
|
|
6
|
+
import * as utils from "./util/utils";
|
|
7
|
+
import DaraForm from "./DaraForm";
|
|
8
|
+
|
|
9
|
+
interface NumberFieldMap {
|
|
10
|
+
[key: string]: FormField;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface StringNumberMap {
|
|
14
|
+
[key: string]: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default class FieldInfoMap {
|
|
18
|
+
private fieldIdx = 0;
|
|
19
|
+
|
|
20
|
+
private allFieldInfo: NumberFieldMap = {};
|
|
21
|
+
|
|
22
|
+
private keyNameMap: StringNumberMap = {};
|
|
23
|
+
|
|
24
|
+
private conditionFields: string[] = [];
|
|
25
|
+
|
|
26
|
+
private fieldPrefix;
|
|
27
|
+
|
|
28
|
+
private form;
|
|
29
|
+
|
|
30
|
+
constructor(selector: string, form: DaraForm) {
|
|
31
|
+
this.fieldPrefix = `${FIELD_PREFIX}_${utils.getHashCode(selector)}`;
|
|
32
|
+
this.form = form;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* add Field 정보
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
* @param {FormField} field 폼필드 정보
|
|
40
|
+
*/
|
|
41
|
+
public addField(field: FormField) {
|
|
42
|
+
utils.replaceXssField(field);
|
|
43
|
+
this.fieldIdx += 1;
|
|
44
|
+
field.$key = `${this.fieldPrefix}_${this.fieldIdx}`;
|
|
45
|
+
field.$validName = field.name ?? field.label;
|
|
46
|
+
this.keyNameMap[field.$validName] = field.$key;
|
|
47
|
+
this.allFieldInfo[field.$key] = field;
|
|
48
|
+
field.$renderType = getRenderer(field);
|
|
49
|
+
|
|
50
|
+
if (field.conditional) {
|
|
51
|
+
this.conditionFields.push(field.$key);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 필드명으로 필드 정부 구하기
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
* @param {string} fieldName 필드명
|
|
60
|
+
* @returns {FormField}
|
|
61
|
+
*/
|
|
62
|
+
public getFieldName(fieldName: string): FormField {
|
|
63
|
+
return this.allFieldInfo[this.keyNameMap[fieldName]];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 필드 키로 정보 구하기
|
|
68
|
+
*
|
|
69
|
+
* @public
|
|
70
|
+
* @param {string} fieldKey
|
|
71
|
+
* @returns {FormField}
|
|
72
|
+
*/
|
|
73
|
+
public get(fieldKey: string): FormField {
|
|
74
|
+
return this.allFieldInfo[fieldKey];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 필드명 있는지 여부 체크.
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
81
|
+
* @param {string} fieldName 필드명
|
|
82
|
+
* @returns {boolean}
|
|
83
|
+
*/
|
|
84
|
+
public hasFieldName(fieldName: string): boolean {
|
|
85
|
+
if (this.keyNameMap[fieldName] && this.allFieldInfo[this.keyNameMap[fieldName]]) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 모든 필드 정보
|
|
94
|
+
*
|
|
95
|
+
* @public
|
|
96
|
+
* @returns {NumberFieldMap}
|
|
97
|
+
*/
|
|
98
|
+
public getAllFieldInfo(): NumberFieldMap {
|
|
99
|
+
return this.allFieldInfo;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 필드 정보 맵에서 지우기
|
|
104
|
+
*
|
|
105
|
+
* @public
|
|
106
|
+
* @param {string} fieldName
|
|
107
|
+
*/
|
|
108
|
+
public removeFieldInfo(fieldName: string) {
|
|
109
|
+
delete this.allFieldInfo[this.keyNameMap[fieldName]];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 모든 필드값 구하기
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
* @param {boolean} validationCheck
|
|
117
|
+
* @returns {*}
|
|
118
|
+
*/
|
|
119
|
+
public getAllFieldValue(formValue: any, validationCheck: boolean) {
|
|
120
|
+
const useTypeValue = this.form.getOptions().useTypeValue;
|
|
121
|
+
|
|
122
|
+
if (validationCheck !== true) {
|
|
123
|
+
for (let [key, fieldInfo] of Object.entries(this.allFieldInfo)) {
|
|
124
|
+
formValue = addFormValue(formValue, fieldInfo, useTypeValue);
|
|
125
|
+
}
|
|
126
|
+
return formValue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
for (let [key, fieldInfo] of Object.entries(this.allFieldInfo)) {
|
|
131
|
+
if (!fieldInfo.$instance.isEnableView()) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let fieldValid = this.getFieldValidation(fieldInfo, true);
|
|
136
|
+
|
|
137
|
+
if (fieldValid !== true) {
|
|
138
|
+
reject(new Error(fieldValid.message, { cause: fieldValid }));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
formValue = addFormValue(formValue, fieldInfo, useTypeValue);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
resolve(formValue);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public getFormDataValue(formValue: any, validationCheck: boolean) {
|
|
150
|
+
if (validationCheck !== true) {
|
|
151
|
+
let reval = new FormData();
|
|
152
|
+
|
|
153
|
+
for (let [key, value] of Object.entries(formValue)) {
|
|
154
|
+
reval.set(key, value as any);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
for (let [key, fieldInfo] of Object.entries(this.allFieldInfo)) {
|
|
158
|
+
addFieldFormData(reval, fieldInfo, fieldInfo.$instance.getValue());
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return reval;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return new Promise((resolve, reject) => {
|
|
165
|
+
let reval = new FormData();
|
|
166
|
+
|
|
167
|
+
for (let [key, value] of Object.entries(formValue)) {
|
|
168
|
+
reval.set(key, value as any);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
for (let [key, fieldInfo] of Object.entries(this.allFieldInfo)) {
|
|
172
|
+
if (!fieldInfo.$instance.isEnableView()) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
let fieldValid = this.getFieldValidation(fieldInfo, true);
|
|
177
|
+
|
|
178
|
+
if (fieldValid !== true) {
|
|
179
|
+
reject(new Error(fieldValid.message, { cause: fieldValid }));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
addFieldFormData(reval, fieldInfo, fieldInfo.$instance.getValue());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
resolve(reval);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
*
|
|
192
|
+
*
|
|
193
|
+
* @param field
|
|
194
|
+
* @returns
|
|
195
|
+
*/
|
|
196
|
+
public isConditionFieldCheck(field: FormField) {
|
|
197
|
+
let parent = field;
|
|
198
|
+
|
|
199
|
+
while (typeof parent !== "undefined") {
|
|
200
|
+
if (!this.isConditionField(parent)) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
parent = parent.$parent;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* field 활성 비활성화 여부.
|
|
212
|
+
*
|
|
213
|
+
* @param field form field
|
|
214
|
+
* @returns
|
|
215
|
+
*/
|
|
216
|
+
public isConditionField(field: FormField) {
|
|
217
|
+
if (!this.conditionFields.includes(field.$key)) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
let condFlag = false;
|
|
222
|
+
|
|
223
|
+
if (field.conditional.custom) {
|
|
224
|
+
condFlag = field.conditional.custom.call(null, field);
|
|
225
|
+
} else {
|
|
226
|
+
if (field.conditional.field) {
|
|
227
|
+
const condField = this.getFieldName(field.conditional.field);
|
|
228
|
+
|
|
229
|
+
if (condField) {
|
|
230
|
+
if (field.conditional.eq == condField.$instance.getValue()) {
|
|
231
|
+
condFlag = true;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return condFlag;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* 컬럼 로우 보이고 안보이기 체크.
|
|
242
|
+
*
|
|
243
|
+
* @public
|
|
244
|
+
*/
|
|
245
|
+
public conditionCheck() {
|
|
246
|
+
this.conditionFields.forEach((fieldKey) => {
|
|
247
|
+
const fieldInfo = this.allFieldInfo[fieldKey];
|
|
248
|
+
|
|
249
|
+
let condFlag = this.isConditionField(fieldInfo);
|
|
250
|
+
|
|
251
|
+
if (condFlag) {
|
|
252
|
+
fieldInfo.$instance.show();
|
|
253
|
+
} else {
|
|
254
|
+
fieldInfo.$instance.hide();
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* field validation check
|
|
261
|
+
*
|
|
262
|
+
* @param fieldInfo FormField
|
|
263
|
+
* @returns boolean true or ValidResult
|
|
264
|
+
*/
|
|
265
|
+
public getFieldValidation(fieldInfo: FormField, focusFlag: boolean | undefined) {
|
|
266
|
+
if (!this.isConditionFieldCheck(fieldInfo)) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const renderInfo = fieldInfo.$instance;
|
|
271
|
+
let fieldValid = renderInfo.valid();
|
|
272
|
+
|
|
273
|
+
if (fieldValid === true) return true;
|
|
274
|
+
|
|
275
|
+
if (focusFlag) {
|
|
276
|
+
renderInfo.focus();
|
|
277
|
+
}
|
|
278
|
+
fieldValid = fieldValid as ValidResult;
|
|
279
|
+
if (utils.isUndefined(fieldValid.message)) {
|
|
280
|
+
fieldValid.message = Lanauage.validMessage(fieldInfo, fieldValid)[0];
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return fieldValid;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* add form value
|
|
289
|
+
* @param formData {Object} return Object value
|
|
290
|
+
* @param fieldInfo {FormField} field info
|
|
291
|
+
* @param fieldValue {any} form value
|
|
292
|
+
*/
|
|
293
|
+
function addFormValue(formData: any, fieldInfo: FormField, useTypeValue?: boolean) {
|
|
294
|
+
if (utils.ignoreValueField(fieldInfo)) {
|
|
295
|
+
return formData;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const fieldValue = fieldInfo.$instance.getValue();
|
|
299
|
+
|
|
300
|
+
if (fieldInfo.renderType === "file") {
|
|
301
|
+
const uploadFiles = fieldValue["uploadFile"];
|
|
302
|
+
|
|
303
|
+
formData[fieldInfo.$validName] = uploadFiles;
|
|
304
|
+
formData[fieldInfo.$validName + "RemoveIds"] = fieldValue["removeIds"];
|
|
305
|
+
} else {
|
|
306
|
+
if (useTypeValue !== true) {
|
|
307
|
+
if (utils.isTabType(fieldInfo)) {
|
|
308
|
+
for (let [key, value] of Object.entries(fieldValue)) {
|
|
309
|
+
formData[key] = value;
|
|
310
|
+
}
|
|
311
|
+
} else {
|
|
312
|
+
if (!utils.isEmpty(fieldInfo.name)) {
|
|
313
|
+
formData[fieldInfo.name] = fieldValue;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
formData[fieldInfo.$validName] = fieldValue;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return formData;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function addFieldFormData(formData: FormData, fieldInfo: FormField, useTypeValue?: boolean) {
|
|
325
|
+
if (utils.ignoreValueField(fieldInfo)) {
|
|
326
|
+
return formData;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const fieldValue = fieldInfo.$instance.getValue();
|
|
330
|
+
|
|
331
|
+
if (fieldInfo.renderType === "file") {
|
|
332
|
+
const uploadFiles = fieldValue["uploadFile"];
|
|
333
|
+
formData.delete(fieldInfo.$validName);
|
|
334
|
+
for (let uploadFile of uploadFiles) {
|
|
335
|
+
formData.append(fieldInfo.$validName, uploadFile);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
formData.set(fieldInfo.$validName + "RemoveIds", fieldValue["removeIds"]);
|
|
339
|
+
} else {
|
|
340
|
+
if (useTypeValue !== true) {
|
|
341
|
+
if (utils.isTabType(fieldInfo)) {
|
|
342
|
+
for (let [key, value] of Object.entries(fieldValue)) {
|
|
343
|
+
formData.set(key, value as any);
|
|
344
|
+
}
|
|
345
|
+
} else {
|
|
346
|
+
if (!utils.isEmpty(fieldInfo.name)) {
|
|
347
|
+
formData.set(fieldInfo.$validName, fieldValue);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
} else {
|
|
351
|
+
formData.set(fieldInfo.$validName, fieldValue);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return formData;
|
|
356
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { FormOptions } from "@t/FormOptions";
|
|
2
|
+
import { FieldStyle, FormField } from "@t/FormField";
|
|
3
|
+
import * as utils from "./util/utils";
|
|
4
|
+
import FieldInfoMap from "src/FieldInfoMap";
|
|
5
|
+
|
|
6
|
+
import styleUtils from "./util/styleUtils";
|
|
7
|
+
import DaraForm from "./DaraForm";
|
|
8
|
+
import TabRender from "./renderer/TabRender";
|
|
9
|
+
import GridRender from "./renderer/GridRender";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* form template
|
|
13
|
+
*
|
|
14
|
+
* @class FormTemplate
|
|
15
|
+
* @typedef {FormTemplate}
|
|
16
|
+
*/
|
|
17
|
+
export default class FormTemplate {
|
|
18
|
+
private readonly options: FormOptions;
|
|
19
|
+
private readonly formElement;
|
|
20
|
+
|
|
21
|
+
private fieldInfoMap;
|
|
22
|
+
|
|
23
|
+
private daraform: DaraForm;
|
|
24
|
+
|
|
25
|
+
private addRowFields: string[] = [];
|
|
26
|
+
|
|
27
|
+
constructor(daraform: DaraForm, formElement: Element, fieldInfoMap: FieldInfoMap) {
|
|
28
|
+
this.daraform = daraform;
|
|
29
|
+
this.options = daraform.getOptions();
|
|
30
|
+
this.formElement = formElement;
|
|
31
|
+
|
|
32
|
+
this.fieldInfoMap = fieldInfoMap;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* field row 추가.
|
|
37
|
+
*
|
|
38
|
+
* @param field
|
|
39
|
+
*/
|
|
40
|
+
public addRow(field: FormField) {
|
|
41
|
+
if (this.checkHiddenField(field)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.addRowFields = [];
|
|
46
|
+
|
|
47
|
+
this.addRowTemplate(field);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 그룹 템플릿
|
|
52
|
+
*
|
|
53
|
+
* @param {FormField} field
|
|
54
|
+
* @returns {string} row template
|
|
55
|
+
*/
|
|
56
|
+
public addRowTemplate(field: FormField): void {
|
|
57
|
+
let labelHideFlag = this.isLabelHide(field);
|
|
58
|
+
|
|
59
|
+
let fieldStyle: FieldStyle = styleUtils.fieldStyle(this.options, field, null, labelHideFlag);
|
|
60
|
+
|
|
61
|
+
this.addRowFieldInfo(field);
|
|
62
|
+
|
|
63
|
+
const rowElement = utils.templateToElement(`
|
|
64
|
+
<div class="df-row form-group ${fieldStyle.fieldClass}" id="${field.$key}">
|
|
65
|
+
${labelHideFlag ? "" : `<div class="df-label ${fieldStyle.labelClass} ${fieldStyle.labelAlignClass}" title="${field.label ?? ""}" style="${fieldStyle.labelStyle}">${this.getLabelTemplate(field)}</div>`}
|
|
66
|
+
|
|
67
|
+
<div class="df-field-container ${fieldStyle.valueClass} ${field.required ? "required" : ""}" style="${fieldStyle.valueStyle}"></div>
|
|
68
|
+
</div>
|
|
69
|
+
`);
|
|
70
|
+
|
|
71
|
+
if (rowElement) {
|
|
72
|
+
this.createField(field, rowElement);
|
|
73
|
+
this.formElement.append(rowElement);
|
|
74
|
+
|
|
75
|
+
if (field.children) {
|
|
76
|
+
this.childTemplate(field, fieldStyle);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public createField(field: FormField, element: Element): void {
|
|
82
|
+
field.$instance = new (field.$renderType as any)(field, element, this.daraform);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* child template
|
|
87
|
+
*
|
|
88
|
+
* @param {FormField} field
|
|
89
|
+
* @param {FieldStyle} parentFieldStyle
|
|
90
|
+
* @returns {*}
|
|
91
|
+
*/
|
|
92
|
+
public childTemplate(field: FormField, parentFieldStyle: FieldStyle): void {
|
|
93
|
+
let beforeField: FormField = null as any;
|
|
94
|
+
let firstFlag = true;
|
|
95
|
+
let isEmptyLabel = false;
|
|
96
|
+
|
|
97
|
+
if (!(field.$renderType as any).isChildrenCreate()) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const rowElement = document.createElement("div");
|
|
102
|
+
rowElement.classList.add("df-row", parentFieldStyle.rowStyleClass ?? "");
|
|
103
|
+
|
|
104
|
+
let idx = 0;
|
|
105
|
+
|
|
106
|
+
for (const childField of field.children) {
|
|
107
|
+
if (utils.isEmpty(childField)) {
|
|
108
|
+
throw new Error(`parent field :[${field.$validName}], children index ${idx}, empty [${childField}]`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
childField.$parent = field;
|
|
112
|
+
++idx;
|
|
113
|
+
|
|
114
|
+
if (this.checkHiddenField(childField)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.addRowFieldInfo(childField);
|
|
119
|
+
|
|
120
|
+
if (firstFlag) {
|
|
121
|
+
beforeField = childField;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let labelHideFlag = this.isLabelHide(childField);
|
|
125
|
+
|
|
126
|
+
let childFieldStyle;
|
|
127
|
+
|
|
128
|
+
let labelTemplate = "";
|
|
129
|
+
if (labelHideFlag) {
|
|
130
|
+
childFieldStyle = styleUtils.fieldStyle(this.options, childField, beforeField, !isEmptyLabel);
|
|
131
|
+
labelTemplate = isEmptyLabel ? `<span class="df-label empty ${childFieldStyle.labelClass}" style="${childFieldStyle.labelStyle}"></span>` : "";
|
|
132
|
+
} else {
|
|
133
|
+
childFieldStyle = styleUtils.fieldStyle(this.options, childField, beforeField, false);
|
|
134
|
+
labelTemplate = `<span class="df-label ${childFieldStyle.labelClass} ${childFieldStyle.labelAlignClass}" title="${childField.label ?? ""}" style="${childFieldStyle.labelStyle}">${this.getLabelTemplate(childField)}</span>`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const groupElement = utils.templateToElement(`<div class="form-group ${childFieldStyle.fieldClass}" style="${childFieldStyle.fieldStyle}" id="${childField.$key}">
|
|
138
|
+
${labelTemplate}
|
|
139
|
+
<span class="df-field-container ${childFieldStyle.valueClass} ${childField.required ? "required" : ""}" style="${childFieldStyle.valueStyle}"></span>
|
|
140
|
+
</div>`);
|
|
141
|
+
|
|
142
|
+
if (groupElement) {
|
|
143
|
+
this.createField(childField, groupElement);
|
|
144
|
+
rowElement.append(groupElement);
|
|
145
|
+
|
|
146
|
+
if (childField.children) {
|
|
147
|
+
this.childTemplate(childField, childField.children ? childFieldStyle : parentFieldStyle);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (!labelHideFlag) {
|
|
151
|
+
isEmptyLabel = true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
firstFlag = false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
field.$instance.addChildField(rowElement);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* label template
|
|
162
|
+
*
|
|
163
|
+
* @param {FormField} field form field
|
|
164
|
+
* @returns {string} template string
|
|
165
|
+
*/
|
|
166
|
+
public getLabelTemplate(field: FormField) {
|
|
167
|
+
const requiredTemplate = field.required ? `<span class="required"></span>` : "";
|
|
168
|
+
const tooltipTemplate = utils.isBlank(field.tooltip) ? "" : `<span class="df-tooltip">?<span class="tooltip">${field.tooltip}</span></span>`;
|
|
169
|
+
|
|
170
|
+
return `${field.label ?? ""} ${tooltipTemplate} ${requiredTemplate}`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* label 숨김 여부
|
|
175
|
+
*
|
|
176
|
+
* @param field formfield
|
|
177
|
+
* @returns
|
|
178
|
+
*/
|
|
179
|
+
public isLabelHide(field: FormField): boolean {
|
|
180
|
+
return field.style?.labelHide || utils.isUndefined(field.label);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public checkHiddenField(field: FormField) {
|
|
184
|
+
if (utils.isHiddenField(field)) {
|
|
185
|
+
this.fieldInfoMap.addField(field);
|
|
186
|
+
field.$instance = new (field.$renderType as any)(field, null, this.daraform);
|
|
187
|
+
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* add row file map
|
|
196
|
+
*
|
|
197
|
+
* @param {FormField} field
|
|
198
|
+
*/
|
|
199
|
+
public addRowFieldInfo(field: FormField) {
|
|
200
|
+
if (!utils.isBlank(field.name) && this.fieldInfoMap.hasFieldName(field.name)) {
|
|
201
|
+
throw new Error(`Duplicate field name "${field.name}"`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.fieldInfoMap.addField(field);
|
|
205
|
+
this.addRowFields.push(field.$key);
|
|
206
|
+
}
|
|
207
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import NumberRender from "src/renderer/NumberRender";
|
|
2
|
+
import TextAreaRender from "src/renderer/TextAreaRender";
|
|
3
|
+
import DropdownRender from "src/renderer/DropdownRender";
|
|
4
|
+
import TextRender from "src/renderer/TextRender";
|
|
5
|
+
import CheckboxRender from "src/renderer/CheckboxRender";
|
|
6
|
+
import RadioRender from "src/renderer/RadioRender";
|
|
7
|
+
import PasswordRender from "src/renderer/PasswordRender";
|
|
8
|
+
import FileRender from "src/renderer/FileRender";
|
|
9
|
+
import CustomRender from "./renderer/CustomRender";
|
|
10
|
+
import GroupRender from "./renderer/GroupRender";
|
|
11
|
+
import HiddenRender from "./renderer/HiddenRender";
|
|
12
|
+
import ButtonRender from "./renderer/ButtonRender";
|
|
13
|
+
import RangeRender from "./renderer/RangeRender";
|
|
14
|
+
import DateRender from "./renderer/DateRender";
|
|
15
|
+
import TabRender from "./renderer/TabRender";
|
|
16
|
+
import GridRender from "./renderer/GridRender";
|
|
17
|
+
|
|
18
|
+
export type FORM_MODE = "new" | "modify" | "view";
|
|
19
|
+
|
|
20
|
+
export const RULES = {
|
|
21
|
+
NAN: "nan",
|
|
22
|
+
MIN: "minimum",
|
|
23
|
+
EXCLUSIVE_MIN: "exclusiveMinimum",
|
|
24
|
+
MAX: "maximum",
|
|
25
|
+
EXCLUSIVE_MAX: "exclusiveMaximum",
|
|
26
|
+
MIN_LENGTH: "minLength",
|
|
27
|
+
MAX_LENGTH: "maxLength",
|
|
28
|
+
BETWEEN: "between",
|
|
29
|
+
BETWEEN_EXCLUSIVE_MIN: "betweenExclusiveMin",
|
|
30
|
+
BETWEEN_EXCLUSIVE_MAX: "betweenExclusiveMax",
|
|
31
|
+
BETWEEN_EXCLUSIVE_MINMAX: "betweenExclusiveMinMax",
|
|
32
|
+
REGEXP: "regexp",
|
|
33
|
+
REQUIRED: "required",
|
|
34
|
+
VALIDATOR: "validator",
|
|
35
|
+
} as const;
|
|
36
|
+
|
|
37
|
+
export const FIELD_PREFIX = "dff"; // daracl form field
|
|
38
|
+
|
|
39
|
+
export const RENDER_TEMPLATE: any = {
|
|
40
|
+
number: NumberRender,
|
|
41
|
+
textarea: TextAreaRender,
|
|
42
|
+
dropdown: DropdownRender,
|
|
43
|
+
checkbox: CheckboxRender,
|
|
44
|
+
radio: RadioRender,
|
|
45
|
+
text: TextRender,
|
|
46
|
+
password: PasswordRender,
|
|
47
|
+
file: FileRender,
|
|
48
|
+
custom: CustomRender,
|
|
49
|
+
group: GroupRender,
|
|
50
|
+
hidden: HiddenRender,
|
|
51
|
+
button: ButtonRender,
|
|
52
|
+
range: RangeRender,
|
|
53
|
+
datehour: DateRender,
|
|
54
|
+
datemonth: DateRender,
|
|
55
|
+
date: DateRender,
|
|
56
|
+
datetime: DateRender,
|
|
57
|
+
tab: TabRender,
|
|
58
|
+
grid: GridRender,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const ALIGN = {
|
|
62
|
+
left: "left",
|
|
63
|
+
center: "center",
|
|
64
|
+
right: "right",
|
|
65
|
+
} as const;
|
|
66
|
+
|
|
67
|
+
export type TEXT_ALIGN_TYPE = (typeof ALIGN)[keyof typeof ALIGN];
|
|
68
|
+
|
|
69
|
+
export type RENDER_TYPE = "number" | "text" | "file" | "textarea" | "dropdown" | "radio" | "checkbox" | "date" | "datetime" | "dateyear" | "datemonth" | "datehour" | "group" | "custom";
|
|
70
|
+
|
|
71
|
+
export type REGEXP_TYPE = "email" | "url" | "alpha" | "alpha-num";
|
|
72
|
+
|
|
73
|
+
export type PASSWORD_TYPE = "number" | "upper" | "upper-special" | "upper-special-number"; // 숫자 | 대문자 포함, 대문자 특수문자 포함, 대문자 특수문자 숫자
|
|
74
|
+
|
|
75
|
+
export type FIELD_POSITION = "top" | "left" | "left-left" | "left-right" | "right" | "right-left" | "right-right" | "bottom";
|
|
76
|
+
|
|
77
|
+
export type ORIENTATION_TYPE = "horizontal" | "vertical";
|
|
78
|
+
|
|
79
|
+
interface StringArrayMap {
|
|
80
|
+
[key: string]: string[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const FIELD_POSITION_STYLE: StringArrayMap = {
|
|
84
|
+
"top-left": ["top", "txt-left"],
|
|
85
|
+
"top-center": ["top", "txt-center"],
|
|
86
|
+
"top-right": ["top", "txt-right"],
|
|
87
|
+
"left-left": ["", "txt-left"],
|
|
88
|
+
"left-center": ["", "txt-center"],
|
|
89
|
+
"left-right": ["", "txt-right"],
|
|
90
|
+
"right-right": ["right", "txt-right"],
|
|
91
|
+
"right-center": ["right", "txt-center"],
|
|
92
|
+
"right-left": ["right", "txt-left"],
|
|
93
|
+
"bottom-left": ["bottom", "txt-left"],
|
|
94
|
+
"bottom-center": ["bottom", "txt-center"],
|
|
95
|
+
"bottom-right": ["bottom", "txt-right"],
|
|
96
|
+
};
|
|
97
|
+
FIELD_POSITION_STYLE["top"] = FIELD_POSITION_STYLE["top-left"];
|
|
98
|
+
FIELD_POSITION_STYLE["right"] = FIELD_POSITION_STYLE["right-right"];
|
|
99
|
+
FIELD_POSITION_STYLE["left"] = FIELD_POSITION_STYLE["left-left"];
|
|
100
|
+
FIELD_POSITION_STYLE["bottom"] = FIELD_POSITION_STYLE["bottom-left"];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FormField } from "@t/FormField";
|
|
2
|
+
import Render from "src/renderer/Render";
|
|
3
|
+
import * as utils from "src/util/utils";
|
|
4
|
+
|
|
5
|
+
export const inputEvent = (field: FormField, element: Element, renderInfo: Render) => {
|
|
6
|
+
element.addEventListener("input", (e: Event) => {
|
|
7
|
+
customChangeEventCall(field, e, renderInfo, renderInfo.getValue());
|
|
8
|
+
renderInfo.valid();
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const numberInputEvent = (field: FormField, element: HTMLInputElement, renderInfo: Render) => {
|
|
13
|
+
element.addEventListener("keyup", (e: any) => {
|
|
14
|
+
const val = e.target.value;
|
|
15
|
+
|
|
16
|
+
if (!utils.isNumber(val)) {
|
|
17
|
+
element.value = val.replace(/[^0-9\.\-\+]/g, "");
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
}
|
|
20
|
+
customChangeEventCall(field, e, renderInfo, renderInfo.getValue());
|
|
21
|
+
renderInfo.valid();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
element.addEventListener('input', (e: any) => {
|
|
26
|
+
customChangeEventCall(field, e, renderInfo);
|
|
27
|
+
renderInfo.valid();
|
|
28
|
+
})
|
|
29
|
+
*/
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const dropdownChangeEvent = (field: FormField, element: Element, renderInfo: Render) => {
|
|
33
|
+
element.addEventListener("change", (e: any) => {
|
|
34
|
+
customChangeEventCall(field, e, renderInfo, renderInfo.getValue());
|
|
35
|
+
renderInfo.valid();
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const customChangeEventCall = (field: FormField, e: Event, renderInfo: Render, value: any) => {
|
|
40
|
+
renderInfo.changeEventCall(field, e, renderInfo, value);
|
|
41
|
+
};
|