Conform

Simple, flexible node.js form module with casting and validation; highly inspired by mongoose

View the Project on GitHub nrako/formal

Formal Build Status Coverage Status Dependency Status

Formal is a Form module for node.js inspired by mongoose, Formal provides casting, validation and much more!

DRY! If you use Mongoose, use Formal-Mongoose to define your form from an existing schema.

Example

var Form = require('formal');

var form = new Form({
  name: {
    family: String,
    first: {
      type: [String],
      set: function(val) {return val.split(' ');}
    }
  },
  email: {
    type: String,
    required: true,
    match: [/^[a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-z]{2,3}$/, 'email'],
    attributes: {
      type: 'email'
    }
  },
  age: {type: Number, min: 18}
}, {
  errors: {
    // custom error message for match validator
    email: 'Value is not a valid email'
}
});

form.set({
  name: {family: 'Martinez'},
  'name.first': 'José Luis Chavez',
  age: 12
});

form.validate(function (err) {
  console.log(err); // missing required email, age to low
  console.log(form.get('name.first.0')); // José
  console.log(form.export()); // data with nice error messages
});

Install

npm install formal --save

Summary

This module focus on form field casting and validation, with suppports for advanced path definition.

It supports

It doesn't

TODO... maybe

API

Summary of the most useful methods.
For a complete list see gh-pages documentation.

new Form(Object:definition[, Object:option]):instance

var form = new Form({
  username: {
    type: String,
    trim: true,
    required: true
  },
  password: {
    type: String,
    trim: true,
    required: true
  }
}, {
  errors: {
    required: 'Please fill out this field'
  }
});

Options

{
  dataSources: ['body', 'query', 'params'], // sources of data used by the route-middleware
  autoTrim: false,  // automatically add trim options to fields
  autoLocals: true,  // form.middleware adds form.export + validation results to res.locals
  errors: { // default errors message, can be extanded to match your own error type
    required: 'This is a required field',
    min: 'Value must be greater than or equal to <%= data.min %>',
    max: 'Value must be less than or equal to <%= data.max %>',
  }
}

Connect and express route-middleware

For connect and express calling the constructor function will operate as a shorthand which return the result of form.middleware() which will monkey patch the request and the response object.

var form = require('formal');
app.post('/url',
  // sames as (new Form({...})).middleware()
  form({
    username: String
  }),
  function (req, res) {
    console.log(req.form);
    console.log(res.locals.form.username.value);
  }
);

form.field(obj:Object):this

Define and add a new field to the form.

Alias

form.add()

form.field({
  example: {
    'of.a.nested.field': String
  }
});

form.set(path:String|obj:Object[, value])

Set values.

form.set({
  username: 'nrako'
});

form.set('example.of.a.nested.field', 'overboard nested path example');

form.get(path:String):value

Return a value with getters applied.

console.log(form.get('username')); //nrako

form.getData():Object

Return tree data with getters applied

console.log(form.getData()); // Object

form.validate(callback(err):Function)

Validate all fields and return an ValidationError object, if any, via the callback function.

form.validate(function(err) {
  console.log(err) // ValidationError object
});

form.export(err:ValidationError):Object

err: a ValidationError object returned by from.validate

Export and return an object which includes all friendly message error when error template message is defined in options.errors.

form.validate(function(err) {
  var result = form.export(err);
  console.log(result.username.value); // nrako
  console.log(result.password.error); // Please fill out this field
});

form.middleware():Function(req, res, next)

Provide a route-middleware à la connect/express which will monkey patch the request.form and response.locals.form.

app.post('/url',
  form.middleware({
    username: String
  }),
  function (req, res) {
    console.log(req.form.getData());
    console.log(res.locals.form.username.value);
  }
);

Custom error message for a custom validation

Custom error message within the result of form.export(errors) are available with the form options.errors. Error message must be a valid lodash string template which is populate with the field content.

Example

var form = new Form({
  a: {
    type: String,
    validate: [/^a/i, 'startWithA']
  },
  b: {
    type: String,
    validate: [/^b/i, 'startWithB']
  }
}, {
  errors: {
    'startWithA': 'Value <%= value %> should start with "a"'
  }
});

form.option('errors', {startWithB: 'Value <%= value %> should start with "b"'})

form.set({a: 'Babar', 'b': 'Basile'});

form.validate(function (err) {
  var result = form.export(err);
  console.log(result);
});

See the tests for more examples.

Test

npm test
Mocha Coverage
npm run-script coverage
On Coveralls.io

All tests are in Coffee-script, hence easy to read! Provides a great way to understand the API ;)

LICENSE

MIT