Validation for multiple programming languages using a single configuration object (JSON)
PHP
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
MIT-LICENSE.txt
README.md
index.php
logo.png

README.md

HAPPY HOLIDAYS & A WONDERFUL NEW YEAR TO ALL

Valid8r - Validation for multiple programming languages.

Valid8r

Valid8r is a validation library written for multiple programming languages, but all using a common configuration file. Create a single JSON file defining rules for fields, and then use that file to validate data in the browser via JavaScript, or on the server via PHP or Node (other languages may be added in the future.)

Demo

You can see the Kitchen Sink demo running live at:

http://thomporter.com/valid8r

Links to both JavaScript enabled, and PHP Server-Side only validation are there. I'll be adding Mocha browser tests to that when I get them done.

Quick Example

Here is a quick and dirty example of using Valid8r to on form data. We'll start with a form:

<form id="my_form">
	<input type="text" id="my_field" name="my_field">
	<input type="submit" value="Submit">
</form>

Now we'll setup our JSON configuration. We'll require that my_field be filled in, and at least 5 characters long.

{
	"my_field": {
		"rules": [
			{ "rule": "required" },
			{ "rule": "len", "min": 5 },
		]
	}
}

Now we can use this configuration to validate the form in...

JavaScript:

$(function(){
	var validator = new Valid8r({
		
		// instruct Valid8r to validate the form in real-time 
		bindToBlur: true, 
		
		// a selector for our form (required to prevent submit)
		form: "#my_form",
		
		// our callback function to deal with errors, 
		// for this simple demo, we'll just alert the result:
		callback: function(field, err) {
		  
		  if (err)  alert(field + ': ' + err);
		  else alert('Validation Passed');
		}
	});
	
	// I'll load the rules via AJAX here, but you could include them using
	// server side code (and should if you can!)
	$.get('./form-rules.json', function(rules) {
		validator.setRules(rules);		
	}, 'json');
});

PHP:

<php
require 'Valid8r/Valid8r.php';
$validator = new Valid8r();
$rules = json_decode(file_get_contents('form-rules.json'));
$validator->setRules($rules);
$errors = $v->validateFields($_POST);
$success = empty($errors);
?>

MoreExamples

Each language has it's own examples folder, which for now just has the Kitchen Sink demo. See each language's documentation for more.

For JavaScript:

Clone the JavaScript repo and run npm install & start in the examples folder:

git clone https://github.com/thomporter/valid8r_js
cd valid8r_js/examples
npm install
npm start

Then you can access http://localhost:3737 to see the examples.

You can also setup the JavaScript examples folder to run under a web server you already have setup - eg, the JavaScript Kitchen Sink Demo on my website is running under Apache.

For Node:

Clone the Node repo, change into the directory and run npm install & start:

git clone https://github.com/thomporter/valid8r_node
cd valid8r_node
npm install
npm start

Then you can access http://localhost:3737 to see the examples.

For PHP:

The PHP repo includes an examples directory. Set it up on an PHP server and you can test it out. I've only tested it under Apache, but any PHP environment should work. If you have any issues, please let me know.
(NOTE: JavaScript is disabled in the PHP example.)

Installation

Both PHP & JavaScript require only one file. You'll find them in the dist folder.

Note: The PHP class is name-spaced for PHP5 - feel free to change that to suit your needs.

Alternatively, you can clone the repos you need:

git clone https://github.com/thomporter/valid8r_js
git clone https://github.com/thomporter/valid8r_php
git clone https://github.com/thomporter/valid8r_node

Or use a package manager:

Installing Valid8r for JavaScript via Bower

bower install valid8r_js

Installing Valid8r for Node via npm

npm install valid8r_node

Installing Valid8r for PHP via Composer

{
  "require": {
    "valid8r/valid8r_php": "v0.0.2"
  }
}

Configuration

Valid8r uses JSON for configuration, making it simple to use across multiple languages and platforms. The structure of the object is fairy simple:

{
  "field": { // unique key that is also the key in the data array, eg $_POST for PHP.
    "selector": "jQuerySelector", // optional, used only for JavaScript in browser
    "rules": [ // required - array of validation rules to run against data in field.
      {"rule": "rule_name"},
      {"rule": "another_rule_name", "someRuleOption": true},
    ]
  }
}

That's it. Nothing much to the rule files, they are simple and clean.

JavaScript Updated in v0.0.4: It is no longer necessary to define the selector property if you have an ID on the input that is the same as field. eg:

&lt;input type="text" name="my_field" id="my_field" />

Can be defined as:

{
  "my_field": {
    "rules": [...]
  }
}

Global Conditions

In the event you need to use global conditions, you can slightly modify the configuration object to look like such:

{
	"_globalConditions": { ... conditions you want to use in multiple rules ... }
	"_rules": { ... the original config object as described above ... },
}

Global Conditions are not automatically attached to rules, you still have to use the when property on a rule, setting it's value to the global condition key. See the Conditional Validation section for more details.

Valid8r Rules

Here we will document the rules for Valid8r. These are available in all languages. For simplicity's sake, the examples below are of just the rule object - not much use unless you put it in a rules array.

required

The required rule requires that a field be filled in, selected or checked.

{"rule": "required"}

len

The len rule allows you to validate the length of a field:

{"rule": "len", "min": 5} // require min 5 characters.
{"rule": "len", "max": 20} // require max 20 characters.
{"rule": "len", "min": 5, "max": 20} // require min 5 & max 20 characters.

val

Validate your data for a particular numeric value using the val rule:

{"rule":"val","min":5} // accept any number greater than 4
{"rule":"val","max":10} // accept any number lower than 11
{"rule":"val","min":5,"max":10} // accept any number from 5-10
{"rule":"val", "outside":[5,10]} // accept any number less than 5 and greater than 10

isAlpha

The isAlpha rule requires all characters in the field be alphabetic (A-z)

{"rule": "isAlpha"}

isNum

The isNum rule requires all characters in the field be numeric (0-9)

{"rule": "isNum"} // allows negative numbers
{"rule": "isNum", "nonNeg": true} // requires a non-negative number

isAlnum

The isAlnum rule requires all characters in the field be alphanumeric (A-z,0-9)

{"rule": "isNum"}

formatted_as

The formatted_as rule allows you to specify a format for a string.
A = alpha, D = digit, and you can use symbols:

{"rule": "formatted_as", "format": "DD/DD/DDDD"}
{"rule": "formatted_as", "format": "(DDD) DDD-DDDD"}
{"rule": "formatted_as", "format": "AADDAADDDDDD"}

regex

Create your own regular expressions to validate with using the regex rule.

{"rule":"regex", pattern:"[a-Z0-9.-]{2,7}", modifiers:"i"}

email

Validate email addresses:

{"rule": "email"}
{"rule": "email", "validator": "simple" } // very basic validator, will let a lot fly
{"rule": "email", "validator": "default" } // the default validator, works well. 
{"rule": "email", "validator": "rfc5322" } // full blown RFC 5322 RegExp - not tested yet 

the validator property defaults to "default" if not specified.

url

Use the url rule to validate URLs, with or without protocols:

{"rule": "url"} // validates a url, allowing any protocol (even made up ones.)
{"rule": "url", "protocols": ["http","https","ftp","git"]} // set the protocols to accept
{"rule": "url", "noProtocols": true} // require there be no protocols 

TODO:

  • Add host property requiring the url be of a particular host.
  • Add domain property requiring host be of particular domain (less restrictive than the host option.)

ip

Use the ip rule to validate IP addresses. Set a v property on the rule to require version 4 or 6, or leave it off to allow both!

{"rule":"ip"} // allows IPv4 or IPv6 addresses
{"rule":"ip", "v": 4} // allows IPv4 addresses
{"rule":"ip", "v": 6} // allows IPv6 addresses

checks

Use the checks rule to validate that a certain number of checkboxes have been checked.

Example Rules:

{"rule": "checks"} // requires at least one be checked
{"rule": "checks", "min": 3} // requires at least 3 boxes be checked
{"rule": "checks", "max": 5} // requires at no more than 5 boxes be checked
{"rule": "checks", "min": 3, "max": 5} // requires between 3 and 5 boxes be checked

SERVER SIDE NOTE: You must properly name your checkboxes with the array notation ([]) at the end of the name, eg:

<input type="checkbox" name="my_checkboxes[]" value="1" />
<input type="checkbox" name="my_checkboxes[]" value="2" />

radio

Use the radio rule to require one of the radio buttons in the set have been checked.

Example Rules:

{"rule": "radio"} // requires one of the radios be checked.

Custom Validators

You can create a custom validator by using the custom rule. You must additionally include a func property that either contains the function, or the name of the function.

Example Rules:

{"rule": "custom", "func": "my_custom_validator" }

Please review the language-dependent documentation for details about how to declare your functions.

Note

The JavaScript and Node versions both accept a customValidators property on the main configuration object you pass to Valid8r. This is the preferred way of defining custom validators. JavaScript Example:

var validator = new Valid8r({
	customValidators: {
		myValidator: function(field, value) { ... },
		myOhterValidator: function(field, value) { ... }
	},
	...
});

AJAX Note

Asynchronous validation can be done in the browser, but requires you add the async property (equal to true) to your rule's definition:

{"rule":"custom","func":"myCustomAsynValidator", "async":true}

Valid8r will not run async rules onSubmit - only onBlur as the user fills in your form.

Conditional Validation

It is possible to attach conditional validation to any of the rules in your validation scheme. Here is how:

{
	"my_field": {
		"conditions": {
			"condition_key": {
				"field": "condition_field_id",
				"is": "required value to satisfy condition"
			}
		},
		rules: [
			{"rule":"required", "when":"condition_key"}
		]
	}
}

Lets take a look. First, we've declared a conditions object on our main validation object for "my_field". We declare a condition_key property, which describes a field and value (is) that must be satisfied for the condition to be true. Next, our rules array defines a single rule, required, with the when property set to our self-defined condition_key.

So, in order for the required rule to be tested, the condition_key condition must be satisfied, or more verbosely, the field with key condition_field_id must have the value required value to satisfy condition.

How about a more real-world example. Say you have a registration form. On it, you want to require someone say "Yes" or "No" to a question, let's say, "Do you have a website?". If they say yes, we want to require they enter their website into another field. So we'll have 2 radio buttons named have_website, one with value "Yes", the other value "No". Next we'll have a text input, with the ID of url. Here's the rules:

{
	"url": {
		"conditions": {
			"have_website": {
				"field": "have_website",
				"is": "Yes"
			}
		},
		"rules": [
			{"rule": "required", "when": "have_website"},
			{"rule": "url", "when": "have_website"}
		]
	}
}

If you need to use the same condition across multiple fields, you can restructure the configuration object slightly, as described above in the Global Conditionals section.

TODO

  • Test the "Quick Example" code.
  • Mocha Browser Tests
  • AMD/Require browser support for JavaSript module.
  • AMD support for the node module.
  • Add ability to create "global conditionals" - All modules pushed to version 0.1.0 with this change.