Aurelia-Validate.js Plugin

Aurelia and Validate.js

aurelia/validation rewrite

I've been contributing for a while now to some of the core plugin libraries we have but with Validation recently we realized there was some changes to be made and it was a great chance to take the concepts and go through a re-write.

I worked heavily with @jdanyow on this and we tried to find the best way to represent validation in an Aurelia plugin. Instead of starting fresh with new validation and everything we chose to start with a popular server/browser pure validation library called validate.js.

Validate.js has been a great library for me to interact with. I really enjoyed how fluid and clean setting up validation has been.

Technical Requirements

  1. Must run on server (node.js) and browser.
  2. Use existing pure validation library.
  3. Installed as an Aurelia plugin.

You can read about more of the technical requirements here.

Alpha Release

I think we are at a point where we want to get heavy user feedback upfront, so today you can install the alpha release here -

If you are using JSPM -

$ jspm install aurelia-validatejs

If you are using NPM -

$ npm install aurelia-validatejs --save

Then install the plugin in your main.js -

export function configure(aurelia) {  
  aurelia.use
    .standardConfiguration()
    // .other stuff
    .plugin('aurelia-validatejs');

  aurelia.start().then(() => aurelia.setRoot());
}

Decorator usage

Next you can use it in your view-models or views as a decorator -

import {ValidationEngine, required} from 'aurelia-validation';

export class MyModel {  
  @required name = '';
}

export class MyViewModel {  
  model = new MyModel();
  @required id = 12345;
  constructor() {
    this.reporter = ValidationEngine.getValidationReporter(this.model);
    this.reporter.subscribe(result => {
      // do something with error
    });
  }
}

Both the model.name and the id property on the view-model will be required.

Fluent API Usage

You can also use the Fluent API -

import {Validator, length, required} from 'aurelia-validatejs';

export class Fluent {  
  model;
  static inject = [Validator];
  constructor(validator) {
    this.model = new Model();
    this.validator = validator
      .ensure(this.model, 'firstName')
        .required()
        .length({minimum: 3, maximum: 10})
      .ensure(this.model, 'lastName')
        .required();
  }
}

You can see both the decorator and fluent API take the same configuration options.

Displaying errors

Currently, to display errors you can use the ValidateBindingBehavior which watches for changes to the validation properties of the object and uses a renderer to show them. We would like some feedback on the setup so try it out and let us know what you think.

We can use the validate binding behavior in your HTML to show errors -

<template>  
  <form class="container">
    <div>
      <label class="form-group">
        <strong>Name</strong>
        <input class="form-control" value.bind="model.name & validate" />
      </label>
    </div>
  </form>
</template>  

This uses the standard Bootstrap error formatting.

ValidationReporter

In your view-model code you can watch for errors emitted by the error reporter -

import {required, ValidationEngine} from 'aurelia-validation';

export class MyModel {  
  @required name = '';
}

export class MyViewModel {  
  constructor() {
    this.model = new MyModel();
    this.reporter = ValidationEngine.getValidationReporter(this.model);
    this.reporter.subscribe(result => {
      // result is array of errors    
    });
  }
}

What's next?

Weekly Releases

This first release is to get some initial feedback. Next week we plan to release on Tuesday with some nice improvements in renderers. Right now, for example we are inferring the reporter from the binding engine but we have some planned improvements for the coming week. We hope to continue iteratively releasing improvements and welcome community contribution.

More Complex Renderers

We plan to add more complex renderers to a templating-validation repository. This is a collection of renderers and templating aids for validation to show errors in the DOM.

This will include ones for showing validation errors on forms as well as ones that are scoped to the current element.

We definitely want to welcome community contributions which this is in place to handler rendering in other scenarios besides just using the default Bootstrap ones.

Feedback

In the repository for the validate.js bridge You can track issues or provide feedback. We've added a new tag contribution-welcome to indicate that a particular piece of the code-base is stable and contributions are welcome.

How can you contribute?

I've put together another blog post detailing how validation is currently structured to give others an idea of how things currently work and what we can do to improve validation as we go forward.

Here are some ways to get started if you are interested -

  1. Bug repros / fixes
  2. Unit test coverage
  3. Add TypeScript types
  4. Documentation
  5. Descriptive errors (I'd like for errors to have links to trouble-shooting sections of docs for developers)
  6. Make it work with other CSS libraries

Custom Renderer

Here's a few tips on creating a custom renderer to try out with your CSS framework of choice -

validate-binding-behavior.js currently gets the renderer from validation-renderer.js. To try out your own renderer you can simply copy the validate-binding-behavior and update the name. Change the import to a renderer of your choosing (follow the same patterns in validation-renderer.js of renderErrors / unrenderErrors method signatures for now). We'll have more information and docs on this ASAP.

Thanks again for everyone's patience and help! Please report any issues you are having!