patternphpMinor
Ajax form validation
Viewed 0 times
formajaxvalidation
Problem
This is my first ever attempt at Ajax form validation, and everything works as expected, the final true example will hold a lot more input fields than in my testing scripts which are below.
The file is expected to get a lot bigger as in my testing I have only used 3 input fields, how can I improve on this:
HTML file
As you can see in the event of an onblur on the input fields I call the function ajax. I also send with the function a parameter which is exact to the id. Here is my function:
JavaScript
Here is what I have tried to do:
-
With the id that I send with the function I assign the value of the input field to a variable named value.
-
Using the same id I then assign a loading div which contains a gif image in my css.
-
Depending on the id send the correct request with the correct na
The file is expected to get a lot bigger as in my testing I have only used 3 input fields, how can I improve on this:
HTML file
Login Details
Your Email:
Password:
Account Details
Your Username:
As you can see in the event of an onblur on the input fields I call the function ajax. I also send with the function a parameter which is exact to the id. Here is my function:
JavaScript
function ajax (id) {
var value = $('#' + id).val();
$('#' + id).after('');
if (id === 'email') {
$.post('http://www.example.com/ajax.php', {email: value},
function (response) {
$('#email_error, #email_success').hide();
setTimeout(function(){
$('.loading').hide();
finish_ajax (id, response);
}, 1000);
});
}
if (id === 'password') {
$.post('http://www.example.com/ajax.php', {password: value},
function (response) {
$('#password_error, #password_success').hide();
setTimeout(function(){
$('.loading').hide();
finish_ajax (id, response);
}, 1000);
});
}
if (id === 'username') {
$.post('http://www.example.com/ajax.php', {username: value},
function (response) {
$('#username_error, #username_success').hide();
setTimeout(function(){
$('.loading').hide();
finish_ajax (id, response);
}, 1000);
});
}
return false;
}
function finish_ajax (id, response) {
$('#' + id).after(response).fadeIn(2000);
}Here is what I have tried to do:
-
With the id that I send with the function I assign the value of the input field to a variable named value.
-
Using the same id I then assign a loading div which contains a gif image in my css.
-
Depending on the id send the correct request with the correct na
Solution
Here's a few things I can observe at first glance:
HTML
-
-
I don't know about your visual aspect, but you should use CSS to format your elements and keep HTML to a minimum.
-
Your password field should have the type password as to allow the browser to obfuscate the characters being typed.
-
If you're using jQuery, you're better of going with the .blur() event instead of giving
Your HTML form would become something like:
JQUERY
Your jQuery currently uses the same code over and over, the best option is always to make scripts as generic as possible, to minimize the amount of code that as to be downloaded and interpreted by the browser. Also, in future maintenance, you'll find it easy to deal with a small generic code then a large element specific one.
-
As mentioned above, with the jQuery
-
Instead of having an
-
No need for specific error elements for each input subjected to validation, use classes and target then thru the
-
If you are appending the element
Your jQuery code to validate the above form would become something like:
PHP
Your PHP code falls under the same issues as the jQuery code, that is, repeating several chunks of code that latter on will prove difficult to maintain.
-
If you're using a
-
Perform some cleanup to the values before using them.
-
Since you're querying the same table, having the field passed along with the value, proves useful to have a single database line to maintain instead of several across the script.
You can choose to mascaraed the field name if your really want to obfuscate what's being done.
-
When using many
-
If the HTML that this script is outputting is the same, changing only the text and a class, best is to make use of variables to store the desirable values and have one single like with the script output.
Will prove useful when dealing with problems, having to "upgrade" the script, etc.
Your PHP code would become something like:
The above notes should give you an overall improvement on your form validation, leading to a valid code and a better solution for future maintenance.
I haven't tested any of it, but it should be working.
Validating Code:
This links should prove useful as to validate your code and warn you about common mistakes:
HTML
-
form elements don't accept input fields as direct child’s, so you should place your submit button inside a wrapper element.-
I don't know about your visual aspect, but you should use CSS to format your elements and keep HTML to a minimum.
-
Your password field should have the type password as to allow the browser to obfuscate the characters being typed.
-
If you're using jQuery, you're better of going with the .blur() event instead of giving
onblur attribute to all elements subjected to validation.Your HTML form would become something like:
Login Details
Your Email:
Password:
Account Details
Your Username:
JQUERY
Your jQuery currently uses the same code over and over, the best option is always to make scripts as generic as possible, to minimize the amount of code that as to be downloaded and interpreted by the browser. Also, in future maintenance, you'll find it easy to deal with a small generic code then a large element specific one.
-
As mentioned above, with the jQuery
.blur() function, you can bind the event to all inputs inside the target form and start creating a more generic validation solution.-
Instead of having an
if statement to ascertain the element subject to validation, send to the PHP file the field collected and its value.-
No need for specific error elements for each input subjected to validation, use classes and target then thru the
input id attribute, that in conjunction with a generic class for messages gives your the target element for the user messages.-
If you are appending the element
.loading to the form, you should also remove it when not needed. If the user keeps triggering the blur in the same input field, the element .loading keeps being added and you end up with tons of them.Your jQuery code to validate the above form would become something like:
$('#myForm input').blur(function() {
var id = $(this).attr("id");
$('#' + id).after('');
$.post('http://www.example.com/ajax.php', {field:id, value:value}, function (response) {
$('.'+id+'.msg').hide();
setTimeout(function() {
$('.loading').remove();
finish_ajax (id, response);
}, 1000);
});
});
function finish_ajax (id, response) {
$('#' + id).after(response).fadeIn(2000);
}PHP
Your PHP code falls under the same issues as the jQuery code, that is, repeating several chunks of code that latter on will prove difficult to maintain.
-
If you're using a
POST method, check for it and the specific variables necessary to execute the script, otherwise, bailout.-
Perform some cleanup to the values before using them.
-
Since you're querying the same table, having the field passed along with the value, proves useful to have a single database line to maintain instead of several across the script.
You can choose to mascaraed the field name if your really want to obfuscate what's being done.
-
When using many
If elseif else statements, the best option is to migrate to a switch case statement. Easy to maintain, read and "upgrade".-
If the HTML that this script is outputting is the same, changing only the text and a class, best is to make use of variables to store the desirable values and have one single like with the script output.
Will prove useful when dealing with problems, having to "upgrade" the script, etc.
Your PHP code would become something like:
if (isset($_POST["field"]) && isset($_POST["value"])) {
$field = cleanStr($_POST["field"]);
$value = cleanStr($_POST["value"]);
$q = $dbc -> prepare("SELECT ".$field." FROM accounts WHERE ".field." = ?");
$q -> execute(array($value));
$msgType = "error";
switch($field) {
case "email": {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$message = "This is not a valid email!";
} elseif ($q -> rowCount() > 0) {
$message = "Email already owns an account!";
} else {
$message = "Email success!";
$msgType = "success";
}
}
break;
case "password": {
if (strlen($_REQUEST['password']) rowCount() > 0) {
$message = "Username already taken";
} else {
$message = "Username available!";
$msgType = "success";
}
break;
}
default:
echo "The field could not be identified!";
break;
}
echo ''.$message.'';
} else {
header('Location: http://www.projectv1.com');
exit();
}
function cleanStr($str) {
return filter_var(trim($str),FILTER_SANITIZE_STRING);
}The above notes should give you an overall improvement on your form validation, leading to a valid code and a better solution for future maintenance.
I haven't tested any of it, but it should be working.
Validating Code:
This links should prove useful as to validate your code and warn you about common mistakes:
- HTML: Validating HTML using the W3C Ma
Code Snippets
<form id="myForm" action="#" method="post">
<fieldset>
<legend>Login Details</legend>
<label>Your Email:</label>
<input id="email" name="email" type="text" />
<label>Password:</label>
<input id="password" name="password" type="password" />
</fieldset>
<fieldset>
<legend>Account Details</legend>
<label>Your Username:</label>
<input id="username" name="username" type="text" />
</fieldset>
<p>
<input class="submit" type="submit" value="Create Account" />
</p>
</form>$('#myForm input').blur(function() {
var id = $(this).attr("id");
$('#' + id).after('<div class="loading"></div>');
$.post('http://www.example.com/ajax.php', {field:id, value:value}, function (response) {
$('.'+id+'.msg').hide();
setTimeout(function() {
$('.loading').remove();
finish_ajax (id, response);
}, 1000);
});
});
function finish_ajax (id, response) {
$('#' + id).after(response).fadeIn(2000);
}if (isset($_POST["field"]) && isset($_POST["value"])) {
$field = cleanStr($_POST["field"]);
$value = cleanStr($_POST["value"]);
$q = $dbc -> prepare("SELECT ".$field." FROM accounts WHERE ".field." = ?");
$q -> execute(array($value));
$msgType = "error";
switch($field) {
case "email": {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$message = "This is not a valid email!";
} elseif ($q -> rowCount() > 0) {
$message = "Email already owns an account!";
} else {
$message = "Email success!";
$msgType = "success";
}
}
break;
case "password": {
if (strlen($_REQUEST['password']) < 6) {
$message = "Your password is not long enough.";
} else {
$message = "Password success!";
$msgType = "success";
}
}
break;
case "username": {
if (strlen($_REQUEST['username']) < 3) {
$message = "Has to be at least 3 characters";
} elseif ($q -> rowCount() > 0) {
$message = "Username already taken";
} else {
$message = "Username available!";
$msgType = "success";
}
break;
}
default:
echo "The field could not be identified!";
break;
}
echo '<div class="'.$field.' msg '.$msgType.'">'.$message.'</div>';
} else {
header('Location: http://www.projectv1.com');
exit();
}
function cleanStr($str) {
return filter_var(trim($str),FILTER_SANITIZE_STRING);
}Context
StackExchange Code Review Q#4925, answer score: 3
Revisions (0)
No revisions yet.