HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Simple validation script

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scriptsimplevalidation

Problem

I'm playing about with JavaScript and wanted to create a simple validation script.

It works ok but is a bit clunky. How could I improve it?

var el = document.getElementById("username");
var el_pwd = document.getElementById("password");
var el2 = document.getElementById("feedback");
var el3 = document.getElementById("ok");
var el4 = document.getElementById("ok2");

function checkUsername() {
var username = el.value;
var password = el_pwd.value;
if((username.length = 5) & (password = 5) {
el3.style.display="block";
} else {
    el3.style.display = "none";
 }
}

function passwordOK() {
var password = el_pwd.value;

if(password.length >= 7) {
el4.style.display="block";
} else {
    el4.style.display = "none";
 }
}

function feedBack() {
el2.className = 'tip';
el2.textContent = "The username MUST be at least 5 characters";
el2.style.color = "blue";
}

el.addEventListener("focus", feedBack, false);
el.addEventListener("blur", checkUsername, false);
el.addEventListener("blur", usernameOK, false);

el_pwd.addEventListener("focus", checkPassword, false);
el_pwd.addEventListener("blur", passwordOK, false);




`var el = document.getElementById("username");
var el_pwd = document.getElementById("password");
var el2 = document.getElementById("feedback");
var el3 = document.getElementById("ok");
var el4 = document.getElementById("ok2");

function checkUsername() {
var username = el.value;
var password = el_pwd.value;
if ((username.length = 5) & (password = 5) {
el3.style.display = "block";
} else {
el3.style.display = "none";
}
}

function passwordOK() {
var password = el_pwd.value;

if (password.length >= 7) {
el4.style.display = "block";
} else {
el4.style.display = "none";
}
}

function feedBack() {
el2.className = 'tip';
el2.textContent = "The username MUST be at least 5 characters";
el2.style.color = "blue";
}

el.addEventListener("focus", feedBack, false);
el.addEventListener("blur", checkUsername, false);
el.addEventListe

Solution

Validation gone wrong

Every piece of code you write should solve a problem. Every good piece of code you write should solve a problem so small it has nearly no dependencies. So often, you'll end up writing a lot of little pieces of code in order to create beautiful software.

Take for instance a Calculator. Instead of cramming everything in one huge function. There will probably be tons of little methods that do as much as possible without knowing to much. A 'sum' method will have 2 arguments passed in, and return the sum. It couldn't care less where they come from.

Validation the right way

What you actually needed was some code that uses a validator to validate your usernames and passwords.

But what is a validator?

At it's core, a valdiator needs 2 things. It needs an input, and it needs a strategy to validate that input. It might even have a chain of strategies.

A Validator

First of, let's define our validator:

function createValidator(input, strategy) {
    var input = input,
        strategy = strategy;

    return {
        passes : function() {
            return strategy(input);
        }
    }
}


Now we can create our validators, we can start creating our strategies. For instance a LengthValidator strategy:

function createLengthValidator(min, max) {
    var minLength = min,
        maxLength = max || Infinity;

    return function(data) {
        return data.length = min;
    }
}


To use it we would do:

var usernameValidator = createValidator(
    document.getElementById("username").value,
    createLengthValidator(5)
);
var passwordValidator = createValidator(
    document.getElementById("password").value,
    createLengthValidator(7)
);


And then our check* functions:

function checkUsername() {
    if ( !usernameValidator.passes() ) {
        var feedback = document.getElementById("feedback");
        feedback.className = 'warning'; 
        feedback.textContent = "Username Not long enough yet..";
        feedback.style.color = "red";
    }   
}

function checkPassword() {
    if ( !passwordValidator.passes() ) {
        var feedback = document.getElementById("feedback");
        feedback.className = 'warning'; 
        feedback.textContent = "Password MUST be 7 or more characters";
        feedback.style.color = "red";
    }
}


Handle only the bare minimum

Your function checkUsername relies on the password (hunk?) and your checkPassword also checks the userName (hunk?). But they handle different criteria.

Your functions add a class, text and CSS. Woah, that's a lot. Let's refactor that using events.

Defining how it rolls

Defining the problem is always the hardest step. But somehow, a lot of people tend to skip this step. Don't.

What we want is the following:
We have an input-field. Every time the input loses focus (blur event) the input should be evaluated. If the given input is not correct, show an error message.

Our problem is defined in 3 sentences. Each sentence defines a smaller problem. The first part is easy:



The second part, a little harder. But still doable since we already have our validator:

var $username = document.getElementById('username');

$username.addEventListener('blur', function() {
    var usernameValidator = createValidator(
        $username.value,
        createLengthValidator(5)
    );
    if ( usernameValidator.passes() ) {
        //create a validatorPassed event
        var event = new CustomEvent('validatorPassed');
        $username.dispatchEvent(event);
    } else {
        //create a validatorFailed event
        var event = new CustomEvent('validatorFailed');
        $username.dispatchEvent(event);
    }
});


Wow, so much code. But why?

Here is why:

$username.addEventListener('validatorPassed', function() {
    var feedback = document.getElementById("feedback");
    feedback.textContent = "";
});

$username.addEventListener('validatorFailed', function() {
    var feedback = document.getElementById("feedback");
    feedback.className = 'warning'; 
    feedback.textContent = "Username Not long enough yet..";
    feedback.style.color = "red";
});


See how we have successful decoupled our code? Our validator now knows nothing about our html. It simply validates input. We then have 2 eventListeners that listen to the Validator and do html-editing accordingly.


Disclaimer: I wrote this code inside the text-editor and is written as an example. I don't expect you to go all the way as I have. But it gives you the idea ;) always keep track of that one rule:

First make it work, then make it fast and then make it nice.

Code Snippets

function createValidator(input, strategy) {
    var input = input,
        strategy = strategy;

    return {
        passes : function() {
            return strategy(input);
        }
    }
}
function createLengthValidator(min, max) {
    var minLength = min,
        maxLength = max || Infinity;

    return function(data) {
        return data.length <= max && data.length >= min;
    }
}
var usernameValidator = createValidator(
    document.getElementById("username").value,
    createLengthValidator(5)
);
var passwordValidator = createValidator(
    document.getElementById("password").value,
    createLengthValidator(7)
);
function checkUsername() {
    if ( !usernameValidator.passes() ) {
        var feedback = document.getElementById("feedback");
        feedback.className = 'warning'; 
        feedback.textContent = "Username Not long enough yet..";
        feedback.style.color = "red";
    }   
}

function checkPassword() {
    if ( !passwordValidator.passes() ) {
        var feedback = document.getElementById("feedback");
        feedback.className = 'warning'; 
        feedback.textContent = "Password MUST be 7 or more characters";
        feedback.style.color = "red";
    }
}
<input type="text" name="user_name" id="username" />

Context

StackExchange Code Review Q#63940, answer score: 11

Revisions (0)

No revisions yet.