Vuelidate example
by duleorlovic
HTML
<script src="https://unpkg.com/vuelidate/dist/vuelidate.min.js"></script>
<script src="https://unpkg.com/vuelidate/dist/validators.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.min.js"></script>
<div id="app">
On client-side we have "required" validation and age between 20 and 30<br>
Simulated server promise returns error if name length or age is odd.<br>
Note that server errors are shown on Submit (and cleared on input update).
<form @submit.prevent="submit">
<p>
<input
type="text"
v-model="name"
v-on:input="$v.name.$touch"
v-bind:class="{'error-input': hasError('name')}"
>
<span
class='error-message'
v-if='hasError("name") && nameServerError === null'
>
This is a required field
</span>
<span
class='error-message'
v-if='hasError("name") && nameServerError != null'
>
Error: {{ nameServerError }}
</span>
</p>
<p>
<input
type="number"
v-model="age"
v-on:input="$v.age.$touch"
v-bind:class="{error: hasError('age')}"
>
<span
class='error-message'
v-if='hasError("age") && ageServerError === null'
>
Age must be between 20 and 30
</span>
<span
class='error-message'
v-if='hasError("age") && age != null'
>
Error: {{ ageServerError }}
</span>
</p>
<p>
<button type='submit'>
Submit
</button>
<span v-if='showLoader'>waiting for server response...</span>
</p>
</form>
<pre>{{ $v }}</pre>
</div>
CSS
.error-input {
border-color: red;
}
.error-message {
color: red;
}
Babel + JSX
Vue.use(window.vuelidate.default)
const { required, between} = window.validators
const validateFromServer = fieldName => function() {
if (this.validationPromise) {
// until we get response, serverSaidOK will be false, but validation will
// not be triggered untill this promise is resolved or rejected
return this.validationPromise
// return true to mark success validation in case we successfully get
// result (otherwise, validateFromServer will return null in this case)
.then(() => true)
.catch(response => {
// return false in case there is an http error and data.errors for
// fieldName exists
if (response.errors[fieldName] === undefined) {
console.log(`validateFromServer ${fieldName} true ${JSON.stringify(response)}`)
return true
} else {
const fieldNameForServerError = fieldName + 'ServerError'
this[fieldNameForServerError] = response.errors[fieldName].join()
console.log(`validateFromServer ${fieldName} = ${this[fieldNameForServerError]}`)
return false
}
})
.finally(() => {
this.showLoader = false
})
} else {
console.log(`validateFromServer ${fieldName} true because validationPromise is null`)
return true
}
}
const simulateServerErrorsPromise = function(name, age) {
return new Promise((resolutitonFunc, rejectionFunc) => {
setTimeout(() => {
if (name.length % 2 == 0 && age % 2 == 0) {
const successResponse = {
message: `name='${name}' length is even and age=${age} is even`
}
resolutitonFunc(successResponse)
} else {
var errorResponse
if (name.length % 2 != 0 && age % 2 == 0) {
errorResponse = {
errors: {
name: [`name='${name}' length is NOT even`]
}
}
} else if (name.length % 2 == 0 && age % 2 != 0) {
errorResponse = {
errors: {
...