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

ractive-validator

v3.1.1

Published

Validates objects according to given rules, in a manner compatible with Ractive (ractivejs.org).

Downloads

16

Readme

A form validator compatible with the Ractive.JS framework

This package can be used to perform custom validation on JavaScript objects -- although the name of the package is ractive-validator, it doesn't have to be used with Ractive. I like to use it on the client-side with Ractive, and also on the server, with the same rules, checking the request.body object.

(Ractive.JS is a great framework for two-way model binding in javascript applications.)

Installation

Install via npm:

$ npm install --save ractive-validator

Usage

The RactiveValidator class can be used with AMD, node, and regular browser script soup type scenarios. For example, using require.js you could write the following:

define(['ractive', 'ractive-validator'], function (Ractive, RactiveValidator) {
  var ractive = new Ractive({...});

  var validator = new RactiveValidator(ractive, {
    //rules
  });
});

Or, for node:

var RactiveValidator = require('ractive-validator');

var validator = new RactiveValidator(mymodel, {
  //rules
});

You can also just use it in the browser with a script tag.

The constructor

The constructor has the signature new RactiveValidator(basePath, model, rules). The first two arguments are optional, so you can have either, both, or neither of them.

the rules parameter

We'll start with rules, since that is mandatory. The rules define what data is valid and what is not, and are composed of an object keyed by keypaths. A keypath (a Ractive concept) is just a reference into hierarchical data. Take the following object:

var obj = {
  data: {
    list: [{name: 'bob'}, {name: 'betty'}],
    count: 2
  },
  other: '',
  crap: ''
}

