Giter VIP home page Giter VIP logo

vuelidate's Introduction

vuelidate

Simple, lightweight model-based validation for Vue.js 2.x & 3.0

Visit Vuelidate Docs for detailed instructions.

Sponsors

Get Form

Storyblok

Vue Mastery logo

Installation

You can use Vuelidate just by itself, but we suggest you use it along @vuelidate/validators, as it gives a nice collection of commonly used validators.

Vuelidate supports both Vue 3.0 and Vue 2.x

npm install @vuelidate/core @vuelidate/validators
# or
yarn add @vuelidate/core @vuelidate/validators

Usage with Options API

To use Vuelidate with the Options API, you just need to return an empty Vuelidate instance from setup.

Your validation state lives in the data and the rules are in validations function.

import { email, required } from '@vuelidate/validators'
import { useVuelidate } from '@vuelidate/core'

export default {
  name: 'UsersPage',
  data: () => ({
    form: {
      name: '',
      email: ''
    }
  }),
  setup: () => ({ v$: useVuelidate() }),
  validations () {
    return {
      form: {
        name: { required },
        email: { required, email }
      }
    }
  }
}

Usage with Composition API

To use Vuelidate with the Composition API, you need to provide it a state and set of validation rules, for that state.

The state can be a reactive object or a collection of refs.

import { reactive } from 'vue' // or '@vue/composition-api' in Vue 2.x
import { useVuelidate } from '@vuelidate/core'
import { email, required } from '@vuelidate/validators'

export default {
  setup () {
    const state = reactive({
      name: '',
      emailAddress: ''
    })
    const rules = {
      name: { required },
      emailAddress: { required, email }
    }

    const v$ = useVuelidate(rules, state)

    return { state, v$ }
  }
}

Providing global config to your Vuelidate instance

You can provide global configs to your Vuelidate instance using the third parameter of useVuelidate or by using the validationsConfig. These config options are used to change some core Vuelidate functionality, like $autoDirty, $lazy, $scope and more. Learn all about them in Validation Configuration.

Config with Options API

<script>
import { useVuelidate } from '@vuelidate/core'

export default {
  data () {
    return { ...state }
  },
  validations () {
    return { ...validations }
  },
  setup: () => ({ v$: useVuelidate() }),
  validationConfig: {
    $lazy: true,
  }
}
</script>

Config with Composition API

import { reactive } from 'vue' // or '@vue/composition-api' in Vue 2.x
import { useVuelidate } from '@vuelidate/core'
import { email, required } from '@vuelidate/validators'

export default {
  setup () {
    const state = reactive({})
    const rules = {}
    const v$ = useVuelidate(rules, state, { $lazy: true })

    return { state, v$ }
  }
}

The validation object, aka v$ object

interface ValidationState {
  $dirty: false, // validations will only run when $dirty is true
  $touch: Function, // call to turn the $dirty state to true
  $reset: Function, // call to turn the $dirty state to false
  $errors: [], // contains all the current errors { $message, $params, $pending, $invalid }
  $error: false, // true if validations have not passed
  $invalid: false, // as above for compatibility reasons
  // there are some other properties here, read the docs for more info
}

Validations rules are on by default

Validation in Vuelidate 2 is by default on, meaning validators are called on initialisation, but an error is considered active, only after a field is dirty, so after $touch() is called or by using $model.

If you wish to make a validation lazy, meaning it only runs validations once it a field is dirty, you can pass a { $lazy: true } property to Vuelidate. This saves extra invocations for async validators as well as makes the initial validation setup a bit more performant.

const v = useVuelidate(rules, state, { $lazy: true })

Resetting dirty state

If you wish to reset a form's $dirty state, you can do so by using the appropriately named $reset method. For example when closing a create/edit modal, you dont want the validation state to persist.

<app-modal @closed="v$.$reset()">
<!-- some inputs  -->
</app-modal>

Displaying error messages

