siriusjs-validation

Advanced validation library for browsers and Node. Designed to handle complex validation scenarios and integrate with any UI library like Vue, React etc

Usage no npm install needed!

<script type="module">
  import siriusjsValidation from 'https://cdn.skypack.dev/siriusjs-validation';
</script>

README

SiriusJS Validation

Source Code Software License Build Status

Sirius Validation is stand-alone JS library for data validation in Node and browsers. It offers:

  1. 23 build-in validation rules. There are validators for strings, array, numbers, emails, URLs
  2. Ability to validate deep objects
  3. Asynchronous validation support
  4. Referenced validation rules. Validation rules may have parameters which can be value or references to other paths
  5. 98% code coverage
  6. 11kb minified (4kb gziped)

Elevator pitch

1. Configure the validator object

/**
 * Given a user profile creation form we have the following rules:
 * - username required and at least 6 characters long
 * - email required and valid email address
 * - password is required and must be confirmed
 * - add up to 6 social profiles; the URL for the social profile is required if a provider was selected
 * - add up to 3 addresses where street, city and country are required
 */
let rules = {
  'name': 'required | min_length(6)',
  'email': 'required | email',
  'password': 'required | min_length(8)',
  'password_confirmation': 'required | min_length(8) | equal("@password")',
  'social_profiles': 'array_length(6)',
  'social_profiles[*][url]': 'required_when("@social_profiles[*][provider]',
  'addresses': 'array_length(3)',
  'addresses[*][street]': 'required',
  'addresses[*][city]': 'required | min_length(5)',
  'addresses[*][country]': 'required | min_length(3)',
};

/**
 * A callback to handle changes to the validation status of a path or, 
 * in case of async validator, changes to the state of a path
 */
function change_handler (type, path) {
  // type is `validation` (when the validation status for a path to a value is set) 
  // or `state` (when doing async validation a path can have a "pending" state
  
  // `this` is bound to the validator
  if (type === 'validation') {
    if (this.hasError(path)) {
      console.log(path, ' is not valid: ', this.getError(path));
      // here you can inject the error in the DOM, set error messages into your state etc
    }
  }
  if (type === 'state') {
    if (this.isPending(path)) {
      console.log(path, ' is waiting validation result');
    }
  }
}

/**
 * A callback to handle errors that occur during validation
 * exception are caught and you can decide to either throw it again or not so the rest of the app keeps working
 */
function error_handler (type, error) {
  // this is NOT for handling a validation error (ie: a value is not valid)  
}


/**
 * Custom validation messages
 * The library comes with predefined messages for it's built-in-rules but can use instance-specific messages
 */
let messages = {
  'password:min_length': 'Come on, you\'re not even trying',
  'password_confirmation:equal': 'Passwords should match'
}

let validator = SiriusValidation.build(rules, change_handler, error_handler, messages); 

2. Pass data to the validator

This has to be done depending on the tools you are using. Maybe you need to intercept browser events, set watchers in your framework of choice etc

validator.set('addresses[0][city]', 'New');

// or you can set an object
validator.set('addresses[0]', {city: 'New'}, true); // 3rd argument skips validation

// or you can set everything at once (eg: you loaded data from API)
validator.setData(obj, true, true); // 2nd argument skips validation and resets the form (error messages, touched fields etc)

/**
 * At this point the `change_handler` is called and it should be able to make changes to the application. 
 */ 

3. Submit form


function submit() {
  validator.validate().then(function(isValid) {
    if (isValid) {
      // send data to the server
    }
  }).then(function(response) {
    // maybe set server-side validation errors, show success message etc
  });
}

Why this style?

1. Being a general-purpose library it should work with "classic" web applications where the HTML looks like this

<input name="lines[0][price]" value="123.00">

2. If I am to do server side validation I can receive a JSON like this and push the messages into the page

{
    "errors": {
        "recipients[0]": "Field must be a valid email",
        "lines[2][price]": "Price must be a number",
    }
}

Caveats & known-issues

  1. Only one asynchronous validator per selector. It should be the last

Links