The count property is at keypath 'data.count', while the string 'bob' is at keypath 'data.list.0.name' (note: Ractive also lets you use 'data.list[0].name', but I haven't bothered to implement that...). Wildcard keypaths are also allowed, so for example, 'data.list.*.name' refers to all the name properties in the list.

So, we can now build rules to make sure count is positive and each element in list has a name property with a non-empty value:

var validator = new RactiveValidator({
  'data.list.*.name': {required: true},
  'data.count': {required: true, positive: true, type: 'integer'}
});

As you can hopefully see, rules are defined by creating an object with a property for each keypath. The validators to be applied to the keypath are specified in an object as the value of the property. See the Validators section for what validators are allowed.

the model parameter

You can provide a model at construction. It can either be just a Plain Old JavaScript Object, or a 'model' object with .get and .set methods for getting and setting keypaths (e.g., a Ractive object). You can also pass it a jQuery selector for a bunch of form fields you want validated.

If the given model also has an .observe method (e.g., is a Ractive object), the validator will listen for changes to the keypaths defined in the rules, and validate in real time.

the 'basePath' parameter

basePath sets the base keypath. That is, the example given previously could have been written as:

var validator = new RactiveValidator('data', {
  'list.*.name': {required: true},
  'count': {required: true, positive: true, type: 'integer'}
});

the validate method

This method runs the validation on the model: this will be the argument supplied to this method if there is one, or the model given at construction.

var validation = validator.validate(model);

if (validation.valid) {
  // yay!!
}
else {
  // oh no!
}

Another property of the result object is data, which contains only the valid data found at the keypaths specified by the format rules. The errors property contains any validation error messages.

By default, if the validator finds an error on a field, it will put the appropriate error message in a property with the name of the field with Msg appended. E.g., if the name field is required, but has no value, then the nameMsg field will be set to 'required'. This is useful for frontend stuff for reporting errors to the user; you would probably have a span element to display the value of the error message, as in the following example using Ractive:

<div class="{{nameMsg ? 'has-error' : ''}}">
  <input type="text" value="{{name}}">
  <span class="validation-message">{{nameMsg}}</span>
</div>

I've also made it add an error css class if there is an error present.

the validators property

The validator functions that the validator instance can use live in the validators property, with each validator being given a default set at construction. The default set live in the static validators property -- changing this will change the default set given to each new instance.

Remember from earlier a rule looks like this:

'some.keypath': {required: true, type: 'string'}

Here, required and type match properties of the validators property. If you use a rule name that is not recognised, it'll throw an exception when validaton is being performed; unless the argument is a function, in which case, it'll use the function as a validator. This is a handy way to define one-off custom validators, e.g.:

'some.keypath': {mySuperValidator: function (value, ruleValue, result) { ... }}

If you're going to use that validator a bunch of times though, you're better to put it in the validators property:

validator.validators.mySuperValidator = function (value, ruleValue, result) { ... }

Or, if you're going to use it in loads of different validators, you might even put it in the static property (before you instance anything that uses it):

RactiveValidator.validators.mySuperValidator = function (value, ruleValue, result) { ... }

The arguments to the validaion function are thus:

  • value - the value being validated
  • ruleValue - the value of the property in the rule, e.g., for the example required: true, ruleValue is true
  • result - the result object - gives access to the model and the current errors

this is set to the validator instance.

A validator function returns an object with the following properties:

  • valid - true if the value was valid; otherwise, false
  • error - if valid is false, a message indicating why it is invalid
  • coerced - the validator can coerce the data to some other value, if desired

It may even return a promise for an object with those properties: this will cause the validate method to return a promise though. This is especially useful for validators which need to make a call to the server to work.

built in validators

There are only a handful of built-in validators, for the most common cases.

required

If you add required: true as a rule, then the value will be considered invalid if it is an empty string, null, or undefined. required: false is always valid, but is a handy way to get a value to show up in the data property of the validation result if there are no other validation requirements.

moment

This checks that the value is valid according to the given moment.js format, e.g., moment: 'DD/MM/YYYY' will validate only if the string is a valid UK date. By default, the data property of the validation result will contain a property for the field containing the same value as the field; however, you can have it converted to a moment object illustrated in the more complete value below:

var validator = new RactiveValidator(ractive, {
  'date': {required: true, moment: {format: 'DD/MM/YYYY', coerce: true}}
});

var validation = validator.validate();
// validation.data.date will be a moment object representing the input date

You can also specify the rule as moment: {format: 'DD/MM/YYYY', coerce: 'YYYY-MM-DD'} for example, to have it coerced to a date string in a different format. This is useful if you want your UI to accept dates in one format, and have your API accept the date in ISO format for example.

positive

This makes sure that the value is positive.

type

This ensures that the value matches the specified type, one of the following: string, integer, decimal, and boolean. For validation of models passed into the constructor, the data will be coerced into the required type if possible. E.g., if the rule is type: 'decimal', and the value is '5.5', then the data after validation will be 5.5.

However, for validation of models specified as an argument to validate, it will give a validation error if the type is not actually the specified type.

password

A validator for 'confirm password' fields: checks that the value matches the value at the specified keypath.

Disabling validation

Sometimes you might want to disable validation. For example, if you load some details into the form at the start, you probably don't want required errors on every empty field. The solution is to just disable validation until after you have loaded the initial data, and then turn it back on again:

validator.enable(false);

///...
//load some data
///...

validator.enable(true);

Calling the enable method with any value clears the validation errors at the ...Msg fields described earlier.

Changing the error suffix

The errorSuffix property lets you configure what the error field for a given field will be. For example, if you want the message for name to go into nameError, you would write:

validator.errorSuffix = 'Error';

Using on a conventional HTML form

If you clone the repository and build it with grunt release, you'll get a ractive-validator.js and ractive-validator.min.js in the dist/ directory. Your HTML page will need to reference jQuery then one of these JavaScript files.

You can then build an HTML form as normal, and then make a new RactiveValidator instance:

var validator = new RactiveValidator($('#myform', {
  // rules...
}));

It will automatically subscribe to the change event so that the error messages get updated when the field loses focus.

Have a look at test/html/index.html for a really quick example.

The end

I made this in my spare time, so it's probably a bit rough around the edges and there's probably some stuff missing, particularly common, useful validators. Feel free to get in touch if you think there's something that should be added!