@coherent.js/forms 1.0.0-beta.8 → 1.0.0-rc.1
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/form-builder.js +0 -5
- package/dist/form-builder.js.map +2 -2
- package/dist/index.js +14 -617
- package/dist/index.js.map +4 -4
- package/package.json +5 -7
- package/types/index.d.ts +3 -50
- package/dist/advanced-validation.js +0 -523
- package/dist/advanced-validation.js.map +0 -7
- package/dist/forms.js +0 -432
- package/dist/forms.js.map +0 -7
|
@@ -1,523 +0,0 @@
|
|
|
1
|
-
// src/advanced-validation.js
|
|
2
|
-
import { ReactiveState, observable, computed } from "@coherent.js/state/src/reactive-state.js";
|
|
3
|
-
import { globalErrorHandler } from "@coherent.js/core/src/utils/error-handler.js";
|
|
4
|
-
var validationRules = {
|
|
5
|
-
required: (value, params = true) => {
|
|
6
|
-
if (!params) return true;
|
|
7
|
-
const isEmpty = value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
|
|
8
|
-
return !isEmpty || "This field is required";
|
|
9
|
-
},
|
|
10
|
-
min: (value, minValue) => {
|
|
11
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
12
|
-
const num = Number(value);
|
|
13
|
-
return isNaN(num) || num >= minValue || `Value must be at least ${minValue}`;
|
|
14
|
-
},
|
|
15
|
-
max: (value, maxValue) => {
|
|
16
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
17
|
-
const num = Number(value);
|
|
18
|
-
return isNaN(num) || num <= maxValue || `Value must be no more than ${maxValue}`;
|
|
19
|
-
},
|
|
20
|
-
minLength: (value, minLen) => {
|
|
21
|
-
if (value === null || value === void 0) return true;
|
|
22
|
-
const str = String(value);
|
|
23
|
-
return str.length >= minLen || `Must be at least ${minLen} characters`;
|
|
24
|
-
},
|
|
25
|
-
maxLength: (value, maxLen) => {
|
|
26
|
-
if (value === null || value === void 0) return true;
|
|
27
|
-
const str = String(value);
|
|
28
|
-
return str.length <= maxLen || `Must be no more than ${maxLen} characters`;
|
|
29
|
-
},
|
|
30
|
-
pattern: (value, regex, message = "Invalid format") => {
|
|
31
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
32
|
-
const pattern = typeof regex === "string" ? new RegExp(regex) : regex;
|
|
33
|
-
return pattern.test(String(value)) || message;
|
|
34
|
-
},
|
|
35
|
-
email: (value) => {
|
|
36
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
37
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
38
|
-
return emailRegex.test(String(value)) || "Please enter a valid email address";
|
|
39
|
-
},
|
|
40
|
-
url: (value) => {
|
|
41
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
42
|
-
try {
|
|
43
|
-
new URL(String(value));
|
|
44
|
-
return true;
|
|
45
|
-
} catch {
|
|
46
|
-
return "Please enter a valid URL";
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
numeric: (value) => {
|
|
50
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
51
|
-
return !isNaN(Number(value)) || "Must be a valid number";
|
|
52
|
-
},
|
|
53
|
-
integer: (value) => {
|
|
54
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
55
|
-
const num = Number(value);
|
|
56
|
-
return Number.isInteger(num) || "Must be a whole number";
|
|
57
|
-
},
|
|
58
|
-
alpha: (value) => {
|
|
59
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
60
|
-
return /^[a-zA-Z]+$/.test(String(value)) || "Must contain only letters";
|
|
61
|
-
},
|
|
62
|
-
alphanumeric: (value) => {
|
|
63
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
64
|
-
return /^[a-zA-Z0-9]+$/.test(String(value)) || "Must contain only letters and numbers";
|
|
65
|
-
},
|
|
66
|
-
equals: (value, otherValue, fieldName = "other field") => {
|
|
67
|
-
return value === otherValue || `Must match ${fieldName}`;
|
|
68
|
-
},
|
|
69
|
-
oneOf: (value, options, message = "Invalid selection") => {
|
|
70
|
-
if (value === null || value === void 0 || value === "") return true;
|
|
71
|
-
return options.includes(value) || message;
|
|
72
|
-
},
|
|
73
|
-
custom: (value, validator, ...args) => {
|
|
74
|
-
if (typeof validator !== "function") {
|
|
75
|
-
throw new Error("Custom validator must be a function");
|
|
76
|
-
}
|
|
77
|
-
return validator(value, ...args);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
var FieldValidator = class {
|
|
81
|
-
constructor(name, rules = {}, options = {}) {
|
|
82
|
-
this.name = name;
|
|
83
|
-
this.rules = rules;
|
|
84
|
-
this.options = {
|
|
85
|
-
validateOnChange: options.validateOnChange !== false,
|
|
86
|
-
validateOnBlur: options.validateOnBlur !== false,
|
|
87
|
-
debounce: options.debounce || 0,
|
|
88
|
-
...options
|
|
89
|
-
};
|
|
90
|
-
this.errors = observable([]);
|
|
91
|
-
this.isValid = computed(() => this.errors.value.length === 0);
|
|
92
|
-
this.isPending = observable(false);
|
|
93
|
-
this.isTouched = observable(false);
|
|
94
|
-
this.isDirty = observable(false);
|
|
95
|
-
this._debounceTimer = null;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Validate field value
|
|
99
|
-
*/
|
|
100
|
-
async validate(value, formData = {}) {
|
|
101
|
-
this.isPending.value = true;
|
|
102
|
-
const errors = [];
|
|
103
|
-
try {
|
|
104
|
-
for (const [ruleName, ruleParams] of Object.entries(this.rules)) {
|
|
105
|
-
const validator = validationRules[ruleName];
|
|
106
|
-
if (!validator) {
|
|
107
|
-
console.warn(`Unknown validation rule: ${ruleName}`);
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
let result;
|
|
111
|
-
if (validator.constructor.name === "AsyncFunction") {
|
|
112
|
-
result = await validator(value, ruleParams, formData);
|
|
113
|
-
} else {
|
|
114
|
-
result = validator(value, ruleParams, formData);
|
|
115
|
-
}
|
|
116
|
-
if (result !== true) {
|
|
117
|
-
errors.push(typeof result === "string" ? result : `Invalid ${this.name}`);
|
|
118
|
-
if (!this.options.validateAll) {
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
} catch (_error) {
|
|
124
|
-
globalErrorHandler.handle(_error, {
|
|
125
|
-
type: "validation-_error",
|
|
126
|
-
context: { field: this.name, value, rules: this.rules }
|
|
127
|
-
});
|
|
128
|
-
errors.push("Validation _error occurred");
|
|
129
|
-
} finally {
|
|
130
|
-
this.isPending.value = false;
|
|
131
|
-
}
|
|
132
|
-
this.errors.value = errors;
|
|
133
|
-
return this.isValid.value;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Validate with debouncing
|
|
137
|
-
*/
|
|
138
|
-
validateDebounced(value, formData = {}) {
|
|
139
|
-
if (this.options.debounce <= 0) {
|
|
140
|
-
return this.validate(value, formData);
|
|
141
|
-
}
|
|
142
|
-
return new Promise((resolve) => {
|
|
143
|
-
if (this._debounceTimer) {
|
|
144
|
-
clearTimeout(this._debounceTimer);
|
|
145
|
-
}
|
|
146
|
-
this._debounceTimer = setTimeout(async () => {
|
|
147
|
-
const result = await this.validate(value, formData);
|
|
148
|
-
resolve(result);
|
|
149
|
-
}, this.options.debounce);
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Mark field as touched
|
|
154
|
-
*/
|
|
155
|
-
touch() {
|
|
156
|
-
this.isTouched.value = true;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Mark field as dirty
|
|
160
|
-
*/
|
|
161
|
-
dirty() {
|
|
162
|
-
this.isDirty.value = true;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Reset field state
|
|
166
|
-
*/
|
|
167
|
-
reset() {
|
|
168
|
-
this.errors.value = [];
|
|
169
|
-
this.isTouched.value = false;
|
|
170
|
-
this.isDirty.value = false;
|
|
171
|
-
this.isPending.value = false;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Get field state
|
|
175
|
-
*/
|
|
176
|
-
getState() {
|
|
177
|
-
return {
|
|
178
|
-
errors: this.errors.value,
|
|
179
|
-
isValid: this.isValid.value,
|
|
180
|
-
isPending: this.isPending.value,
|
|
181
|
-
isTouched: this.isTouched.value,
|
|
182
|
-
isDirty: this.isDirty.value,
|
|
183
|
-
hasError: this.errors.value.length > 0
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
var FormValidator = class {
|
|
188
|
-
constructor(schema = {}, options = {}) {
|
|
189
|
-
this.schema = schema;
|
|
190
|
-
this.options = {
|
|
191
|
-
validateOnSubmit: options.validateOnSubmit !== false,
|
|
192
|
-
validateOnChange: options.validateOnChange !== false,
|
|
193
|
-
stopOnFirstError: options.stopOnFirstError !== false,
|
|
194
|
-
...options
|
|
195
|
-
};
|
|
196
|
-
this.data = new ReactiveState();
|
|
197
|
-
this.validators = /* @__PURE__ */ new Map();
|
|
198
|
-
this.isSubmitting = observable(false);
|
|
199
|
-
this.submitCount = observable(0);
|
|
200
|
-
this.initializeValidators();
|
|
201
|
-
this.isValid = computed(() => {
|
|
202
|
-
return Array.from(this.validators.values()).every((validator) => validator.isValid.value);
|
|
203
|
-
});
|
|
204
|
-
this.isPending = computed(() => {
|
|
205
|
-
return Array.from(this.validators.values()).some((validator) => validator.isPending.value);
|
|
206
|
-
});
|
|
207
|
-
this.isTouched = computed(() => {
|
|
208
|
-
return Array.from(this.validators.values()).some((validator) => validator.isTouched.value);
|
|
209
|
-
});
|
|
210
|
-
this.isDirty = computed(() => {
|
|
211
|
-
return Array.from(this.validators.values()).some((validator) => validator.isDirty.value);
|
|
212
|
-
});
|
|
213
|
-
this.errors = computed(() => {
|
|
214
|
-
const allErrors = {};
|
|
215
|
-
for (const [name, validator] of this.validators.entries()) {
|
|
216
|
-
if (validator.errors.value.length > 0) {
|
|
217
|
-
allErrors[name] = validator.errors.value;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return allErrors;
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Initialize field validators from schema
|
|
225
|
-
*/
|
|
226
|
-
initializeValidators() {
|
|
227
|
-
for (const [fieldName, fieldSchema] of Object.entries(this.schema)) {
|
|
228
|
-
const rules = fieldSchema.rules || fieldSchema;
|
|
229
|
-
const options = fieldSchema.options || {};
|
|
230
|
-
this.validators.set(fieldName, new FieldValidator(fieldName, rules, options));
|
|
231
|
-
this.data.set(fieldName, fieldSchema.default || "");
|
|
232
|
-
if (this.options.validateOnChange) {
|
|
233
|
-
this.data.watch(fieldName, (newValue) => {
|
|
234
|
-
const validator = this.validators.get(fieldName);
|
|
235
|
-
validator.dirty();
|
|
236
|
-
if (validator.options.validateOnChange) {
|
|
237
|
-
validator.validateDebounced(newValue, this.data.toObject());
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Set field value
|
|
245
|
-
*/
|
|
246
|
-
setField(name, value) {
|
|
247
|
-
this.data.set(name, value);
|
|
248
|
-
const validator = this.validators.get(name);
|
|
249
|
-
if (validator) {
|
|
250
|
-
validator.dirty();
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Get field value
|
|
255
|
-
*/
|
|
256
|
-
getField(name) {
|
|
257
|
-
return this.data.get(name);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Set multiple fields
|
|
261
|
-
*/
|
|
262
|
-
setFields(fields) {
|
|
263
|
-
this.data.batch(fields);
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Get all form data
|
|
267
|
-
*/
|
|
268
|
-
getData() {
|
|
269
|
-
return this.data.toObject();
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Validate specific field
|
|
273
|
-
*/
|
|
274
|
-
async validateField(name) {
|
|
275
|
-
const validator = this.validators.get(name);
|
|
276
|
-
if (!validator) {
|
|
277
|
-
console.warn(`No validator found for field: ${name}`);
|
|
278
|
-
return true;
|
|
279
|
-
}
|
|
280
|
-
const value = this.data.get(name);
|
|
281
|
-
return validator.validate(value, this.data.toObject());
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Validate all fields
|
|
285
|
-
*/
|
|
286
|
-
async validateAll() {
|
|
287
|
-
const validationPromises = [];
|
|
288
|
-
for (const [name, validator] of this.validators.entries()) {
|
|
289
|
-
const value = this.data.get(name);
|
|
290
|
-
validationPromises.push(validator.validate(value, this.data.toObject()));
|
|
291
|
-
}
|
|
292
|
-
const results = await Promise.all(validationPromises);
|
|
293
|
-
return results.every((result) => result === true);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Handle field blur event
|
|
297
|
-
*/
|
|
298
|
-
handleBlur(name) {
|
|
299
|
-
const validator = this.validators.get(name);
|
|
300
|
-
if (validator) {
|
|
301
|
-
validator.touch();
|
|
302
|
-
if (validator.options.validateOnBlur) {
|
|
303
|
-
const value = this.data.get(name);
|
|
304
|
-
validator.validate(value, this.data.toObject());
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Handle form submission
|
|
310
|
-
*/
|
|
311
|
-
async handleSubmit(submitHandler) {
|
|
312
|
-
if (this.isSubmitting.value) {
|
|
313
|
-
return false;
|
|
314
|
-
}
|
|
315
|
-
this.isSubmitting.value = true;
|
|
316
|
-
this.submitCount.value += 1;
|
|
317
|
-
try {
|
|
318
|
-
for (const validator of this.validators.values()) {
|
|
319
|
-
validator.touch();
|
|
320
|
-
}
|
|
321
|
-
let isValid = true;
|
|
322
|
-
if (this.options.validateOnSubmit) {
|
|
323
|
-
isValid = await this.validateAll();
|
|
324
|
-
}
|
|
325
|
-
if (!isValid) {
|
|
326
|
-
return false;
|
|
327
|
-
}
|
|
328
|
-
if (typeof submitHandler === "function") {
|
|
329
|
-
const result = await submitHandler(this.getData(), this);
|
|
330
|
-
return result !== false;
|
|
331
|
-
}
|
|
332
|
-
return true;
|
|
333
|
-
} catch (_error) {
|
|
334
|
-
globalErrorHandler.handle(_error, {
|
|
335
|
-
type: "form-submit-_error",
|
|
336
|
-
context: { formData: this.getData() }
|
|
337
|
-
});
|
|
338
|
-
return false;
|
|
339
|
-
} finally {
|
|
340
|
-
this.isSubmitting.value = false;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Reset form to initial state
|
|
345
|
-
*/
|
|
346
|
-
reset() {
|
|
347
|
-
for (const [fieldName, fieldSchema] of Object.entries(this.schema)) {
|
|
348
|
-
this.data.set(fieldName, fieldSchema.default || "");
|
|
349
|
-
}
|
|
350
|
-
for (const validator of this.validators.values()) {
|
|
351
|
-
validator.reset();
|
|
352
|
-
}
|
|
353
|
-
this.submitCount.value = 0;
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Add custom validator
|
|
357
|
-
*/
|
|
358
|
-
addValidator(name, rules, options = {}) {
|
|
359
|
-
this.validators.set(name, new FieldValidator(name, rules, options));
|
|
360
|
-
if (!this.data.has(name)) {
|
|
361
|
-
this.data.set(name, "");
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Remove validator
|
|
366
|
-
*/
|
|
367
|
-
removeValidator(name) {
|
|
368
|
-
this.validators.delete(name);
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* Get field validator
|
|
372
|
-
*/
|
|
373
|
-
getValidator(name) {
|
|
374
|
-
return this.validators.get(name);
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* Get form state summary
|
|
378
|
-
*/
|
|
379
|
-
getState() {
|
|
380
|
-
return {
|
|
381
|
-
isValid: this.isValid.value,
|
|
382
|
-
isPending: this.isPending.value,
|
|
383
|
-
isTouched: this.isTouched.value,
|
|
384
|
-
isDirty: this.isDirty.value,
|
|
385
|
-
isSubmitting: this.isSubmitting.value,
|
|
386
|
-
submitCount: this.submitCount.value,
|
|
387
|
-
errors: this.errors.value,
|
|
388
|
-
data: this.getData()
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Watch form state changes
|
|
393
|
-
*/
|
|
394
|
-
watch(callback, options = {}) {
|
|
395
|
-
const unsubscribers = [];
|
|
396
|
-
if (options.watchValid !== false) {
|
|
397
|
-
unsubscribers.push(this.isValid.watch(callback));
|
|
398
|
-
}
|
|
399
|
-
if (options.watchPending !== false) {
|
|
400
|
-
unsubscribers.push(this.isPending.watch(callback));
|
|
401
|
-
}
|
|
402
|
-
if (options.watchErrors !== false) {
|
|
403
|
-
unsubscribers.push(this.errors.watch(callback));
|
|
404
|
-
}
|
|
405
|
-
return () => {
|
|
406
|
-
unsubscribers.forEach((unsub) => unsub());
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Cleanup form
|
|
411
|
-
*/
|
|
412
|
-
destroy() {
|
|
413
|
-
this.data.destroy();
|
|
414
|
-
this.validators.clear();
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
function createForm(schema, options = {}) {
|
|
418
|
-
return new FormValidator(schema, options);
|
|
419
|
-
}
|
|
420
|
-
var binding = {
|
|
421
|
-
/**
|
|
422
|
-
* Two-way data binding for input elements
|
|
423
|
-
*/
|
|
424
|
-
model(form, fieldName, options = {}) {
|
|
425
|
-
return {
|
|
426
|
-
value: form.getField(fieldName),
|
|
427
|
-
oninput: (event) => {
|
|
428
|
-
const value = options.number ? Number(event.target.value) : event.target.value;
|
|
429
|
-
form.setField(fieldName, value);
|
|
430
|
-
},
|
|
431
|
-
onblur: () => {
|
|
432
|
-
form.handleBlur(fieldName);
|
|
433
|
-
}
|
|
434
|
-
};
|
|
435
|
-
},
|
|
436
|
-
/**
|
|
437
|
-
* Checkbox binding
|
|
438
|
-
*/
|
|
439
|
-
checkbox(form, fieldName) {
|
|
440
|
-
return {
|
|
441
|
-
checked: Boolean(form.getField(fieldName)),
|
|
442
|
-
onchange: (event) => {
|
|
443
|
-
form.setField(fieldName, event.target.checked);
|
|
444
|
-
},
|
|
445
|
-
onblur: () => {
|
|
446
|
-
form.handleBlur(fieldName);
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
},
|
|
450
|
-
/**
|
|
451
|
-
* Select dropdown binding
|
|
452
|
-
*/
|
|
453
|
-
select(form, fieldName, options = {}) {
|
|
454
|
-
return {
|
|
455
|
-
value: form.getField(fieldName),
|
|
456
|
-
onchange: (event) => {
|
|
457
|
-
const value = options.multiple ? Array.from(event.target.selectedOptions, (opt) => opt.value) : event.target.value;
|
|
458
|
-
form.setField(fieldName, value);
|
|
459
|
-
},
|
|
460
|
-
onblur: () => {
|
|
461
|
-
form.handleBlur(fieldName);
|
|
462
|
-
}
|
|
463
|
-
};
|
|
464
|
-
},
|
|
465
|
-
/**
|
|
466
|
-
* Radio button binding
|
|
467
|
-
*/
|
|
468
|
-
radio(form, fieldName, value) {
|
|
469
|
-
return {
|
|
470
|
-
checked: form.getField(fieldName) === value,
|
|
471
|
-
value,
|
|
472
|
-
onchange: (event) => {
|
|
473
|
-
if (event.target.checked) {
|
|
474
|
-
form.setField(fieldName, value);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
};
|
|
480
|
-
var formComponents = {
|
|
481
|
-
/**
|
|
482
|
-
* Validation _error display
|
|
483
|
-
*/
|
|
484
|
-
ValidationError({ form, field, className = "validation-_error" }) {
|
|
485
|
-
const validator = form.getValidator(field);
|
|
486
|
-
if (!validator || validator.errors.value.length === 0) {
|
|
487
|
-
return null;
|
|
488
|
-
}
|
|
489
|
-
return {
|
|
490
|
-
div: {
|
|
491
|
-
className,
|
|
492
|
-
children: validator.errors.value.map((_error) => ({
|
|
493
|
-
span: { text: _error, className: "_error-message" }
|
|
494
|
-
}))
|
|
495
|
-
}
|
|
496
|
-
};
|
|
497
|
-
},
|
|
498
|
-
/**
|
|
499
|
-
* Form field wrapper with validation
|
|
500
|
-
*/
|
|
501
|
-
FormField({ form, field, label, children, showErrors = true }) {
|
|
502
|
-
const validator = form.getValidator(field);
|
|
503
|
-
const state = validator ? validator.getState() : {};
|
|
504
|
-
return {
|
|
505
|
-
div: {
|
|
506
|
-
className: `form-field ${state.hasError ? "has-_error" : ""} ${state.isTouched ? "touched" : ""}`,
|
|
507
|
-
children: [
|
|
508
|
-
label ? { label: { text: label, htmlFor: field } } : null,
|
|
509
|
-
children,
|
|
510
|
-
showErrors && state.hasError ? formComponents.ValidationError({ form, field }) : null
|
|
511
|
-
].filter(Boolean)
|
|
512
|
-
}
|
|
513
|
-
};
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
export {
|
|
517
|
-
FormValidator,
|
|
518
|
-
binding,
|
|
519
|
-
createForm,
|
|
520
|
-
formComponents,
|
|
521
|
-
validationRules
|
|
522
|
-
};
|
|
523
|
-
//# sourceMappingURL=advanced-validation.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/advanced-validation.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * Form Validation and Data Binding System for Coherent.js\n * Provides comprehensive form handling with reactive validation\n */\n\nimport { ReactiveState, observable, computed } from '@coherent.js/state/src/reactive-state.js';\nimport { globalErrorHandler } from '@coherent.js/core/src/utils/error-handler.js';\n\n/**\n * Built-in validation rules\n */\nexport const validationRules = {\n required: (value, params = true) => {\n if (!params) return true;\n const isEmpty = value === null || value === undefined || value === '' ||\n (Array.isArray(value) && value.length === 0);\n return !isEmpty || 'This field is required';\n },\n\n min: (value, minValue) => {\n if (value === null || value === undefined || value === '') return true;\n const num = Number(value);\n return isNaN(num) || num >= minValue || `Value must be at least ${minValue}`;\n },\n\n max: (value, maxValue) => {\n if (value === null || value === undefined || value === '') return true;\n const num = Number(value);\n return isNaN(num) || num <= maxValue || `Value must be no more than ${maxValue}`;\n },\n\n minLength: (value, minLen) => {\n if (value === null || value === undefined) return true;\n const str = String(value);\n return str.length >= minLen || `Must be at least ${minLen} characters`;\n },\n\n maxLength: (value, maxLen) => {\n if (value === null || value === undefined) return true;\n const str = String(value);\n return str.length <= maxLen || `Must be no more than ${maxLen} characters`;\n },\n\n pattern: (value, regex, message = 'Invalid format') => {\n if (value === null || value === undefined || value === '') return true;\n const pattern = typeof regex === 'string' ? new RegExp(regex) : regex;\n return pattern.test(String(value)) || message;\n },\n\n email: (value) => {\n if (value === null || value === undefined || value === '') return true;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(String(value)) || 'Please enter a valid email address';\n },\n\n url: (value) => {\n if (value === null || value === undefined || value === '') return true;\n try {\n new URL(String(value));\n return true;\n } catch {\n return 'Please enter a valid URL';\n }\n },\n\n numeric: (value) => {\n if (value === null || value === undefined || value === '') return true;\n return !isNaN(Number(value)) || 'Must be a valid number';\n },\n\n integer: (value) => {\n if (value === null || value === undefined || value === '') return true;\n const num = Number(value);\n return Number.isInteger(num) || 'Must be a whole number';\n },\n\n alpha: (value) => {\n if (value === null || value === undefined || value === '') return true;\n return /^[a-zA-Z]+$/.test(String(value)) || 'Must contain only letters';\n },\n\n alphanumeric: (value) => {\n if (value === null || value === undefined || value === '') return true;\n return /^[a-zA-Z0-9]+$/.test(String(value)) || 'Must contain only letters and numbers';\n },\n\n equals: (value, otherValue, fieldName = 'other field') => {\n return value === otherValue || `Must match ${fieldName}`;\n },\n\n oneOf: (value, options, message = 'Invalid selection') => {\n if (value === null || value === undefined || value === '') return true;\n return options.includes(value) || message;\n },\n\n custom: (value, validator, ...args) => {\n if (typeof validator !== 'function') {\n throw new Error('Custom validator must be a function');\n }\n return validator(value, ...args);\n }\n};\n\n/**\n * Field validation class\n */\nclass FieldValidator {\n constructor(name, rules = {}, options = {}) {\n this.name = name;\n this.rules = rules;\n this.options = {\n validateOnChange: options.validateOnChange !== false,\n validateOnBlur: options.validateOnBlur !== false,\n debounce: options.debounce || 0,\n ...options\n };\n\n this.errors = observable([]);\n this.isValid = computed(() => this.errors.value.length === 0);\n this.isPending = observable(false);\n this.isTouched = observable(false);\n this.isDirty = observable(false);\n\n this._debounceTimer = null;\n }\n\n /**\n * Validate field value\n */\n async validate(value, formData = {}) {\n this.isPending.value = true;\n const errors = [];\n\n try {\n for (const [ruleName, ruleParams] of Object.entries(this.rules)) {\n const validator = validationRules[ruleName];\n\n if (!validator) {\n console.warn(`Unknown validation rule: ${ruleName}`);\n continue;\n }\n\n let result;\n\n // Handle async validators\n if (validator.constructor.name === 'AsyncFunction') {\n result = await validator(value, ruleParams, formData);\n } else {\n result = validator(value, ruleParams, formData);\n }\n\n if (result !== true) {\n errors.push(typeof result === 'string' ? result : `Invalid ${this.name}`);\n\n // Stop on first _error unless configured otherwise\n if (!this.options.validateAll) {\n break;\n }\n }\n }\n } catch (_error) {\n globalErrorHandler.handle(_error, {\n type: 'validation-_error',\n context: { field: this.name, value, rules: this.rules }\n });\n errors.push('Validation _error occurred');\n } finally {\n this.isPending.value = false;\n }\n\n this.errors.value = errors;\n return this.isValid.value;\n }\n\n /**\n * Validate with debouncing\n */\n validateDebounced(value, formData = {}) {\n if (this.options.debounce <= 0) {\n return this.validate(value, formData);\n }\n\n return new Promise((resolve) => {\n if (this._debounceTimer) {\n clearTimeout(this._debounceTimer);\n }\n\n this._debounceTimer = setTimeout(async () => {\n const result = await this.validate(value, formData);\n resolve(result);\n }, this.options.debounce);\n });\n }\n\n /**\n * Mark field as touched\n */\n touch() {\n this.isTouched.value = true;\n }\n\n /**\n * Mark field as dirty\n */\n dirty() {\n this.isDirty.value = true;\n }\n\n /**\n * Reset field state\n */\n reset() {\n this.errors.value = [];\n this.isTouched.value = false;\n this.isDirty.value = false;\n this.isPending.value = false;\n }\n\n /**\n * Get field state\n */\n getState() {\n return {\n errors: this.errors.value,\n isValid: this.isValid.value,\n isPending: this.isPending.value,\n isTouched: this.isTouched.value,\n isDirty: this.isDirty.value,\n hasError: this.errors.value.length > 0\n };\n }\n}\n\n/**\n * Form validation and binding system\n */\nexport class FormValidator {\n constructor(schema = {}, options = {}) {\n this.schema = schema;\n this.options = {\n validateOnSubmit: options.validateOnSubmit !== false,\n validateOnChange: options.validateOnChange !== false,\n stopOnFirstError: options.stopOnFirstError !== false,\n ...options\n };\n\n this.data = new ReactiveState();\n this.validators = new Map();\n this.isSubmitting = observable(false);\n this.submitCount = observable(0);\n\n // Initialize validators\n this.initializeValidators();\n\n // Computed properties for form state\n this.isValid = computed(() => {\n return Array.from(this.validators.values()).every(validator => validator.isValid.value);\n });\n\n this.isPending = computed(() => {\n return Array.from(this.validators.values()).some(validator => validator.isPending.value);\n });\n\n this.isTouched = computed(() => {\n return Array.from(this.validators.values()).some(validator => validator.isTouched.value);\n });\n\n this.isDirty = computed(() => {\n return Array.from(this.validators.values()).some(validator => validator.isDirty.value);\n });\n\n this.errors = computed(() => {\n const allErrors = {};\n for (const [name, validator] of this.validators.entries()) {\n if (validator.errors.value.length > 0) {\n allErrors[name] = validator.errors.value;\n }\n }\n return allErrors;\n });\n }\n\n /**\n * Initialize field validators from schema\n */\n initializeValidators() {\n for (const [fieldName, fieldSchema] of Object.entries(this.schema)) {\n const rules = fieldSchema.rules || fieldSchema;\n const options = fieldSchema.options || {};\n\n this.validators.set(fieldName, new FieldValidator(fieldName, rules, options));\n\n // Initialize data\n this.data.set(fieldName, fieldSchema.default || '');\n\n // Watch for changes if validation on change is enabled\n if (this.options.validateOnChange) {\n this.data.watch(fieldName, (newValue) => {\n const validator = this.validators.get(fieldName);\n validator.dirty();\n\n if (validator.options.validateOnChange) {\n validator.validateDebounced(newValue, this.data.toObject());\n }\n });\n }\n }\n }\n\n /**\n * Set field value\n */\n setField(name, value) {\n this.data.set(name, value);\n\n const validator = this.validators.get(name);\n if (validator) {\n validator.dirty();\n }\n }\n\n /**\n * Get field value\n */\n getField(name) {\n return this.data.get(name);\n }\n\n /**\n * Set multiple fields\n */\n setFields(fields) {\n this.data.batch(fields);\n }\n\n /**\n * Get all form data\n */\n getData() {\n return this.data.toObject();\n }\n\n /**\n * Validate specific field\n */\n async validateField(name) {\n const validator = this.validators.get(name);\n if (!validator) {\n console.warn(`No validator found for field: ${name}`);\n return true;\n }\n\n const value = this.data.get(name);\n return validator.validate(value, this.data.toObject());\n }\n\n /**\n * Validate all fields\n */\n async validateAll() {\n const validationPromises = [];\n\n for (const [name, validator] of this.validators.entries()) {\n const value = this.data.get(name);\n validationPromises.push(validator.validate(value, this.data.toObject()));\n }\n\n const results = await Promise.all(validationPromises);\n return results.every(result => result === true);\n }\n\n /**\n * Handle field blur event\n */\n handleBlur(name) {\n const validator = this.validators.get(name);\n if (validator) {\n validator.touch();\n\n if (validator.options.validateOnBlur) {\n const value = this.data.get(name);\n validator.validate(value, this.data.toObject());\n }\n }\n }\n\n /**\n * Handle form submission\n */\n async handleSubmit(submitHandler) {\n if (this.isSubmitting.value) {\n return false;\n }\n\n this.isSubmitting.value = true;\n this.submitCount.value += 1;\n\n try {\n // Mark all fields as touched\n for (const validator of this.validators.values()) {\n validator.touch();\n }\n\n // Validate all fields if required\n let isValid = true;\n if (this.options.validateOnSubmit) {\n isValid = await this.validateAll();\n }\n\n if (!isValid) {\n return false;\n }\n\n // Execute submit handler\n if (typeof submitHandler === 'function') {\n const result = await submitHandler(this.getData(), this);\n return result !== false;\n }\n\n return true;\n\n } catch (_error) {\n globalErrorHandler.handle(_error, {\n type: 'form-submit-_error',\n context: { formData: this.getData() }\n });\n return false;\n } finally {\n this.isSubmitting.value = false;\n }\n }\n\n /**\n * Reset form to initial state\n */\n reset() {\n // Reset data to defaults\n for (const [fieldName, fieldSchema] of Object.entries(this.schema)) {\n this.data.set(fieldName, fieldSchema.default || '');\n }\n\n // Reset validators\n for (const validator of this.validators.values()) {\n validator.reset();\n }\n\n this.submitCount.value = 0;\n }\n\n /**\n * Add custom validator\n */\n addValidator(name, rules, options = {}) {\n this.validators.set(name, new FieldValidator(name, rules, options));\n if (!this.data.has(name)) {\n this.data.set(name, '');\n }\n }\n\n /**\n * Remove validator\n */\n removeValidator(name) {\n this.validators.delete(name);\n }\n\n /**\n * Get field validator\n */\n getValidator(name) {\n return this.validators.get(name);\n }\n\n /**\n * Get form state summary\n */\n getState() {\n return {\n isValid: this.isValid.value,\n isPending: this.isPending.value,\n isTouched: this.isTouched.value,\n isDirty: this.isDirty.value,\n isSubmitting: this.isSubmitting.value,\n submitCount: this.submitCount.value,\n errors: this.errors.value,\n data: this.getData()\n };\n }\n\n /**\n * Watch form state changes\n */\n watch(callback, options = {}) {\n const unsubscribers = [];\n\n // Watch form-level computed properties\n if (options.watchValid !== false) {\n unsubscribers.push(this.isValid.watch(callback));\n }\n if (options.watchPending !== false) {\n unsubscribers.push(this.isPending.watch(callback));\n }\n if (options.watchErrors !== false) {\n unsubscribers.push(this.errors.watch(callback));\n }\n\n // Return unsubscribe function\n return () => {\n unsubscribers.forEach(unsub => unsub());\n };\n }\n\n /**\n * Cleanup form\n */\n destroy() {\n this.data.destroy();\n this.validators.clear();\n }\n}\n\n/**\n * Create form validator\n */\nexport function createForm(schema, options = {}) {\n return new FormValidator(schema, options);\n}\n\n/**\n * Data binding utilities\n */\nexport const binding = {\n /**\n * Two-way data binding for input elements\n */\n model(form, fieldName, options = {}) {\n return {\n value: form.getField(fieldName),\n oninput: (event) => {\n const value = options.number ? Number(event.target.value) : event.target.value;\n form.setField(fieldName, value);\n },\n onblur: () => {\n form.handleBlur(fieldName);\n }\n };\n },\n\n /**\n * Checkbox binding\n */\n checkbox(form, fieldName) {\n return {\n checked: Boolean(form.getField(fieldName)),\n onchange: (event) => {\n form.setField(fieldName, event.target.checked);\n },\n onblur: () => {\n form.handleBlur(fieldName);\n }\n };\n },\n\n /**\n * Select dropdown binding\n */\n select(form, fieldName, options = {}) {\n return {\n value: form.getField(fieldName),\n onchange: (event) => {\n const value = options.multiple\n ? Array.from(event.target.selectedOptions, opt => opt.value)\n : event.target.value;\n form.setField(fieldName, value);\n },\n onblur: () => {\n form.handleBlur(fieldName);\n }\n };\n },\n\n /**\n * Radio button binding\n */\n radio(form, fieldName, value) {\n return {\n checked: form.getField(fieldName) === value,\n value: value,\n onchange: (event) => {\n if (event.target.checked) {\n form.setField(fieldName, value);\n }\n }\n };\n }\n};\n\n/**\n * Form component helpers\n */\nexport const formComponents = {\n /**\n * Validation _error display\n */\n ValidationError({ form, field, className = 'validation-_error' }) {\n const validator = form.getValidator(field);\n if (!validator || validator.errors.value.length === 0) {\n return null;\n }\n\n return {\n div: {\n className,\n children: validator.errors.value.map(_error => ({\n span: { text: _error, className: '_error-message' }\n }))\n }\n };\n },\n\n /**\n * Form field wrapper with validation\n */\n FormField({ form, field, label, children, showErrors = true }) {\n const validator = form.getValidator(field);\n const state = validator ? validator.getState() : {};\n\n return {\n div: {\n className: `form-field ${state.hasError ? 'has-_error' : ''} ${state.isTouched ? 'touched' : ''}`,\n children: [\n label ? { label: { text: label, htmlFor: field } } : null,\n children,\n showErrors && state.hasError ?\n formComponents.ValidationError({ form, field }) : null\n ].filter(Boolean)\n }\n };\n }\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|