The validation state holds useful data, like the invalid state of each property validator, along with extra properties, like an error message or extra parameters.

Error messages come out of the box with the bundled validators in @vuelidate/validators package. You can check how change those them over at the Custom Validators page

The easiest way to display errors is to use the form's top level $errors property. It is an array of validation objects, that you can iterate over.

<p
  v-for="(error, index) of v$.$errors"
  :key="index"
>
<strong>{{ error.$validator }}</strong>
<small> on property</small>
<strong>{{ error.$property }}</strong>
<small> says:</small>
<strong>{{ error.$message }}</strong>
</p>

You can also check for errors on each form property:

<p
  v-for="(error, index) of v$.name.$errors"
  :key="index"
>
<!-- Same as above -->
</p>

For more info, visit the Vuelidate Docs.

Development

To test the package run

# install dependencies
yarn install

# create bundles.
yarn build

# Create docs inside /docs package
yarn dev

# run unit tests for entire monorepo
yarn test:unit

# You can also run for same command per package

Contributors

Current

Emeriti

Here we honor past contributors who have been a major part on this project.

License

MIT

vuelidate's People

Contributors

38elements avatar a-ghorab avatar aethr avatar akryum avatar ashleyhood avatar bencodezen avatar benoitranque avatar chalkygames123 avatar cherry avatar dargmuesli avatar ddbtrmatic avatar dobromir-hristov avatar felipebohnertpaetzold avatar fl0pzz avatar florent-bouisset avatar frizi avatar hootlex avatar ivansieder avatar jacobbennett avatar javiertury avatar khorsky avatar krusen avatar mokkabonna avatar nurdism avatar pczarn avatar shawnwildermuth avatar shentao avatar sobolevn avatar timowestnosto avatar xavier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vuelidate's Issues

Debounce effect

Is it possible to add debounce effect functionality? It is little bit annoying to see red error (for example "email") after first letter was written. Or when I have async call, I don't want to call api after every single keypress. Better solution would be wait 1,2 seconds and then call async function. Really appreciate simplicity of Vuelidate!

Cascading $touch()?

I think it makes sense if $touching a child property also cascades to its parent properties?

TypeError: Cannot read property '$error' of undefined using v-bind:class

Hey,

I am having some difficulty getting this to work, not sure where I am going wrong.

main.js

import Vue from 'vue'

import router from './router'

import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)

import layout from './views/layout'

/* eslint-disable no-new */
new Vue({
  router,
  el: '#app',
  render: h => h(layout)
})

page.vue

<template>
  <div>
      <div class="form-group" :class="{ 'has-error': $v.customer.first_name.$error }">
         <label>First Name</label>
         <input v-model.trim="customer.first_name" name="first_name" type="text" class="form-control border-input" placeholder="First Name">
         <label v-if="!$v.customer.first_name.minLength" id="first_name-error" class="error" for="first_name">Their first name can only be two letters or more</label>
       </div>

       <div class="form-group" :class="{ 'has-error': $v.customer.last_name.$error }">
         <label>Last Name</label>
         <input v-model.trim="customer.last_name" name="last_name" type="text" class="form-control border-input" placeholder="Last Name">
         <label v-if="!$v.customer.last_name.minLength" id="last_name-error" class="error" for="last_name">Last name is too short</label>
       </div>
  </div>
</template>
<script>
import { required, minLength } from 'vuelidate/lib/validators'

export default {
  name: 'MyPage',
  data () {
    return {
      customer: {
        first_name: '',
        last_name: ''
      }
    }
  },
  validations: {
    customer: {
      first_name: {
        required,
        minLength: minLength(2)
      },
      last_name: {
        minLength: minLength(2)
      }
    }
  }
}

Throws this error:

TypeError: Cannot read property '$error' of undefined
    at Proxy.render (eval at <anonymous> (app.js:2550), <anonymous>:319:41)
    at VueComponent.Vue._render (eval at <anonymous> (app.js:656), <anonymous>:2216:22)
    at VueComponent.updateComponent (eval at <anonymous> (app.js:656), <anonymous>:2609:21)
    at Watcher.get (eval at <anonymous> (app.js:656), <anonymous>:2934:27)
    at new Watcher (eval at <anonymous> (app.js:656), <anonymous>:2926:12)
    at VueComponent.Vue._mount (eval at <anonymous> (app.js:656), <anonymous>:2608:19)
    at VueComponent.Vue$3.$mount (eval at <anonymous> (app.js:656), <anonymous>:6178:15)
    at VueComponent.Vue$3.$mount (eval at <anonymous> (app.js:656), <anonymous>:8549:16)
    at init (eval at <anonymous> (app.js:656), <anonymous>:1740:11)
    at eval (eval at <anonymous> (app.js:656), <anonymous>:1894:5)

What am I missing?

Custom validators

As described in documents, the second argument of the custom validators would be the vm instance.

But it is not, in my case:

export function uniqueEmailValidator (value, context) {
  console.log(value)
  console.log(context)
}


export default {
    data () {
      return {
        credentials: {
          email: '',
          password: '',
          repeatPassword: ''
        },
        api: new APIClient(this, '/apiv1/members')
      }
    },
    validations: {
      credentials: {
        email: {
          required,          
          uniqueEMail: uniqueEmailValidator
        },
        password: {
          required,
          minLength: minLength(6),
          maxLength: maxLength(16)
        },
        repeatPassword: {
          sameAsPassword: sameAs('password')
        }
      }
    },

The actual value of the context is:

credentials: {
  email: '',
  password: '',
  repeatPassword: ''
}        

Validation state of overall form

I really like your idea of implementing validation as a mixing instead of configuring it with vue directives in the tempaltes, as most others do.

But one question: I want the "Save" button in my forms to be deactivated until the whole form, ie all fields in the form, become valid. How would I query for this "overall validity" in your library?

Do I need to create a 'validation group' for the whole form? Shouldn't there be a global $isValid boolean in the returned $v ?

Behaviour of $dirty

Hey,

I have been using vuelidate and loving it. Having experienced using vue-validate before I appreciated being able to detect $error, $dirty and so on. However I would like to suggest the behaviour to be more inline with vue-validate in that

Update $dirty when the value has been modified from it's initial state at least once
Add $touched for when the value has been $v.foo.$touch()
Add $modified for when the value is not the same as the initial value

Also when $v.foo.touch and the it becomes $dirty (or $error etc) the top level $v.$dirty etc should be updated as well.

Is this possible?

Don't works with components

Hi,

I've test your library with the vue-material form components. And the validators don't works with it.

This is my code :

<template>
    <div class="panel-form alone">
        <form class="gform">
            <div class="form-content">
                <fieldset>
                    <legend>Informations globales</legend>
                    <div class="container-fluid">
                        <div class="row">
                            <div class="col m6 s12">
                                <md-input-container :class="{ 'md-input-invalid' : $v.user.firstname.$error }">
                                    <label>Prénom</label>
                                    <md-input v-model="user.firstname" @input.native="$v.user.firstname.$touch()"></md-input>
                                    <span class="md-error" v-if="$v.user.firstname.$error">Une erreur est survenue</span>
                                </md-input-container>
                            </div>
                            <div class="col m6 s12">
                                <md-input-container :class="{ 'md-input-invalid' : $v.user.lastname.$error }">
                                    <label>Nom</label>
                                    <md-input v-model="user.lastname" @input="$v.user.lastname.$touch()"></md-input>
                                    <span class="md-error" v-if="$v.user.lastname.$error">Une erreur est survenue</span>
                                </md-input-container>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col m6 s12">
                                <md-input-container>
                                    <label>Job</label>
                                    <md-input v-model="user.job"></md-input>
                                </md-input-container>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col m12">
                                <md-input-container>
                                    <label>Adresse</label>
                                    <md-textarea v-model="user.address"></md-textarea>
                                </md-input-container>
                            </div>
                        </div>
                    </div>
                </fieldset>
            </div>
            <div class="form-validate btn-control-bar">
                <btn-form v-on:click.native.prevent="closePanel">Annuler</btn-form>
                <btn-form v-on:click.native.prevent="saveElement" color="teal">Valider</btn-form>
            </div>
        </form>
    </div>
</template>

<script>
    import clone                            from 'lodash/clone';
    import isEmpty                          from 'lodash/isEmpty';
    import store                            from '../../../store/store';
    import BtnForm                          from '../../goomeo/buttons/btnForm.vue';
    import { validationMixin }              from 'vuelidate';
    import { required, minLength }          from 'vuelidate/lib/validators';

    export default {
        store,
        mixins      : [
            validationMixin
        ],
        name        : 'user-form',
        components  : {
            BtnForm
        },
        data() {
            let refUser = this.$store.getters.selectedUser;

            return {
                user    : clone(refUser),
                isNew   : isEmpty(refUser)
            };
        },
        methods : {
            closePanel() {
                this.$parent.close();
            },
            saveElement() {
                console.log(this.$v);
                return;

                if (this.isNew === true) {
                    this.$store.commit('addUser', this.user); // remplacer par trigger si vous voulez faire un traitement asynchrone (envoi à une API)
                    this.$parent.close();
                } else {
                    this.$store.dispatch('updateUser', this.user).then(() => {
                        this.$parent.close();
                    });
                }
            }
        },
        validations : {
            user : {
                firstname : {
                    required
                },
                lastname : {
                    required
                },
                job : {
                    required
                }
            }
        }
    };
</script>

I test the @input with and without the .native option and the result is the same, your validators are not called on the input event. I test with the blur event too but the result is the same. The blur is never called.

Thanks

[feature request]Simplify validation API

import { required, minLength, between } from 'vuelidate/lib/validators'

export default {
  data () {
    return {
      name: '',
      age: 0
    }
  },
  validations: {
    name: {
      required,
      minLength: minLength(4)
    },
    age: {
      between: between(20, 30)
    }
  }
}

Why not just:

export default {
  data () {
    return {
      name: '',
      age: 0
    }
  },
  validations: {
    name: {
      required: true,
      minLength: 4
    },
    age: {
      between: [20, 30]
    }
  }
}

Support multiple validation triggers

From what I can tell there are no options to control when a validation is triggered and the out of the box implementation is to fire on each key press. There are pro's and con's to this and it would be good to see some alternatives.

A great article that looks at this issue is at https://uxdesign.cc/forms-need-validation-2ecbccbacea1 with the trigger specific content at https://uxdesign.cc/forms-need-validation-2ecbccbacea1#e661

I like the idea of using several triggers that will fire validation if any trigger is hit.

  • After x milliseconds from the first keypress
  • After a configured number of keys entered for a field
  • When field onblur fired
  • On key press when previously valid but now invalid

Add $success value which is the opposite of $error

It's easy enough to calculate the value, but it would be cool if it was already computed.

Use case:

If there is a requirement to display the validity of input whether its valid or invalid; additional logic needs to be written to determine whether the value is dirty and valid:

<template>
  <input v-model="value" :class="{ success, error: $v.value.$error }" />
</template>

...
computed: {
  valid() {
    return this.$v.value.$dirty ? !this.$v.value.$invalid : null
  },
  success() {
    return this.valid === true
  },
},

Whereas if it were computed for us:

<template>
  <input v-model="value :class="{ success: $v.value.$success, $v.error: value.$error }" />
</template>

An example where it could be useful would be for a password strength validator - $success would indicate that the password is strong enough.

I'd love to submit a pull request if this is a viable enhancement.

Automatic $touch()

Could you include an option to automatically run validators on any change? As I unserstand I need to add an something like @change="$v.email.$touch()" to every input I have and this kind of kills the mood. Should be optional obviously, but it's also a nobrainer that it would be useful in many cases. Thanks.

email validator

email validator should return true for null, undefined and empty values.

Validations on collections with dynamic elements

What i have is basically a collection of objects. There are inputs with v-model associated to those objects' properties and a button for removing an object from the array. Think of this as a list of contacts.

What the issue refers to specifically is: that when an element is removed from the array (which it's done with splice) the validations of the items left, get messed up. It seems like it stops tracking the items and even after retrying with several other ways, it's still the same.

Some of the solutions that i've tried are:

  • Using v-bind:key in the template
  • Using $trackBy with a key consisting in a random generated pseudoId for each element in the array
  • Instead of using splice for removing the element, replacing the whole array
  • Using $reset
  • Combinations of all the options from above

I've noticed that even if i used the $trackBy option and "printed" the $v object, the key for each object in the collection still corresponds to the item's index in the array.

I'll put some example code below.
Forgive me if there's something wrong with it, i'm writing it from memory, but i hope you get the point

<div v-for="(person, index) in people">
    <input type="text" v-model="person.firstName" />
    <input type="text" v-model="person.email" />
    <span class="error" v-if="$v.people[index].firstName.$invalid">Email is required</span>
    <button v-on:click="remove(index)>Remove</button>
</div>
{
    validations : {
        people : {
            $each : {
                email :  {
                    required : function(email, person) {
                          return (person.firstName && email) || email;
                    }
                }
            }
        }
    },
    data : {
        people : [{     // initialize as empty for showing the empty inputs 
             firstName : "",
             email : ""
        }]
    },
    methods : {
        add : function() {
            this.people.add({
                 firstName : "",
                 email : ""
            })
        },

        remove : function(index) {
            if (this.people.length === 1 ) { 
                this.people.splice(0, 1, {
                     firstName : "",
                     email : ""
                });
            } else {
                this.people.splice(index, 1);
            }
        }
    }
}

Cannot add plugin with browser bundle

Says 'Cannot read property 'installed' of undefined'.

Also how do you add custom validations at runtime? It's not described in the documentation.

btw, excellent idea, i was looking for a validation library that works on models as well.

sameAs validator

sameAs validator should NOT return true for null, undefined and empty values, instead it should return true if they are both null, undefined or empty.

Dirty flag propagation

Using touch on nested field does not propagate to top level dirty flag unless all nested fields are dirty.

In my opinion, setting dirty on a nested field should set dirty for all parents.

It can be tested on https://monterail.github.io/vuelidate/#sub-data-nesting

form$dirty is true if both nestedA.$dirty and nestedB.$dirty are true.

This is true for flat data too. All fields should be dirty in order the top level dirty flag turns dirty.

Validations for arrays

users = []

validations: {
  name: {
    required,
    minLength: minLength(4)
  },
  'form.nestedB': {
    required
  },
  users: {
    minLength: minLength(2),
    $each: {
      hasFields: hasFields(['id', 'name', 'email']),
      email: {
        isEmail,
        sameAs: sameAs('form.nestedB')
      },
    }
  },
  form: {
    nestedA: {
      required
    }
    nestedB: {
      required
    }
  },
  validationGroup: ['form.nestedA', 'form.nestedB', 'name']
}

About computed properties

Hello,

I am currently having problems with computed property validation.

Versions are listed below.

  • "vue": "^2.1.8",
  • "vuelidate": "^0.2.0",

I have 2 types of validations, local params (data) & computed properties via components props.

  • First screen, initial view of component. Both same.

  • After filling fields, whole $v object behaves differently.

Here is my validation property

validations: {
    test: {required}, // data
    user: { // computed and nested
      Name: {
        required
      }
    }
  },

And both fields have touch on input

<div class="form-group">
  <label class="col-md-3">Data</label>
  <div class="col-md-9">
    <input type="text" class="form-control" v-model="test" @input="$v.test.$touch()">
    <pre>name: {{ $v.test }}</pre>
  </div>
</div>

I used vuelidate as a mixin.

import { validationMixin } from 'vuelidate'
import { required, minLength, between } from 'vuelidate/lib/validators'

export default {
  mixins: [validationMixin],
  ...

Not sure i forgot something to add or its a bug. Any ideas?

Thanks.

Use Prop or Computed Value in Validation

I'm trying to validate an amount between 0 and some amount passed in as a prop.

validations: {
  amount: {
    required,
    between: between(0, this.allowedAmount)
  }
}

However, I'm getting Uncaught TypeError: Cannot read property 'allowedAmount' of undefined(…). Same error whether I try to use a prop or computed property.

Do I have to create my own validator in this case?

TypeError: Cannot read property 'name' of undefined

Hey,

I am also having some difficulty getting this to work, not sure where I am going wrong. Some guidance would be very much appreciated.

app.js

import Vue from 'Vue'
import Vuelidate from 'vuelidate'
import { required, alpha, email } from 'vuelidate/lib/validators'

Vue.use(Vuelidate)

new Vue({
  el: '#form',
  data: {
    name: '',
    email: '',
  },
  validations: {
    name: {
      required,
      alpha,
    },
    email: {
      required,
      email,
    },
  },
})

Here is my html

<form id="form">

<input type="text" placeholder="Name" v-model="name" name="name">
<span v-if="!$v.name.alpha">Please enter a valid name.</span>

<input type="text" placeholder="Email" v-model="email" name="email">
<span v-if="!$v.email.email">Please enter a valid email.</span>

</form>

When I try to output {{ $v }} I get nothing either.

Get validation error from child component.

I created a Google place autocomplete component. That component only has a location field. I'm using that component in several places in my site. But I'm not sure how can I get the validation error from that component in parent component.

Validations of Arrays (of strings, numbers, booleans)

Hi,

I have a little question (maybe a suggestion ?) : I've got a problem to manage an use case.
Here is my data :

data() {
  return {
    values: [
      'foo'
      'bar',
      'baz',
    ]
  }
}

And here is my validation schema :

validations : {
  values: {
    minLength: minLength(6),
    $each: true // Here is the suggestion ;)
  }
}

My template :

<div v-for="(item, index) in values">
  <input type="text" v-model="values[index]"/>
  <button @click="onRemoveItem(index)">Remove</button>
</div>
<button @click="onAddItem()">Add</button>

I can add or remove rows in my title var with some buttons.
I manage, on my own, the maximum and minimum number of rows that my title array can accept.

So, here, required and minLength validators needs to be applied on values of the array (strings), not on the array itself.

How can I do that ? I've tried lots of thing, but none work...

Obviously, I saw that issue : #2, but it seems to only works with arrays of objects (with sub fields).

Thanks for your help !

(Edit : html template added)

single prebuilt js file

Could you include a prebuilt js file containing all plugins? Just for the lazy ones who want to try it out quickly, or those that use another toolchain. Thanks a lot. Great direction.

Enter the page will automatically do a check

Hello, I am a novice just use vuelidate, I have a doubt, the use of @blur, just enter the page will automatically do a check. I would like to ask what configuration can be entered in the first page of the time do not check it.

Here is my code.

Looking forward to your reply. Thank you!!!

template

<input type="text"  v-model.trim="mobile" @blur="$v.mobile.$touch()">
<span v-if="!$v.mobile.check">mobile have problem</span>

script

export default{
        name: 'login',
        data() {
            return {
                mobile:''
            };
        },
        validations: {
            mobile: {
                check:function (value) {
                    if(!(/^1[34578]\d{9}$/.test(value))){
                        console.log('mobile have problem');
                        return false;
                    }
                    return true;
                }
            },
        },

Validation inside components

Perhaps this is a mistake on my side, but I don't know how to use validation results ($v) inside a component which has some data passed to it through comps. I would define the validation in the root app as it has all the data, but would use the results in the component. The problem is that at the time of the component initialization the $v property is not yet available as it seems, so there is no way to pass it down to the component through a props definition.

[Feature Suggestion] Error Component

Hello guys,
After #3 is implemented, an Error Component would be really cool.

It can have for, rule, and amount properties. For example:

// display the first 2 errors for 'name'
<vuelidate-error :for="name" amount="2"><vuelidate-error>

// display the error for the 'required' rule
<vuelidate-error :for="email" rule="required"><vuelidate-error>

// display the errors for a group
<vuelidate-error :for="groupOne"><vuelidate-error>

For starters, it can return a plain text in order to let devs wrap it within other tags.

<p class="text-danger">
  <vuelidate-error :for="groupOne"><vuelidate-error>
</p>

Later on, we can make it templatable but I don't know yet if this will be handy.

<vuelidate-error :for="email" template="bootstrap"><vuelidate-error>
<vuelidate-error :for="email" template="semantic"><vuelidate-error>
<vuelidate-error :for="email" template="plain"><vuelidate-error>

// or by passing 'class names'
<vuelidate-error :for="email" classes="['text-danger', 'whoops']"><vuelidate-error>

What do you think?

distinguish between validation rule and validator

A validation rule
is very abstract, like is alphanumeric,isnumber,istext,haslength and so on. They can be usefull on nearly all systems.

A Validator
Makes use of these rules combines them for a more specific usecase for example username validation.
It also contains default validation texts for each rule like "Username is required" for the rule Required and so on. Validators are more specific they usually apply to a whole system. If we would create a UserValidator for "Company A" it might only fit to this company as it can contain buisness logic, but it might be used in a lot of different services and also clients of this "Company A".

i know this is somehow possible right now but i would add more support for this pattern as i think it makes sense for a lot of systems.

More detailed:
At the moment we have a list of validation rules which we can define for a specific model variable.
for example i define a username should be required and minlength of 4:

username: {required, minLength: minLength(4)}

I would add a level of abstraction and say additionaly to these common validation rules i would like to have a validator which can use these rules:

username: userNameValidator

The UsernameValidator can be defined somewhere else. The validator should contain:
One or more Rules and also default error texts for each rule. Which can be used (but dont need to) in the validation markers for example via "$v.username.required.defaultText" to display this text. It is nice that you can define the text in vuelidate for each marker but often you want to show always the same text for the same problem.

It might also be usefull to get a list of errortext like $v.username.defaultTexts which will return all failing texts

If you need to validate a user in your system it is likely that the way how to validate a username will be equal on the whole system.

You can use this validator if you register a new username, or if you would like to write a private message to some username or if you forgot your password and need to enter username and email and so on.

These validatos can be defined externaly and can also be used on server side. To be secure that the user input arrived on my service i will check the following during register:

I will check this on client:
username syntax (alphanum,max/min length)
if this was successfull i want to call my service
the service will execute the same checks again
if all are successfull the service additionaly checks the database if the user already exist
the validation result is then returned to the client and shown to the user.

It might makes sense to allow to combine Validators for example i could create a UsernameSyntaxValidator with rules and errortexts and a UsernameDatabaseValidator which will do a call to the database it would be nice if i could combine these two.

I could than create a basic syntax validator and could derive an servervalidator which will do additionaly a check of the database and for the client i can derive from the syntax validator and do an async check to the service.

One additional thing. it might be also usefull that an i18n method can be defined. In this case the i18n function will be called to lookup the real string. For example i define as text for username required:

"username_required"; instead of "Username is required"

i than define some i18n function

i18n:function(key){
return textlookup(key);
}
this method will than be called with the validation string if defined. For one language systems where no i18n function is defined the string is simply returned like it is now. But if an i18n function is defined the text is translated to the real string.

What do you think?

Access reference models for "sameAs" validator

How can i access referenced models/names used in "sameAS"

password: { required, alphaNum, minLength: minLength(6) }, confirmPassword: { sameAs: sameAs('password') }

I want to display a generic message on validation error that "confirmPassword" must be same as "password" (how to get this name?).

Example for using or, and

I'm trying to use or validations. User need to insert either email or mobile. I could not find any example on your documentation. I'm doing this way. But can't get it working.

import { required, email, or } from 'vuelidate/lib/validators'

  validations: {
        email: {
            email,
            required,
            or: or('mobile')
        },
        mobile: {
            required,
            or: or('email')
        }
    }

Message Params

name: {
  required,
  minLength: minLength(6)
  maxLength: withMessage(maxLength, 10)
}

function withMessage (rule, ...args) {
  const wrapRule = rule(...args)
  wrapRule.messageParams = () => args
  return wrapRule
}

function required (x) {
  return !!x
}

required.messageParams (x) {
  return
}

Feature request: "require()"

E.g.

import { validationMixin } from 'vuelidate';

…is awesome!

const validationMixin = require('vuelidate');

…would also be awesome!

✌️ 😎 ✌️

Between numbers from state

Hi!

Fist of all, I really like the package, but I got stock. How is it possible to pass values from the state dinamycally to validators? (If it is possible)

What I was trying to achieve is passing min, max value to between:

Simplified example:

export default {
	data() {
		return {
			amount : 1,
			min : 100,
			max : 10000
		}
	},
	validations : {
		amount : {
			required,
			between : between(this.min, this.max)
		}
	}
}

But "this" seems to be undefined here, because I keep getting "Cannot read property 'min' of undefined" error. How could I solve this issue?

(Min and max value would change depending on other conditions)

Thanks!

How to do onSubmit validation?

I really like this way of doing validation and would like a simple way to du onSubmit valdiation.

I do not think the optimal UX is to show error messages while the user starts to type. The behavior i am looking for could be achieved by making a flag ad to multiple tenery statements however i would like the validation plugin to have a way to handle this situation.

Get first error

I think there should be a method to get the first error of an attribute. Right now it is very inconvenient to do so.

set validations programmatically

I have a component with this props:

props: {
  value: {
    type: [String, Number],
    required: true,
    default: ''
  },
  minlength: {
    type: Number
  },
  maxlength: {
    type: Number,
    default: 255
  },
  required: {
    type: Boolean
  }
},

is there a way to set Vuelidate's validations object according to my props?

Thanks

Question: Dynamic inputs with v-if

First of all: Great work here. Just waiting to have more free time to work on an integration between this library and Vue Material.

Now the question:

I have a form that is created dynamically, based on some flags on my endpoint.
Like the following example:

<md-input-container>
  <label for="name">Name</label>
  <md-input type="text" name="name" id="name" v-model="name" />
</md-input-container>

<md-input-container v-if="options.hasAddress">
  <label for="address">address</label>
  <md-input type="text" name="address" id="address" v-model="address" />
</md-input-container>

And, of course, I have the validations:

validations: {
  name: { required },
  address: { required } 
}

Now, supposing that options.hasAddress is false, the field is not going to be rendered, but the validation and the model variable are still there. When I call the this.$v.$touch() the $invalid flag will be evaluated as true.

There is a way "out of the box" to deal with examples like that? Or should I create another validation to replace the required just to check if the field exists?

Validation rules

Please consider incorporating validator.js to take care of string validation instead of re-implementing rules.

I like the validation approach this project is taking, keep up the good work.

Option for blank values

I have min and max length validators (both set to 4) on a field which should optionally take a 4 digit year.
The min length validator is triggered when there is no value on the field.

Could there be an option to allow blank values?

required error message visible on first load

Not quite sure if this is a bug, but it seems like on my tests when using the required validation rule that the form will indicate there is an error before user input is given.

<span class="form-group__message" v-if="!$v.phoneNumber.required">* required</span>

So on the first visit, a user will see * required even though they haven't inputted anything in. It doesn't seem to do this on the example page though so I'm a bit confused.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.