npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

form-validation-manager

v2.3.0

Published

VueJs validation manager, model based

Downloads

87

Readme

beta version of fvm for vue3 (composition api) and vue2

Some bugs may still present, please report them

Form Validation Manager - fvm

v2.x.x is compatible with vue2, vue3(options api) and vue3(composition api) v1.x.x is only compatible with vue2

Test Coverage Dependencies Typescript LGPL3

Simple, lightweight model-based validation for Vue.js

Inpired by vuelidate

This plugin usage is similar of vuelidate

Why a new plugin ?

Instead of vuelidate this one allow fine error report and custom messages
and a better integreation in templates

  • Model based
  • Decoupled from templates
  • Minimalistic library
  • Support for collection validations
  • Support for nested models
  • Contextified validators
  • Easy to use with custom validators (e.g. Moment.js)
  • Easy errors messages customisation

Summary

Installation

npm install form-validation-manager --save

Vue 2 :

Import the library and use as a Vue plugin to enable the functionality globally on all components containing > > validation configuration.

import Vue from 'vue'
import Fvm from 'form-validation-manager/vue2'

//for typescript
import * as fvmTypes from 'form-validation-manager/vue2/types';
import * as fvmTypesValidators from 'form-validation-manager/validators/types';

Vue.use(Fvm)

Basic usage

Vue2 options-api

import { and, required, numeric, gte, length } from 'form-validation-manager/validators'

export default {
  data () {
    return {
      form:{
        name: '',
        age: 0
      }
    }
  },
  validations: {
    form:{
      name: and(required(), length(gte(3))),
      age: and(required(), numeric(), gte(21))
    }
  },
  methods:{
    submit(){
      if(this.$fvm.$isValid){
        //do something
      }
    }
  }
}

a validation oject is generated with the same tree as 'validations'

//generated object
//$fvm
{
  $errors:String[],
  $error:Boolean,
  $isValid:Boolean,
  $invalid:Boolean,
  $dirty:Boolean,
  $pristine:Boolean,
  $pending:Boolean,

  validate: ()=>void

  form:{
    $errors:String[],
    $error:Boolean,
    $isValid:Boolean,
    $invalid:Boolean,
    $dirty:Boolean,
    $pristine:Boolean,
    $pending:Boolean,

    validate: ()=>void

    name:{
      $errors:String[],
      $error:Boolean,
      [...]
    },
    age:{
      $errors:String[],
      $error:Boolean,
      [...]
    }
  }
}
  • $errors :
    • string[]
    • For each 'non-final' node : $errors Array concatenate $errors of sub nodes
  • $error : node (or sub nodes) has one or more errors
  • $isvalid : node (or sub nodes) as no errors
  • $invalid : node (or sub nodes) has one or more errors
  • $dirty : node (or sub nodes) have been edited by user
  • $pristine : node (or sub nodes) have not been edited by user
  • $pending : node (or sub nodes) wait for an async validation result
  • _validate : force validation of node (and sub nodes)

Vue3 options-api

import { and, required, numeric, gte, length } from 'form-validation-manager/validators'
import { useFvm } from 'form-validation-manager/vue3'

export default {
   data () {
    return {
      form:{
        name: '',
        age: 0
      }
    }
  },
  validations: {
    form:{
      name: and(required(), length(gte(3))),
      age: and(required(), numeric(), gte(21))
    }
  },
  setup:()=>({ fvm$: useFvm()})
}

or

import { and, required, numeric, gte, length } from 'form-validation-manager/validators'
import { useFvm } from 'form-validation-manager/vue3'

export default {
   data () {
    return {
      form:{
        name: '',
        age: 0
      }
    }
  },
  setup(){
    return{
      fvm$ : useFvm({
        form:{
          name: and(required(), length(gte(3))),
          age: and(required(), numeric(), gte(21))
        }
      })
    }
  }
}

validation state is accessible with fvm$or this.fvm$

Vue3 Composition API

import { and, required, numeric, gte, length} from 'form-validation-manager/validators'
import { useFvm } from 'form-validation-manager/vue3'

export default {
  setup () {
  const form = reactive({
    name: '',
    age: 0
  });

  const validation = useFvm(form, {
    name: and(required(), length(gte(3))),
    age: and(required(), numeric(), gte(21))
  });

  return { validation, form };
  }
}

validation state is accessible with validation

Specials nodes

export default {
  data () {
    return {
      form:{
        list:[
          {id:1, value:15}
          {id:2, value:0}
        ],
        parent:{
          child: {
            property:'value'
          }
        }
      }
    }
  },
  validations: {
    form:{
      liste:{
        $each:{
          value:gt(0)
        }
      },
      parent:{
        $self: custom(function()=>{ /* ...*/ }), //validate parent obj
        child:{
          property: regexp(/.../) //validate child's property
        }
      }

    }
  }
}
  • $each : loop over elements of an array
  • $self : allow to validate parent and child nodes

