elearning/Frontend-Learner/composables/useFormValidation.ts

92 lines
2.6 KiB
TypeScript
Raw Permalink Normal View History

2026-01-13 10:46:40 +07:00
export interface ValidationRule {
required?: boolean
minLength?: number
maxLength?: number
email?: boolean
pattern?: RegExp
match?: string
custom?: (value: string) => string | null
}
export interface FieldErrors {
[key: string]: string
}
export function useFormValidation() {
const errors = ref<FieldErrors>({})
const validateEmail = (email: string): boolean => {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return re.test(email)
}
const validateField = (value: string, rules: ValidationRule, fieldName: string, formData?: Record<string, string>, messages?: Record<string, string>): string | null => {
2026-01-13 10:46:40 +07:00
if (rules.required && !value.trim()) {
return messages?.required || `กรุณากรอก${fieldName}`
2026-01-13 10:46:40 +07:00
}
if (rules.minLength && value.length < rules.minLength) {
return messages?.minLength || `${fieldName}ต้องมีอย่างน้อย ${rules.minLength} ตัวอักษร`
2026-01-13 10:46:40 +07:00
}
if (rules.maxLength && value.length > rules.maxLength) {
return messages?.maxLength || `${fieldName}ต้องไม่เกิน ${rules.maxLength} ตัวอักษร`
2026-01-13 10:46:40 +07:00
}
if (rules.email && value && !validateEmail(value)) {
return messages?.email || 'รูปแบบอีเมลไม่ถูกต้อง'
2026-01-13 10:46:40 +07:00
}
if (rules.pattern && value && !rules.pattern.test(value)) {
return messages?.pattern || `${fieldName}รูปแบบไม่ถูกต้อง`
2026-01-13 10:46:40 +07:00
}
if (rules.match && formData && value !== formData[rules.match]) {
return messages?.match || 'รหัสผ่านไม่ตรงกัน'
2026-01-13 10:46:40 +07:00
}
if (rules.custom) {
return rules.custom(value)
}
return null
}
const validate = (
formData: Record<string, string>,
validationRules: Record<string, { rules: ValidationRule; label: string; messages?: Record<string, string> }>
2026-01-13 10:46:40 +07:00
): boolean => {
const newErrors: FieldErrors = {}
let isValid = true
for (const [fieldKey, config] of Object.entries(validationRules)) {
const error = validateField(formData[fieldKey] || '', config.rules, config.label, formData, config.messages)
2026-01-13 10:46:40 +07:00
if (error) {
newErrors[fieldKey] = error
isValid = false
}
}
errors.value = newErrors
return isValid
}
const clearErrors = () => {
errors.value = {}
}
const clearFieldError = (field: string) => {
if (errors.value[field]) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete errors.value[field]
}
}
return {
errors,
validate,
clearErrors,
clearFieldError
}
}