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
Nod is not targeted directly at Bootstrap, but it should work fairly well with the newest versions (and probably older ones too).
npm install nod-validate
The examples you see below are made specifically with Bootstrap in mind, but what isn't directly clear from the examples, is that I had to do a small modification before starting, to get the colors and check mark (or cross) working properly. The problem is that the container (the parent of the element) is required to have the class "has-success" or "has-error" in Bootstrap which nod does not do by default. Here's a quick solution:
nod.classes.successClass = 'has-success';
nod.classes.errorClass = 'has-error';
This is basically overwriting nod's default classes for the parent, which is exactly what you want to do in this case.
Simple validation of email, password, a "must check" checkbox, and disabling the submit button unless all input elements have valid inputs.
var myNod = nod(); myNod.configure({ submit: '.submit-btn', disableSubmit: true }); myNod.add([{ selector: '.email-input', validate: 'email', errorMessage: 'That is not an email' }, { selector: '.password-input', validate: 'min-length:3', errorMessage: 'Should be at least 3 characters long!' }, { selector: '.checkbox', validate: 'checked', errorMessage: 'You must check me!' }]);
You can make one "rule" to target more than one element (in this example .name can not be empty), and one element can have multiple checks attached to it (#first-name must both contain something, and can not be "Captain").
var myNod = nod(); myNod.add([{ selector: '.name', validate: 'presence', errorMessage: 'Don\'t leave empty.' }, { selector: '#first-name', validate: 'not:Captain', errorMessage: 'You are not a captain! (I think)' }]);
There are two ways to do this. If the function is only needed once, just add it to your validate
property (first element); but if it is needed across your platform, it will make sense to add it to the general library and reuse it (second example).
var myNod = nod(); // First the simple use case of just one function used once. myNod.add({ selector: '#divBy2', validate: function (callback, value) { var number = parseInt(value, 10); callback(number % 2 === 0); }, errorMessage: 'Must be disible by two' }); // Here we are adding our own function. Notice we take a parameter, // that can later be configured when the function is used. nod.checkFunctions.divByX = function (x) { x = parseInt(x, 10); return function (callback, value) { var number = parseInt(value, 10); callback(number % x === 0); }; }; myNod.add({ selector: '#divBy3', validate: 'divByX:3', errorMessage: 'Your number must be divisable by 3' });
It can work with contentEditable
if you provide nod with keyup
as a triggerEvent
.
var myNod = nod(); myNod.add({ selector: '.some-div', validate: 'contains:Hello', errorMessage: 'Must contain "Hello"!', // can be an array of events if you need more triggerEvents: 'keyup' });
Here we are check whether a checkbox has been ticket, and if so, we check the value if it is a valid email. We also tell nod to listen for events from the checkbox (via triggeredBy
) and run the check whenever it triggers an event.
var myNod = nod(), // The raw dom element spamCheckBox = nod.getElement('.send-spam-checkbox'), // Knowing this, requires reading the source code checkEmail = nod.checkFunctions.email(); myNod.add({ selector: '#spam-mail', triggeredBy: spamCheckBox, validate: function (callback, value) { if (spamCheckBox.checked) { // Here you can just do any kind of check // you like. No need to use one of the // predefined functions. checkEmail(callback, value); } else { // If checkbox isn't checked, then it // doesn't matter if #spam-mail is filled // out or not, so we just return true to // indicate that the element is valid. callback(true); } }, errorMessage: 'If you checked the checkbox, then you must fill out the input field.' });
Just a quick example to show that you can listen in on the checks as they are happening.
var myNod = nod(), jsonResult = document.getElementById('json-result'); myNod.configure('tap', function (result) { // This can't be stringified, so I'll // replace in this example. result.element = '[ The raw dom element being checked ]'; jsonResult.innerHTML = JSON.stringify(result, null, 4); }); myNod.add({ selector: '#tap-input', validate: 'between-length:5:10', errorMessage: 'Must be between 5 and 10 characters long.' });
The library is about as flexible as I could get away with, and can do a lot more than what you find just above. The full documentation is on Github, and don't be afraid to open an issue or shoot me a message if you have any problems or wishes (that aren't too specific to your case).
Fork me