70 lines
1.5 KiB
JavaScript
70 lines
1.5 KiB
JavaScript
import { useState } from 'react';
|
|
|
|
export function useFormValidation(rules) {
|
|
const [errors, setErrors] = useState({});
|
|
|
|
const validate = (data) => {
|
|
const newErrors = {};
|
|
|
|
Object.entries(rules).forEach(([field, fieldRules]) => {
|
|
for (const rule of fieldRules) {
|
|
const error = rule(data[field], data);
|
|
if (error) {
|
|
newErrors[field] = error;
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
setErrors(newErrors);
|
|
return Object.keys(newErrors).length === 0;
|
|
};
|
|
|
|
const clearError = (field) => {
|
|
setErrors(prev => {
|
|
const next = { ...prev };
|
|
delete next[field];
|
|
return next;
|
|
});
|
|
};
|
|
|
|
const clearAllErrors = () => setErrors({});
|
|
|
|
return { errors, validate, clearError, clearAllErrors };
|
|
}
|
|
|
|
export const validators = {
|
|
required: (message = 'Pflichtfeld') => (value) => {
|
|
if (!value || (typeof value === 'string' && !value.trim())) {
|
|
return message;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
email: (message = 'Ungültige E-Mail-Adresse') => (value) => {
|
|
if (!value) return null;
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(value)) {
|
|
return message;
|
|
}
|
|
return null;
|
|
},
|
|
|
|
url: (message = 'Ungültige URL') => (value) => {
|
|
if (!value) return null;
|
|
try {
|
|
new URL(value);
|
|
return null;
|
|
} catch {
|
|
return message;
|
|
}
|
|
},
|
|
|
|
minLength: (min, message) => (value) => {
|
|
if (!value || value.length < min) {
|
|
return message || `Mindestens ${min} Zeichen`;
|
|
}
|
|
return null;
|
|
}
|
|
};
|