@daracl/form 0.0.3 → 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 +67 -33
- 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 +20 -8
- package/dist/index.cjs.map +2 -2
- package/dist/index.css.map +2 -2
- package/dist/index.js +20 -8
- 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,239 @@
|
|
|
1
|
+
import { FileInfo, FormField } from "@t/FormField";
|
|
2
|
+
import Render from "./Render";
|
|
3
|
+
import { resetRowElementStyleClass, invalidMessage } from "src/util/validUtils";
|
|
4
|
+
import { fileValidator } from "src/rule/fileValidator";
|
|
5
|
+
import Lanauage from "src/util/Lanauage";
|
|
6
|
+
import { customChangeEventCall } from "src/event/renderEvents";
|
|
7
|
+
import DaraForm from "src/DaraForm";
|
|
8
|
+
import * as utils from "src/util/utils";
|
|
9
|
+
|
|
10
|
+
export default class FileRender extends Render {
|
|
11
|
+
private element: HTMLInputElement;
|
|
12
|
+
private removeIds: any[] = [];
|
|
13
|
+
private uploadFiles: any = {};
|
|
14
|
+
private fileList: any[] = [];
|
|
15
|
+
private fileSeq = 0;
|
|
16
|
+
|
|
17
|
+
constructor(field: FormField, rowElement: HTMLElement, daraForm: DaraForm) {
|
|
18
|
+
super(daraForm, field, rowElement);
|
|
19
|
+
|
|
20
|
+
this.element = rowElement.querySelector(`[name="${field.$xssName}"]`) as HTMLInputElement;
|
|
21
|
+
this.fileList = field.listItem?.list || [];
|
|
22
|
+
this.mounted();
|
|
23
|
+
this.setDefaultOption();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
mounted() {
|
|
27
|
+
this.element.addEventListener("change", (e: Event) => {
|
|
28
|
+
const files = (e.target as HTMLInputElement)?.files;
|
|
29
|
+
|
|
30
|
+
if (files) {
|
|
31
|
+
let fileList = [];
|
|
32
|
+
for (let item of files) {
|
|
33
|
+
fileList.push(item);
|
|
34
|
+
}
|
|
35
|
+
this.addFiles(fileList);
|
|
36
|
+
}
|
|
37
|
+
customChangeEventCall(this.field, e, this, this.fileList);
|
|
38
|
+
this.valid();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this.fileList.forEach((file) => {
|
|
42
|
+
file.$seq = this.fileSeq += 1;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.setFileList(this.fileList);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
createField() {
|
|
49
|
+
const field = this.field;
|
|
50
|
+
|
|
51
|
+
const fieldContainerElement = this.rowElement.querySelector(".df-field-container") as HTMLElement;
|
|
52
|
+
|
|
53
|
+
fieldContainerElement.innerHTML = `
|
|
54
|
+
<div class="df-field">
|
|
55
|
+
<span class="file-wrapper">
|
|
56
|
+
<label class="file-label">
|
|
57
|
+
<input type="file" name="${field.$xssName}" class="form-field file" multiple />
|
|
58
|
+
${Lanauage.getMessage("fileButton")}
|
|
59
|
+
</label>
|
|
60
|
+
<i class="daracl-icon help-icon"></i>
|
|
61
|
+
</span>
|
|
62
|
+
</div>
|
|
63
|
+
${Render.getDescriptionTemplate(field)}
|
|
64
|
+
<div class="daracl-file-list"></div>
|
|
65
|
+
<div class="help-message"></div>
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
this.element = fieldContainerElement.querySelector(`[name="${field.$xssName}"]`) as HTMLInputElement;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
addFiles(files: any[]) {
|
|
72
|
+
let addFlag = false;
|
|
73
|
+
|
|
74
|
+
const newFiles: FileInfo[] = [];
|
|
75
|
+
|
|
76
|
+
for (let item of files) {
|
|
77
|
+
const fileCheckList = this.fileList.filter((fileItem) => fileItem.fileName == item.name && fileItem.fileSize == item.size && fileItem.lastModified == item.lastModified);
|
|
78
|
+
|
|
79
|
+
if (fileCheckList.length > 0) continue;
|
|
80
|
+
this.fileSeq += 1;
|
|
81
|
+
this.uploadFiles[this.fileSeq] = item;
|
|
82
|
+
|
|
83
|
+
let newFileInfo = {
|
|
84
|
+
fileName: item.name,
|
|
85
|
+
$seq: this.fileSeq,
|
|
86
|
+
fileSize: item.size,
|
|
87
|
+
lastModified: item.lastModified,
|
|
88
|
+
} as FileInfo;
|
|
89
|
+
|
|
90
|
+
newFiles.push(newFileInfo);
|
|
91
|
+
addFlag = true;
|
|
92
|
+
}
|
|
93
|
+
if (addFlag) {
|
|
94
|
+
this.setFileList(newFiles);
|
|
95
|
+
this.fileList.push(...newFiles);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private setFileList(fileList: FileInfo[], initFlag?: boolean | undefined) {
|
|
100
|
+
const fileListElement = this.rowElement.querySelector(".daracl-file-list");
|
|
101
|
+
|
|
102
|
+
if (fileListElement) {
|
|
103
|
+
if (initFlag === true) {
|
|
104
|
+
fileListElement.innerHTML = "";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const fileTemplateHtml: string[] = [];
|
|
108
|
+
|
|
109
|
+
fileList.forEach((file) => {
|
|
110
|
+
fileTemplateHtml.push(`
|
|
111
|
+
<div class="file-item" data-seq="${file.$seq}">
|
|
112
|
+
${file.fileId ? '<span class="file-icon download"></span>' : '<span class="file-icon"></span>'} <span class="file-icon remove"></span>
|
|
113
|
+
<span class="file-name">${file.fileName}</span >
|
|
114
|
+
</div>`);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
fileListElement.insertAdjacentHTML("beforeend", fileTemplateHtml.join(""));
|
|
118
|
+
|
|
119
|
+
fileList.forEach((item) => {
|
|
120
|
+
this.removeFileEvent(item, fileListElement);
|
|
121
|
+
this.downloadFileEvent(item, fileListElement);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 파일 다운로드 이벤트 처리.
|
|
128
|
+
*
|
|
129
|
+
* @param item
|
|
130
|
+
* @param fileListElement
|
|
131
|
+
*/
|
|
132
|
+
private downloadFileEvent(item: FileInfo, fileListElement: Element) {
|
|
133
|
+
const ele = fileListElement.querySelector(`[data-seq="${item.$seq}"] .download`);
|
|
134
|
+
if (ele) {
|
|
135
|
+
ele.addEventListener("click", (evt: Event) => {
|
|
136
|
+
const fileItemElement = (evt.target as Element).closest(".file-item");
|
|
137
|
+
|
|
138
|
+
if (fileItemElement) {
|
|
139
|
+
const attrSeq = fileItemElement.getAttribute("data-seq");
|
|
140
|
+
if (attrSeq) {
|
|
141
|
+
const seq = parseInt(attrSeq, 10);
|
|
142
|
+
const idx = this.fileList.findIndex((v) => v.$seq === seq);
|
|
143
|
+
|
|
144
|
+
const item = this.fileList[idx];
|
|
145
|
+
|
|
146
|
+
if (item["url"]) {
|
|
147
|
+
location.href = item["url"];
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (this.field.fileDownload) {
|
|
152
|
+
this.field.fileDownload.call(null, { file: item, field: this.field });
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 파일 삭제 처리.
|
|
163
|
+
*
|
|
164
|
+
* @param item
|
|
165
|
+
* @param fileListElement
|
|
166
|
+
*/
|
|
167
|
+
private removeFileEvent(item: FileInfo, fileListElement: Element) {
|
|
168
|
+
const ele = fileListElement.querySelector(`[data-seq="${item.$seq}"] .remove`);
|
|
169
|
+
if (ele) {
|
|
170
|
+
ele.addEventListener("click", (evt: Event) => {
|
|
171
|
+
const fileItemElement = (evt.target as Element).closest(".file-item");
|
|
172
|
+
|
|
173
|
+
if (fileItemElement) {
|
|
174
|
+
const attrSeq = fileItemElement.getAttribute("data-seq");
|
|
175
|
+
if (attrSeq) {
|
|
176
|
+
const seq = parseInt(attrSeq, 10);
|
|
177
|
+
const removeIdx = this.fileList.findIndex((v) => v.$seq === seq);
|
|
178
|
+
|
|
179
|
+
const removeItem = this.fileList[removeIdx];
|
|
180
|
+
|
|
181
|
+
this.fileList.splice(removeIdx, 1);
|
|
182
|
+
delete this.uploadFiles[seq];
|
|
183
|
+
fileItemElement.remove();
|
|
184
|
+
|
|
185
|
+
if (removeItem.fileId) {
|
|
186
|
+
this.removeIds.push(removeItem.fileId);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
this.valid();
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
getValue() {
|
|
196
|
+
return {
|
|
197
|
+
uploadFile: Object.values(this.uploadFiles),
|
|
198
|
+
removeIds: this.removeIds,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public setValueItems(value: any): void {
|
|
203
|
+
this.fileList = [];
|
|
204
|
+
this.uploadFiles = [];
|
|
205
|
+
this.removeIds = [];
|
|
206
|
+
for (let file of value) {
|
|
207
|
+
file.$seq = this.fileSeq += 1;
|
|
208
|
+
|
|
209
|
+
this.fileList.push(file);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
this.setFileList(this.fileList, true);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
setValue(value: any): void {
|
|
216
|
+
if (utils.isArray(value)) {
|
|
217
|
+
this.setValueItems(value);
|
|
218
|
+
}
|
|
219
|
+
this.element.value = "";
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
reset() {
|
|
223
|
+
this.setValue("");
|
|
224
|
+
this.setValueItems([]);
|
|
225
|
+
resetRowElementStyleClass(this.rowElement);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
getElement(): HTMLInputElement {
|
|
229
|
+
return this.element;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
valid(): any {
|
|
233
|
+
const validResult = fileValidator(this.element, this.field, this.fileList);
|
|
234
|
+
|
|
235
|
+
invalidMessage(this.field, this.rowElement, validResult);
|
|
236
|
+
|
|
237
|
+
return validResult;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { FieldStyle, FormField } from "@t/FormField";
|
|
2
|
+
import Render from "./Render";
|
|
3
|
+
import { invalidMessage, resetRowElementStyleClass } from "src/util/validUtils";
|
|
4
|
+
import DaraForm from "src/DaraForm";
|
|
5
|
+
import * as utils from "src/util/utils";
|
|
6
|
+
import { stringValidator } from "src/rule/stringValidator";
|
|
7
|
+
import styleUtils from "src/util/styleUtils";
|
|
8
|
+
import FormTemplate from "src/FormTemplate";
|
|
9
|
+
import { FormOptions } from "@t/FormOptions";
|
|
10
|
+
import { NumberKeyMap } from "@t/DataMap";
|
|
11
|
+
|
|
12
|
+
let $$idx = 0;
|
|
13
|
+
|
|
14
|
+
export default class GridRender extends Render {
|
|
15
|
+
private customFunction;
|
|
16
|
+
private gridForm;
|
|
17
|
+
private allAddRowInfo = {} as NumberKeyMap;
|
|
18
|
+
|
|
19
|
+
constructor(field: FormField, rowElement: HTMLElement, daraForm: DaraForm) {
|
|
20
|
+
super(daraForm, field, rowElement);
|
|
21
|
+
|
|
22
|
+
if (field.renderer) {
|
|
23
|
+
this.customFunction = field.renderer;
|
|
24
|
+
} else {
|
|
25
|
+
this.customFunction = {} as any;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const gridFormOptions = {
|
|
29
|
+
style: {
|
|
30
|
+
width: "100%",
|
|
31
|
+
labelWidth: 3,
|
|
32
|
+
valueWidth: 9,
|
|
33
|
+
position: "left-right",
|
|
34
|
+
},
|
|
35
|
+
autoCreate: false,
|
|
36
|
+
notValidMessage: "This form is not valid.",
|
|
37
|
+
fields: [],
|
|
38
|
+
} as FormOptions;
|
|
39
|
+
|
|
40
|
+
this.gridForm = new DaraForm(document.createElement("div"), gridFormOptions);
|
|
41
|
+
|
|
42
|
+
this.mounted();
|
|
43
|
+
this.setDefaultOption();
|
|
44
|
+
this.setDefaultInfo();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
mounted() {
|
|
48
|
+
this.addRow();
|
|
49
|
+
|
|
50
|
+
if (this.customFunction.mounted) {
|
|
51
|
+
(this.customFunction.mounted as any).call(this, this.field, this.rowElement);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.rowElement.querySelector(".df-grid-add-row-btn")?.addEventListener("click", (evt) => {
|
|
55
|
+
this.addRow();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static isDataRender(): boolean {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static isChildrenCreate(): boolean {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
createField() {
|
|
68
|
+
const field = this.field;
|
|
69
|
+
|
|
70
|
+
const fieldContainerElement = this.rowElement.querySelector(".df-field-container") as HTMLElement;
|
|
71
|
+
|
|
72
|
+
let theadTemplate = [];
|
|
73
|
+
let colgroupTemplate = [];
|
|
74
|
+
let addBtnTemplate = [];
|
|
75
|
+
addBtnTemplate.push("");
|
|
76
|
+
|
|
77
|
+
if (field.children) {
|
|
78
|
+
colgroupTemplate.push("<colgroup>");
|
|
79
|
+
|
|
80
|
+
theadTemplate.push("<tr>");
|
|
81
|
+
|
|
82
|
+
colgroupTemplate.push(`<col style="width:38px">`);
|
|
83
|
+
theadTemplate.push("<th>");
|
|
84
|
+
if (field.gridOptions?.disableAddButton !== true) {
|
|
85
|
+
theadTemplate.push(`<button type="button" class="df-btn df-grid-add-row-btn" title="Add"><i class="df-icon df-add-icon"></i></button>`);
|
|
86
|
+
}
|
|
87
|
+
theadTemplate.push("</th>");
|
|
88
|
+
|
|
89
|
+
for (const childField of field.children) {
|
|
90
|
+
colgroupTemplate.push(`<col style="width:${childField.style?.width ?? "*"}">`);
|
|
91
|
+
theadTemplate.push(`<th class="df-grid-header">${childField.label}</th>`);
|
|
92
|
+
}
|
|
93
|
+
colgroupTemplate.push("</colgroup>");
|
|
94
|
+
theadTemplate.push("</tr>");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
fieldContainerElement.innerHTML = `
|
|
98
|
+
<div class="df-grid-field">
|
|
99
|
+
${addBtnTemplate.join("")}
|
|
100
|
+
<div class="df-grid-container ${field.style?.position ?? ""}" style="height:${field.gridOptions?.height ?? "auto"};">
|
|
101
|
+
<table class="df-grid">${colgroupTemplate.join("")}<thead>${theadTemplate.join("")}</thead><tbody></tbody></table>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* add row
|
|
109
|
+
*/
|
|
110
|
+
addRow(valueItem?: any): void {
|
|
111
|
+
let rowTemplate = [];
|
|
112
|
+
|
|
113
|
+
const options = this.daraForm.getOptions();
|
|
114
|
+
const formTemplate = this.gridForm.formTemplate;
|
|
115
|
+
const parentName = this.field.$xssName;
|
|
116
|
+
|
|
117
|
+
++$$idx;
|
|
118
|
+
let addColumns = [];
|
|
119
|
+
rowTemplate.push(`<tr class="grid-row">`);
|
|
120
|
+
|
|
121
|
+
rowTemplate.push("<td>");
|
|
122
|
+
if (this.field.gridOptions?.disableRemoveButton !== true) {
|
|
123
|
+
rowTemplate.push(`<button type="button" data-row-idx="${$$idx}" class="df-btn df-grid-row-remove"><i class="df-icon df-remove-icon"></i></button>`);
|
|
124
|
+
}
|
|
125
|
+
rowTemplate.push("</td>");
|
|
126
|
+
|
|
127
|
+
for (const childField of this.field.children) {
|
|
128
|
+
let fieldStyle: FieldStyle = styleUtils.fieldStyle(options, childField, null, true);
|
|
129
|
+
|
|
130
|
+
let columnField = utils.merge({}, childField) as FormField;
|
|
131
|
+
|
|
132
|
+
addColumns.push(columnField);
|
|
133
|
+
columnField.$orgin = childField;
|
|
134
|
+
columnField.name = columnField.name + "_" + $$idx;
|
|
135
|
+
columnField.$xssName = parentName + "_" + utils.getXssFieldName(columnField);
|
|
136
|
+
|
|
137
|
+
formTemplate.addRowFieldInfo(columnField);
|
|
138
|
+
|
|
139
|
+
rowTemplate.push(`<td id="${columnField.$xssName}"><div class="df-field-container ${columnField.required ? "required" : ""} " style="${fieldStyle.valueStyle}"></div></td>`);
|
|
140
|
+
}
|
|
141
|
+
rowTemplate.push("</tr>");
|
|
142
|
+
|
|
143
|
+
this.allAddRowInfo[$$idx] = addColumns;
|
|
144
|
+
|
|
145
|
+
const addRowElement = utils.templateToElement(rowTemplate.join(""));
|
|
146
|
+
|
|
147
|
+
if (addRowElement) {
|
|
148
|
+
this.rowElement.querySelector("tbody")?.append(addRowElement);
|
|
149
|
+
|
|
150
|
+
addRowElement.querySelector(".df-grid-row-remove")?.addEventListener("click", (evt) => {
|
|
151
|
+
this.removeRow(evt);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
valueItem = valueItem ?? {};
|
|
156
|
+
for (let columnField of addColumns) {
|
|
157
|
+
columnField.$instance = new (columnField.$renderType as any)(columnField, addRowElement?.querySelector(`#${columnField.$xssName}`), this.gridForm);
|
|
158
|
+
|
|
159
|
+
if (valueItem[columnField.$orgin.name]) {
|
|
160
|
+
columnField.$instance.setValue(valueItem[columnField.$orgin.name]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* remove row
|
|
167
|
+
*
|
|
168
|
+
* @param evt event
|
|
169
|
+
*/
|
|
170
|
+
removeRow(evt: Event): void {
|
|
171
|
+
const target = evt.target as Element;
|
|
172
|
+
|
|
173
|
+
const rowElement = target.closest("tr");
|
|
174
|
+
|
|
175
|
+
if (rowElement) {
|
|
176
|
+
if (rowElement.parentElement?.childElementCount == 1) return;
|
|
177
|
+
|
|
178
|
+
let rowIdx = (evt.currentTarget as Element)?.getAttribute("data-row-idx") || "-1";
|
|
179
|
+
|
|
180
|
+
this.removeFieldInfo(rowIdx);
|
|
181
|
+
rowElement.remove();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
*
|
|
187
|
+
* @param rowIdx row index
|
|
188
|
+
*/
|
|
189
|
+
removeFieldInfo(rowIdx?: string) {
|
|
190
|
+
let removeFieldArrs = [] as any;
|
|
191
|
+
if (utils.isEmpty(rowIdx)) {
|
|
192
|
+
for (let key in this.allAddRowInfo) {
|
|
193
|
+
removeFieldArrs = removeFieldArrs.concat(this.allAddRowInfo[key]);
|
|
194
|
+
}
|
|
195
|
+
this.allAddRowInfo = {} as NumberKeyMap;
|
|
196
|
+
} else if (rowIdx) {
|
|
197
|
+
const rowIdxNum = parseInt(rowIdx, 10);
|
|
198
|
+
removeFieldArrs = removeFieldArrs.concat(this.allAddRowInfo[rowIdxNum]);
|
|
199
|
+
delete this.allAddRowInfo[rowIdxNum];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
for (let columnField of removeFieldArrs) {
|
|
203
|
+
this.gridForm.getFieldInfoMap().removeFieldInfo(columnField.name);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
allRemoveRow(): void {
|
|
208
|
+
this.rowElement.querySelector("tbody")?.replaceChildren();
|
|
209
|
+
this.removeFieldInfo();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
getValue() {
|
|
213
|
+
if (this.customFunction.getValue) {
|
|
214
|
+
return (this.customFunction.getValue as any).call(this, this.field, this.rowElement);
|
|
215
|
+
}
|
|
216
|
+
let result = [];
|
|
217
|
+
const children = this.field.children;
|
|
218
|
+
const childrenLength = children.length;
|
|
219
|
+
for (let idx in this.allAddRowInfo) {
|
|
220
|
+
const rowColumns = this.allAddRowInfo[idx];
|
|
221
|
+
|
|
222
|
+
let rowInfo = {} as any;
|
|
223
|
+
for (let childIdx = 0; childIdx < childrenLength; childIdx++) {
|
|
224
|
+
let childField = children[childIdx];
|
|
225
|
+
rowInfo[childField.name] = this.gridForm.getFieldValue(rowColumns[childIdx].name); // rowColumns[childIdx].$instance.getValue();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
result.push(rowInfo);
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
setValue(value: any): void {
|
|
234
|
+
this.field.$value = value;
|
|
235
|
+
|
|
236
|
+
let valueArr: any[] = [];
|
|
237
|
+
if (Array.isArray(value)) {
|
|
238
|
+
valueArr = value;
|
|
239
|
+
} else {
|
|
240
|
+
if (utils.isPlainObject(value)) {
|
|
241
|
+
valueArr.push(value);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
this.allRemoveRow();
|
|
246
|
+
|
|
247
|
+
for (let valueItem of valueArr) {
|
|
248
|
+
this.addRow(valueItem);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
reset() {
|
|
253
|
+
this.setDefaultInfo();
|
|
254
|
+
resetRowElementStyleClass(this.rowElement);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
getElement() {
|
|
258
|
+
if (this.customFunction.getElement) {
|
|
259
|
+
return (this.customFunction.getElement as any).call(this, this.field, this.rowElement);
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
valid(): any {
|
|
265
|
+
if (this.customFunction.valid) {
|
|
266
|
+
const validResult = (this.customFunction.valid as any).call(this, this.field, this.rowElement);
|
|
267
|
+
|
|
268
|
+
invalidMessage(this.field, this.rowElement, validResult);
|
|
269
|
+
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const validResult = this.gridForm.validForm();
|
|
274
|
+
|
|
275
|
+
if (validResult.length > 0) {
|
|
276
|
+
const firstItem = validResult[0];
|
|
277
|
+
|
|
278
|
+
if (firstItem.message) {
|
|
279
|
+
firstItem.message = "[" + this.field.label + "] " + firstItem.message;
|
|
280
|
+
|
|
281
|
+
return firstItem;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
focus(): void {}
|
|
289
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { FormField } from "@t/FormField";
|
|
2
|
+
import Render from "./Render";
|
|
3
|
+
import DaraForm from "src/DaraForm";
|
|
4
|
+
|
|
5
|
+
export default class GroupRender extends Render {
|
|
6
|
+
constructor(field: FormField, rowElement: HTMLElement, daraForm: DaraForm) {
|
|
7
|
+
super(daraForm, field, rowElement);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public mounted() {}
|
|
11
|
+
|
|
12
|
+
static isDataRender(): boolean {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createField() {
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getValue() {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setValue(value: any): void {}
|
|
25
|
+
|
|
26
|
+
reset() {}
|
|
27
|
+
|
|
28
|
+
getElement(): HTMLElement {
|
|
29
|
+
return this.rowElement;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
valid(): any {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public addChildField(element: Element) {
|
|
37
|
+
let addContainer = this.rowElement.querySelector(".df-field-container");
|
|
38
|
+
|
|
39
|
+
if (addContainer) {
|
|
40
|
+
addContainer.append(element);
|
|
41
|
+
} else {
|
|
42
|
+
this.rowElement.append(element);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
focus(): void {}
|
|
47
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { FormField } from "@t/FormField";
|
|
2
|
+
import Render from "./Render";
|
|
3
|
+
import DaraForm from "src/DaraForm";
|
|
4
|
+
|
|
5
|
+
export default class HiddenRender extends Render {
|
|
6
|
+
constructor(field: FormField, rowElement: HTMLElement, daraForm: DaraForm) {
|
|
7
|
+
super(daraForm, field, rowElement);
|
|
8
|
+
this.field.$value = field.defaultValue;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
mounted() {}
|
|
12
|
+
|
|
13
|
+
createField() {
|
|
14
|
+
return ``;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
getValue() {
|
|
18
|
+
return this.field.$value;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
setValue(value: any): void {
|
|
22
|
+
this.field.$value = value;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
reset() {
|
|
26
|
+
this.setValue(this.field.defaultValue);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getElement() {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
valid(): any {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { FormField } from "@t/FormField";
|
|
2
|
+
import Render from "./Render";
|
|
3
|
+
import { numberValidator } from "src/rule/numberValidator";
|
|
4
|
+
import { resetRowElementStyleClass, invalidMessage } from "src/util/validUtils";
|
|
5
|
+
import { numberInputEvent } from "src/event/renderEvents";
|
|
6
|
+
import DaraForm from "src/DaraForm";
|
|
7
|
+
|
|
8
|
+
export default class NumberRender extends Render {
|
|
9
|
+
private element: HTMLInputElement;
|
|
10
|
+
|
|
11
|
+
constructor(field: FormField, rowElement: HTMLElement, daraForm: DaraForm) {
|
|
12
|
+
super(daraForm, field, rowElement);
|
|
13
|
+
|
|
14
|
+
this.mounted();
|
|
15
|
+
this.setDefaultOption();
|
|
16
|
+
this.setDefaultInfo();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
mounted() {
|
|
20
|
+
numberInputEvent(this.field, this.element, this);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
createField() {
|
|
24
|
+
const field = this.field;
|
|
25
|
+
|
|
26
|
+
const fieldContainerElement = this.rowElement.querySelector(".df-field-container") as HTMLElement;
|
|
27
|
+
|
|
28
|
+
fieldContainerElement.innerHTML = `
|
|
29
|
+
<div class="df-field">
|
|
30
|
+
<input type="text" name="${field.$xssName}" class="form-field number help-icon" />
|
|
31
|
+
</div>
|
|
32
|
+
${Render.getDescriptionTemplate(field)}
|
|
33
|
+
<div class="help-message"></div>
|
|
34
|
+
`;
|
|
35
|
+
this.element = fieldContainerElement.querySelector(`[name="${field.$xssName}"]`) as HTMLInputElement;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getValue() {
|
|
39
|
+
return this.element.value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
setValue(value: any, changeCheckFlag?: boolean): void {
|
|
43
|
+
if (changeCheckFlag !== false && this.changeEventCall(this.field, null, this, value) === false) {
|
|
44
|
+
this.element.value = this.field.$value;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.field.$value = value;
|
|
48
|
+
this.element.value = value;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
reset() {
|
|
52
|
+
this.setDefaultInfo();
|
|
53
|
+
this.setDisabled(false);
|
|
54
|
+
resetRowElementStyleClass(this.rowElement);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getElement(): HTMLElement {
|
|
58
|
+
return this.element;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
valid(): any {
|
|
62
|
+
const validResult = numberValidator(this.getValue(), this.field);
|
|
63
|
+
|
|
64
|
+
invalidMessage(this.field, this.rowElement, validResult);
|
|
65
|
+
|
|
66
|
+
return validResult;
|
|
67
|
+
}
|
|
68
|
+
}
|