patternjavascriptModerate
Simple validation script
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.addEventListe
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:
Now we can create our validators, we can start creating our strategies. For instance a LengthValidator strategy:
To use it we would do:
And then our check* functions:
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:
Wow, so much code. But why?
Here is why:
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.
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.