Fork me

Nod v.2.0.3 A frontend validation plugin


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).

Practical info

A few examples

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

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!'
}]);

Multiple rules and targets

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)'
}]);

Using your own function to check the input

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'
});

Works with contentEditable

It can work with contentEditable if you provide nod with keyup as a triggerEvent.

Click here and edit me! I must contain the word "Hello" though
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'
});

Example of fairly complex checkbox to input element

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.'
});

Retrieving information

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.'
});

There's more

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