@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,283 @@
|
|
|
1
|
+
import { FormField } from "@t/FormField";
|
|
2
|
+
|
|
3
|
+
const xssFilter = {
|
|
4
|
+
"&": "&",
|
|
5
|
+
"<": "<",
|
|
6
|
+
">": ">",
|
|
7
|
+
'"': """,
|
|
8
|
+
"'": "'",
|
|
9
|
+
} as any;
|
|
10
|
+
|
|
11
|
+
export const replaceXss = (inputText: string): string => {
|
|
12
|
+
let returnText = inputText;
|
|
13
|
+
if (returnText) {
|
|
14
|
+
Object.keys(xssFilter).forEach((key) => {
|
|
15
|
+
returnText = returnText.replaceAll(key, xssFilter[key]);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return returnText;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const hasOwnProp = (obj: any, key: string): boolean => {
|
|
22
|
+
return obj.hasOwnProperty(key);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const unReplace = (inputText: string): string => {
|
|
26
|
+
let returnText = inputText;
|
|
27
|
+
|
|
28
|
+
if (returnText) {
|
|
29
|
+
Object.keys(xssFilter).forEach((key) => {
|
|
30
|
+
returnText = returnText.replaceAll(xssFilter[key], key);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return returnText;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const unFieldName = (fieldName: string): string => {
|
|
37
|
+
if (fieldName) {
|
|
38
|
+
return unReplace(fieldName).replaceAll('"', '\\"');
|
|
39
|
+
}
|
|
40
|
+
return "";
|
|
41
|
+
};
|
|
42
|
+
export const isBlank = (value: any): boolean => {
|
|
43
|
+
if (value === null) return true;
|
|
44
|
+
if (value === "") return true;
|
|
45
|
+
if (typeof value === "undefined") return true;
|
|
46
|
+
if (typeof value === "string" && (value === "" || value.replace(/\s/g, "") === "")) return true;
|
|
47
|
+
|
|
48
|
+
return false;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const isUndefined = (value: any): value is undefined => {
|
|
52
|
+
return typeof value === "undefined";
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const isFunction = (value: any): boolean => {
|
|
56
|
+
return typeof value === "function";
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const isString = (value: any): value is string => {
|
|
60
|
+
return typeof value === "string";
|
|
61
|
+
};
|
|
62
|
+
export const isNumber = (value: any): value is number => {
|
|
63
|
+
if (isBlank(value)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
value = +value;
|
|
67
|
+
return !isNaN(value);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const isArray = (value: any): value is Array<any> => {
|
|
71
|
+
return Array.isArray(value);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 값있는지 여부 체크.
|
|
76
|
+
*
|
|
77
|
+
* @param {*} value
|
|
78
|
+
* @returns {boolean}
|
|
79
|
+
*/
|
|
80
|
+
export const isEmpty = (value: any): boolean => isUndefined(value) || value == null; //_isEmpty(value);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* tab render type check
|
|
84
|
+
*
|
|
85
|
+
* @param {FormField} field
|
|
86
|
+
* @returns {boolean} tab type 인지 여부
|
|
87
|
+
*/
|
|
88
|
+
export const isTabType = (field: FormField): boolean => {
|
|
89
|
+
return field && field.renderType === "tab";
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* grid render type check
|
|
93
|
+
*
|
|
94
|
+
* @param {FormField} field
|
|
95
|
+
* @returns {boolean} grid type 인지 여부
|
|
96
|
+
*/
|
|
97
|
+
export const isGridType = (field: FormField): boolean => {
|
|
98
|
+
return field && field.renderType === "grid";
|
|
99
|
+
};
|
|
100
|
+
export const replaceXssField = (field: FormField): FormField => {
|
|
101
|
+
field.$xssName = getXssFieldName(field);
|
|
102
|
+
|
|
103
|
+
field.label = replaceXss(field.label);
|
|
104
|
+
return field;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 값을 무시하는 필드
|
|
109
|
+
*
|
|
110
|
+
* @param field formField
|
|
111
|
+
* @returns
|
|
112
|
+
*/
|
|
113
|
+
export const ignoreValueField = (field: FormField): boolean => {
|
|
114
|
+
return isGridType(field.$parent) || isTabType(field.$parent);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* grid field name xss repalce
|
|
119
|
+
*
|
|
120
|
+
* @param {FormField} field
|
|
121
|
+
* @returns {string} replace 된 field name
|
|
122
|
+
*/
|
|
123
|
+
export const getXssFieldName = (field: FormField): string => {
|
|
124
|
+
if (isUndefined(field.$xssName)) {
|
|
125
|
+
let returnText = field.name;
|
|
126
|
+
if (returnText) {
|
|
127
|
+
Object.keys(xssFilter).forEach((key) => {
|
|
128
|
+
returnText = returnText.replaceAll(key, "_");
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return "df_" + returnText;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return field.$xssName;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const getHashCode = (str: string) => {
|
|
139
|
+
let hash = 0;
|
|
140
|
+
if (str.length == 0) return hash;
|
|
141
|
+
for (let i = 0; i < str.length; i++) {
|
|
142
|
+
let tmpChar = str.charCodeAt(i);
|
|
143
|
+
hash = (hash << 5) - hash + tmpChar;
|
|
144
|
+
hash = hash & hash;
|
|
145
|
+
}
|
|
146
|
+
return String(hash).replaceAll(/-/g, "_");
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const isHiddenField = (field: FormField): boolean => {
|
|
150
|
+
if (field.renderType === "hidden") {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const templateToElement = (htmlTemplate: string): Element | null => {
|
|
157
|
+
const template = document.createElement("template");
|
|
158
|
+
template.innerHTML = htmlTemplate;
|
|
159
|
+
return template.content.firstElementChild;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export function isPlainObject(obj: any) {
|
|
163
|
+
// 객체가 아닌 경우 또는 null인 경우 false 반환
|
|
164
|
+
if (typeof obj !== "object" || obj === null) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 프로토타입 체인을 따라 Object 생성자를 찾음
|
|
169
|
+
let proto = obj;
|
|
170
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
171
|
+
proto = Object.getPrototypeOf(proto);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Object 생성자의 prototype과 같으면 Plain Object로 판단
|
|
175
|
+
return Object.getPrototypeOf(obj) === proto;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function isObject(value: any) {
|
|
179
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function isDate(value: any) {
|
|
183
|
+
return value instanceof Date && !isNaN(value.valueOf());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* object merge
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
```
|
|
191
|
+
merge({},{aaa:'bbb',ccc:'ddd'},{bbb:'bbb','aaa':'aaa'})) -> {"aaa": "aaa", "bbb": "bbb", "ccc": "ddd"}
|
|
192
|
+
```
|
|
193
|
+
* @param {...any[]} value
|
|
194
|
+
* @returns {object}
|
|
195
|
+
*/
|
|
196
|
+
export const merge = (...value: any[]): any => {
|
|
197
|
+
let reval = value[0];
|
|
198
|
+
|
|
199
|
+
if (!isPlainObject(reval) || isEmpty(reval)) {
|
|
200
|
+
return reval;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
let i = 1;
|
|
204
|
+
if (Object.keys(reval).length > 0) {
|
|
205
|
+
i = 0;
|
|
206
|
+
reval = isArray(reval) ? [] : {};
|
|
207
|
+
}
|
|
208
|
+
const argLen = value.length;
|
|
209
|
+
for (; i < argLen; i += 1) {
|
|
210
|
+
cloneDeep(reval, value[i]);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return reval;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
function trim(s: string): string {
|
|
217
|
+
return s.replace(/^\s+|\s+$/g, "");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function cloneDeep(dst: any, src: any): any {
|
|
221
|
+
if (isObject(src)) {
|
|
222
|
+
return cloneObjectDeep(dst, src);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (isArray(src)) {
|
|
226
|
+
return cloneArrayDeep(dst, src);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (isDate(src)) {
|
|
230
|
+
return new src.constructor(src);
|
|
231
|
+
}
|
|
232
|
+
return src;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/*eslint no-param-reassign: "error"*/
|
|
236
|
+
function cloneObjectDeep(dst: any, src: any): object {
|
|
237
|
+
if (isFunction(src)) {
|
|
238
|
+
return src;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
for (const key of Object.keys(src)) {
|
|
242
|
+
const val = (src as any)[key];
|
|
243
|
+
|
|
244
|
+
if (isUndefined(val)) {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (val === null) {
|
|
249
|
+
dst[key] = val;
|
|
250
|
+
} else if (isFunction(val)) {
|
|
251
|
+
dst[key] = val;
|
|
252
|
+
} else if (isEmpty(dst[key])) {
|
|
253
|
+
dst[key] = cloneDeep(isArray(val) ? [] : {}, val);
|
|
254
|
+
} else if (!isObject(val)) {
|
|
255
|
+
dst[key] = val;
|
|
256
|
+
} else {
|
|
257
|
+
cloneDeep(dst[key], val);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return dst;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function cloneArrayDeep(dst: any, src: any[]) {
|
|
264
|
+
const isObj = isPlainObject(dst);
|
|
265
|
+
|
|
266
|
+
for (let i = 0; i < src.length; i += 1) {
|
|
267
|
+
const val = src[i];
|
|
268
|
+
let newVal;
|
|
269
|
+
|
|
270
|
+
if (val == null) {
|
|
271
|
+
newVal = val;
|
|
272
|
+
} else {
|
|
273
|
+
newVal = cloneDeep(isArray(val) ? [] : {}, val);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (isObj) {
|
|
277
|
+
(dst as any)[i] = newVal;
|
|
278
|
+
} else {
|
|
279
|
+
dst.push(newVal);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return dst;
|
|
283
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { FormField } from "@t/FormField";
|
|
2
|
+
import { ValidResult } from "@t/ValidResult";
|
|
3
|
+
import Lanauage from "./Lanauage";
|
|
4
|
+
|
|
5
|
+
export const invalidMessage = (field: FormField, rowElement: Element, validResult: ValidResult | boolean) => {
|
|
6
|
+
if (validResult === true) {
|
|
7
|
+
rowElement.classList.remove("invalid");
|
|
8
|
+
|
|
9
|
+
if (!rowElement.classList.contains("valid")) {
|
|
10
|
+
rowElement.classList.add("valid");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const helpMessageElement = rowElement.querySelector(".help-message");
|
|
14
|
+
if (helpMessageElement) {
|
|
15
|
+
helpMessageElement.innerHTML = "";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
rowElement.classList.remove("valid");
|
|
22
|
+
|
|
23
|
+
if (!rowElement.classList.contains("invalid")) {
|
|
24
|
+
rowElement.classList.add("invalid");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (validResult !== false) {
|
|
28
|
+
const message: string[] = Lanauage.validMessage(field, validResult);
|
|
29
|
+
|
|
30
|
+
if (validResult.message) {
|
|
31
|
+
message.push(validResult.message);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const helpMessageElement = rowElement.querySelector(".help-message");
|
|
35
|
+
if (helpMessageElement && message.length > 0) {
|
|
36
|
+
const msgHtml: string[] = [];
|
|
37
|
+
message.forEach((item) => {
|
|
38
|
+
msgHtml.push(`<div>${item}</div>`);
|
|
39
|
+
});
|
|
40
|
+
helpMessageElement.innerHTML = msgHtml.join("");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* remove row element style class
|
|
47
|
+
*
|
|
48
|
+
* @param {Element} rowElement
|
|
49
|
+
*/
|
|
50
|
+
export const resetRowElementStyleClass = (rowElement: Element) => {
|
|
51
|
+
rowElement.classList.remove("invalid");
|
|
52
|
+
rowElement.classList.remove("valid");
|
|
53
|
+
};
|
package/style/daracl.form.scss
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
@use "sass:list";
|
|
1
2
|
$sizes: 8.33333333%, 16.66666667%, 25%, 33.33333333%, 41.66666667%, 50%, 58.33333333%, 66.66666667%, 75%, 83.33333333%, 91.66666667%, 100%;
|
|
2
3
|
|
|
3
4
|
@mixin rowFlex() {
|
|
@@ -263,7 +264,7 @@ body.dark .daracl-form,
|
|
|
263
264
|
}
|
|
264
265
|
|
|
265
266
|
@each $size in $sizes {
|
|
266
|
-
$i: index($sizes, $size);
|
|
267
|
+
$i: list.index($sizes, $size);
|
|
267
268
|
$className: ".col-xs-#{$i}";
|
|
268
269
|
#{$className} {
|
|
269
270
|
flex-basis: $size;
|