UNPKG

alpidate

Version:

A model-based validation plugin for Alpine.js, inspired by Vuelidate.

1 lines 3.53 kB
function createValidationWatcher(data) { for (let model in data.validations) { let chain = model.split('.'); data.$watch(model, () => { data.validate(model); }) let parentModel = data.$v; chain.forEach(upperModel => { if (parentModel[upperModel] === undefined) { parentModel[upperModel] = {}; } if (parentModel[upperModel] !== undefined) { parentModel = parentModel[upperModel]; } }) let modelInDeep = parentModel; data.validations[model].forEach(rule => { rule = rule.split(':'); modelInDeep[rule[0]] = null; }) } return data; } export default function (Alpine) { Alpine.magic('validation', () => data => { data.$v = {}; data.$v.$touch = false; data.validate = (modelName = null) => { let error = false; let message = ''; let models = []; if (modelName == null) { data.$v.$touch = true; models = Object.keys(data.validations); } else { models = [modelName]; } models.forEach(model => { let rules = data.validations[model]; if (typeof rules === 'string') { rules = [rules]; } let currentVModel = data.$v; let currentModel = data; model.split('.').forEach(upperModel => { if (currentVModel[upperModel] !== undefined) { currentVModel = currentVModel[upperModel]; currentModel = currentModel[upperModel]; } }) currentVModel.$invalid = false; rules.forEach(rule => { rule = rule.split(':'); switch (rule[0]) { case 'required': error = currentModel === null || currentModel === "" || !currentModel; break; case 'numeric': error = isNaN(currentModel) break; case 'email': error = !(/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(currentModel)) break; case 'regex': if (!rule[1]) { error = true; break; } let regex = new RegExp(rule[1]) error = !(regex.test(currentModel)) break; case 'min': if (!rule[1]) { error = true; break; } error = currentModel.length < rule[1] break; case 'max': if (!rule[1]) { error = true; break; } error = currentModel.length > rule[1] break; } if (!currentVModel.$invalid) { currentVModel.$invalid = error; } currentVModel[rule[0]] = error; }) }) } data.$v.reset = () => { data.$v.$touch = false; } data.$v.$invalid = true; data = createValidationWatcher(data); data.$watch('$v', () => { let inValid = false; for (let model of Object.keys(data.validations)) { let modelInDeep = data.$v; model.split('.').forEach(upperModel => { if (modelInDeep[upperModel] !== undefined) { modelInDeep = modelInDeep[upperModel]; } }) for (let validation of Object.keys(modelInDeep)) { inValid = modelInDeep[validation] || modelInDeep[validation] === null; if (inValid) break; } if (inValid) break; } data.$v.$invalid = inValid; }) }) }