Validators

values validation

// generic validators
required()
eq(value) // equal

// number validators
numeric() // is numeric
gt(min) // greater than >
gte(min) // greather than equal >=
lt(max) // less than <
lte(max) // less than equal <=
between(min,max[,exclude])

// string validators
isString()
regexp(expr:RegExp)
includes(str:String)
isDate(format:String='yyyy-MM-dd') // value must be a string date
email() //is email address

logic

and(...validators) // all validators must be ok
andSequence(...validators) // all validators must be ok, call next validator only if previous one is OK
or(...validators) // minimum one validtor must be ok
xor(...validators) // only one validator must be ok
_if(condition:(value,context)=>Boolean, thenValidator[, elseValidator])// apply thenValidator only if condition function returned value is true else apply elsevalidator if defined
not(validator) // validator must be KO
optional(validator) //execute validator only if value != null, undefined or ""

specials

pick(property, validator) // validate value[property] instead of value itself
length(validator) // pick length
withMessage(validator,message) // customise validator message
empty() // always ok validator
custom((value, context)=>Boolean|String|String[]) // allow user to create custom validators
async((value, context)=>Promise<Boolean|String|String[]>, forceRenderUpdateAuto=true, debounceTime=0) // allow user to create custom async validators
revalidate(...paths) // force properties revalidation if this one change
// exmple with previous code : revalidate('form.name')

Arrays

A special node '$each' allow to validate each elements of an array

export default {
  data () {
    return {
      form:{
        list : [-1, 5, 10]
      }
    }
  },
  validations: {
    form:{
      list:{
        $each : {
          and(
            gt(0),
            custom(function(value,context){
              // custom validation code
            })
          )
        }
      }
    }
  }
}

Note : using custom validator under $each :
context.indexes contain $each loops indexes. Here :

{
 0:<possible values : 0,1,2>,
 list:<possible values : 0,1,2>,
 length:1
}

for more details about custom validator, see Custom validation

Messages

withMessage wrapper allow to customise error message

export default {
  data () {
    return {
      form:{
        age: 0
      }
    }
  },
  validations: {
    form:{
      age: and(
        withMessage(
          and(required(), numeric()),
          'field is required and must be a number'
        ),
        withMessage(
          gte(21),
          'you must be of age'
        )
      )
    }
  }
}

the property '$errors' will contain defined errors messages if field isnt valid.

Custom validation

component method

a custom method can be used as validator.
inside this one, 'this' refer to current component

export default {
  data () {
    return {
      form:{
        age: 0
      }
    }
  },
  validations: {
    form:{
      age: custom(function(value, context){ //do not use arrow function if you want to use 'this'
        return this.myValidationMethod(value, context);
      })
    }
  },
  methods:{
    myValidationMethod(value, context){
      // ...
    }
  }
}

myValidationMethod must return false if no error and true|string|string[] if one or more errors occured context contain properties: component : current component path : current property path (form.age here) optional indexes : contain $each loops indexes, see $each section

Reusable validator

You may want to define a validator and use it in different components
best way is to define it in separate .js file

import { Validator } from 'form-validation-manager/validators';

export default function myValidator(arg1, arg2) {
  return new Validator('myValidator', (value:any, context:Context) => {
      if( /* test rule 1 KO */){
        return 'message 1'
      }
      if( /* test rule 2 KO */){
        return 'message 2'
      }

      // is valid
      return false
  });
}

and use it

import myValidator from './my-validator'

export default {
  data () {
    return {
      form:{
        age: 0
      }
    }
  },
  validations: {
    form:{
      age: myValidator('val1', 'val2')
    }
  }
}

Async validation

export default {
  data () {
    return {
      form:{
        age: 0
      }
    }
  },
  validations: {
    form:{
      age: async(function(value, context){
        return new Promise(resolve=>{
          // async stuf
          resolve(myValidationResult)
        })
      }, debounceTime)
    }
  },
}
  • debounceTime: number : in ms, optional, default=0, if > 0 debounce calls

Before submiting form, you must wait for $pending == false.
Exemples :

  • In template :
<form>
  <!-- -->
  <button type="submit" :disabled="$form.$pending || $form.$error" @click="submit()">Send</button>
</form>

Integration with vuetify

export default {
  data () {
    return {
      form:{
        age: 0
      }
    }
  },
  validations: {
    form:{
      age: and(
        withMessage(
          and(required(), numeric()),
          'age is required and must be a number'
        ),
        withMessage(
          gte(21),
          'you must be of age'
        )
      )
    }
  }
}
<v-text-field
  :rules="$fvm.form.age.$errors"
/>