Skip to content

Instantly share code, notes, and snippets.

@fatihacet
Last active May 2, 2024 05:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatihacet/3f7d68bdd1922b15a7860bb54a206571 to your computer and use it in GitHub Desktop.
Save fatihacet/3f7d68bdd1922b15a7860bb54a206571 to your computer and use it in GitHub Desktop.
Generic Vue validation
new Vue({
el: '#app',
methods: {
validate() {
VueValidator(this, () => {
console.log('single input is valid');
});
}
}
})
Vue.component('user-add-form', {
methods: {
handleSubmit() {
VueValidator(this, () => {
console.log('submit to server...')
})
},
customValidationHandler(val) {
return val == 'fatihacet' ? false : true;
}
},
data() {
return {
firstName: '',
lastName: '',
username: ''
}
},
template: `
<section>
<h2>Add New User</h2>
<form @submit.prevent="handleSubmit">
<input type="text" name="firstName" placeholder="Type firstname"
ref="firstName"
v-model="firstName"
v-validations="{
target: { ref: 'firstNameErrorMessage' },
rules: [
{ rule: 'required' },
{ rule: 'max-length', value: 10, message: 'Max length for this field is 10.' },
{ rule: 'alphanumeric', message: 'Value should be alphanumeric' }
]
}"
/>
<p ref="firstNameErrorMessage"></p>
<input
ref="lastName" type="text" name="firstName" placeholder="Type lastname" v-model="lastName"
v-validations="{
target: { ref: 'lastNameErrorMessage', selector: '.foo' },
rules: [
{ rule: 'required' },
{ rule: 'max-length', value: 10, message: 'Max length for this field is 20.' },
{ rule: 'alphanumeric', message: 'Value should be alphanumeric' }
]
}"
/>
<p ref="lastNameErrorMessage" class="foo"></p>
<input ref="username" type="text" name="firstName" placeholder="Type username" v-model="username"
v-validations="{
target: { ref: 'usernameErrorMessage', selector: '.foo' },
rules: [
{ rule: 'required' },
{ rule: 'max-length', value: 10, message: 'Max length for this field is 20.' },
{ rule: 'alphanumeric', message: 'Value should be alphanumeric' },
{ rule: 'custom', handler: this.customValidationHandler }
]
}"
/>
<p ref="usernameErrorMessage" class="foo"></p>
<button type="submit">validate form</button>
</form>
<br /><br />
</section>
`
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
</head>
<body>
<div id="app">
<user-add-form></user-add-form>
<input ref="input" type="text"
v-validations="{
target: { ref: 'foo' },
rules: [
{ rule: 'required', message: 'Fill this ^^' }
]
}"
/>
<p ref="foo"></p>
<button @click="validate">validate single field</button>
</div>
</body>
</html>
Vue.directive('validations', {
inserted: (el, options) => {
el.validations = options.value;
}
});
const VueValidator = (vm, cb) => {
const refs = vm.$refs;
let isValid = true;
for (key in refs) {
const el = refs[key];
if (el.tagName === 'INPUT' && el.validations) {
const { rules, target } = el.validations;
const inputVal = el.value;
for (let i = 0, len = rules.length; i < len; i++) {
const validationRule = rules[i];
let { rule, value, message } = validationRule;
const msgPlaceholder = vm.$refs[target.ref];
msgPlaceholder.innerHTML = '';
switch (rule) {
case 'required':
message = message || 'This field is required';
isValid = inputVal.length > 0;
break;
case 'max-length':
message = message || 'Check field max length';
isValid = inputVal.length <= value;
break;
case 'alphanumeric':
message = message || 'This field is alphanumeric';
isValid = (/^[a-z0-9]+$/i).test(inputVal);
break;
case 'custom':
message = message || 'This field is not valid';
isValid = validationRule.handler(inputVal);
break;
}
if (!isValid && target.ref) {
msgPlaceholder.innerHTML = message;
break;
}
}
}
}
if (cb && isValid) {
cb();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment