- Overview
- Documents
Writing frontend validation for forms is painfully boring. So I made this in the hopes that it will help make it a little less agonizing for you.
It's designed to
- Keep validation away from the fields to keep the html clean and simple
- Work with selectors so you can target more fields with just one "rule"
- Be flexible. You can easily define your own functions to validate for (and many other things)
- Be extensible. If you look in the source code, it should be fairly easy to add new rules or remove/add functionality
While it isn't strictly Bootstrap dependent, it defaults to the structure that bootstrap uses for its forms. However it should be flexible enough to accomodate most any structure.
Quick introduction
The plugin is made as a jQuery plugin and is activated like this: $("#form").nod( metrics ); The metrics is a list that you build beforehand. It is basically a list of each selector and how you want it validated.
Example:
var metrics = [ [ '#foo', 'presence', 'Cannot be empty' ], [ '#bar', 'min-length:4', 'Must be at least 4 characters long' ] ]; $( "#form" ).nod( metrics );
Each "sublist" consists of three parts:
- The selector (the validation will be applied to every field that the selector matches)
- A string describing what you wish to validate for (see below for documentation)
- The error message you wish to display on error
Metrics [ ]
Here is a table with what you can currently validate for:
Name | Example |
---|---|
'presence' | [ '#foo', 'presence', 'Cannot be empty' ] |
'exact:String' | [ '#foo', 'exact:bar', 'You have to write "bar"!' ] |
'not:String' | [ '#foo', 'not:bar', 'Do not write "bar"!' ] |
'max-length:Number' | [ '#foo', 'max-length:4', 'No longer than 4 characters please' ] |
'min-length:Number' | [ '#foo', 'min-length:4', 'At least 4 characters please' ] |
'exact-length:Number' | [ '#foo', 'exact-length:4', 'Must be exactly 4 characters' ] |
'between:Number:Number' | [ '#foo', 'between:2:4', 'Must be between 2 and 4 characters long' ] |
'max-num:Number' | [ '#foo', 'max-num:4', 'Type in a number that is at smaller than 5' ] |
'min-num:Number' | [ '#foo', 'min-num:4', 'Type in a number that is bigger than 3' ] |
'between-num:Number:Number' | [ '#foo', 'between-num:2:4', 'Type in a number between 2 and 4' ] |
'integer' | [ '#foo', 'integer', 'Must be a whole number' ] |
'float' | [ '#foo', 'float', 'Must be a number (decimals are fine)' ] |
'same-as:Selector' | [ '#email_repeat', 'same-as:#email', 'Your emails do not match' ] |
'one-of' (example) | [ '#first, #second', 'one-of', 'You must fill out either #first or #second' ] |
'email' (read this) | [ '#foo', 'email', 'Must be a valid email (RFC 822)' ] |
Function | [ '#foo', ( function(x) { return x % 2 == 0; } ), 'Must be divisible by two' ] |
RegExp | [ '#foo', /Hello/, 'String must contain the word "Hello"' ] |
If there is something not on the list that you think others would benefit from, then feel free to create a new issue and let me know.
Options { }
You can also pass along an object: $("#form").nod( metrics, options );
Example:
var options = { 'delay' : 200, 'submitBtnSelector' : '#submit_btn' };
Here is a table of everything you can change with the options object.
Name | Type | Default value | Description |
---|---|---|---|
delay | Number | 700 | Delay on keyup before it runs a check. Set it to false to disable completely. |
disableSubmitBtn | Bool | true | Set to false if you don't want the submit button to be disabled. |
helpSpanDisplay | String | 'help-inline' | Set this to help-block if you want error messages to be shown on next line. |
groupClass | String | 'error' | The .control-group will get this class if an error is found. Can be set to anything you like, but error, info,warning, or success makes the most sense with bootstrap. |
submitBtnSelector | String | '[type=submit]' | Selector to find the submit button. If the form is submitted with a button that is not a member of this selector, then the form will be submitted regardless of errors. |
errorPosClasses | Array | ['.help-inline', '.add-on', button, '.input-append'] | When placing the error message, nod will look for these elements (after and above) and place it after these if they exist. |
errorClass | String | 'nod_msg' | Used internally. This is the class you want to style if you want any specific styling. |
silentSubmit | Bool | false | If set to true, the form will not be submitted the regular way, but instead an event: silentSubmit will be called on the form with the values you'd normally submit. (Read more) |
broadcastError | Bool | false | If set to true, nod will trigger an event on the window object. (Read more) |
groupSelector | String | '.control-group' | The selector for something surrounding your input elements. Like .control-group in bootstrap forms. |
Notes
Radio buttons
These can be a bit tricky to validate, so here's an example.
<div class="control-group"> <div class="controls"> <label class="radio"> <input type="radio" name="a" value="a1" id="bar"> First </label> <label class="radio"> <input type="radio" name="a" value="a2"> Second </label> <label class="radio"> <input type="radio" name="a" value="a3"> Third </label> </div> </div> <!-- ... --> <button data-loading-text="loading..." type="submit" class="btn btn-success">Submit form</button>
Pretty standard html. Notice the #bar on line 4 though. To validate for presence on these fields, we don't need the #bar, we just do
var metrics = [ ['[name=a]', 'presence', 'You must click on at least one radio button'] ]; $( "#form" ).nod( metrics );
However if we want people to specifically click on a particular radio button, we do (line 2 is still important)
var metrics = [ ['[name=a]', 'presence', 'You must click on at least one radio button'], ['#bar', 'exact:a1', 'You must click on *this* radio button'] ]; $( "#form" ).nod( metrics );
Conversely we can use the keyword not instead of exact.
Notice name attribute is mandatory on the input fields for all of these.
Ajax checking
Yes, it works. Here's some code:
var getFn = function( value ) { $.get('check_email.php', value); }; var metrics = [ ['#email', getFn, 'This email is already in use'] ]; $( "#form" ).nod( metrics );
Nod.js will take whatever response it gets from the server and eval it (if possible) to a boolean and use that as an indicator for whether the input is valid. This means that a "truthy" responses like "true", 1, true, "foo" will all return true (the field is valid) and conversely "false", 0, false will return false and be interpreted as if the field is not valid.
Also, if your submit button has data-loading-text, this will be swapped while the check is going on if it was initiated by a click of that button (and swapped back when done, regardless of errors).
Notice This feature is all very beta'ish and kind of hard to test fully. So if you find any errors or things that could be handled more gracefully, then I'd appreciate the feedback.
Email validation
Don't use this. Validating emails should be done backend (by sending an email) and not frontend. I've used the most lax regex for checking emails that I could find (RFC822) so as to err on the side of letting too many emails through rather than rejecting valid emails; but really, you ought not to use frontend email validation at all.
That said, the ones who write the code are not always the ones who get to decide which features to implement, so I've included the feature regardless of what I think about its use. Hope it makes your life a little better.
Silent Submit
if you have set silentSubmit : true, then the form won't submit. Instead you need to listen for the event on the form itself:
var submitFn = function( event, data ) { console.log( data ); } $( '#form' ).on( 'silentSubmit', submitFn );
This is used mainly (only?) if you want to submit your form by ajax.
Broadcasting
Say you want to log to your server everytime users make errors in your fields, then set broadcastError : true in your options object and listen for nod_error_fired on the window oject, like this:
var log_error = function( event, data ) { console.log( data.el ); console.log( data.msg ); } $( window ).on( 'nod_error_fired', log_error );
As you can see, you'll get an object with the element (actually the $(el)) and one with the error message.