Validating and Submitting a form using Javascript + Ajax - javascript

Here's what I'm trying to do.
When the 'Submit' form is clicked on my form, a javascript function will loop through all the fields of the form.
For each field a function will be called which would return true/false to indicate if it was filled in correctly or not.
If a false is returned, it shows an error message next to that field.
If all fields are correct, it submits the form. If not, it doesn't submit.
Here's the tricky part. While most of the validation is being done via javascript, the username and email need to be validated via ajax to see if the username/email is already in use or not.
The structure i'm currently using for this ajax function is something similar to this:
function validateSomething()
{
var valid;
$.post("something.php", {x:y},
function(data)
{
if (isSomething(data))
valid=true;
//Here referring to the valid variable
//set outside this function, in the
// parent function
else
valid=false;
});
return valid/
}
But that currently doesn't work.
What can I do to make it work, i.e can I stop the validateSomething() function from returning a value until its set to true/false by the inner function?
Would something like this work:
function validateSomething()
{
var valid="unset";
$.post("something.php", {x:y},
function(data)
{
if (isSomething(data))
valid=true;
//Here referring to the valid variable
//set outside this function, in the
// parent function
else
valid=false;
});
//Loop without returning until valid is set to true or false
while (valid=='unset')
{
//Do nothing?
}
return valid/
}

You can force the ajax-call to wait with async: false.
Like this using jquery:
function validateSomething() {
var valid;
$.ajax({
url: "something.php",
data: {x: y},
type: "GET",
async: false, // this makes the ajax-call blocking
dataType: 'json',
success: function (response) {
valid= response.valid;
}
});
return valid;
}
However, the big win when using AJAX is that it is asynchronous. This synchronous call might lock up the browser while it is waiting for the server.

You probably don't want to. (Or more appropriately, "Go for it, but be careful when doing so.")
Validating via AJAX is hip and slick and awesome. But it is -not- a substitute for validating server-side. And AJAx validation is -not- server-side validation. I can take the return of your function that says false and flip it to true and submit the form happily, even though you checked to make sure the username wasn't taken 'on the server'. Javascript runs on the client and can't be trusted.
Any validation you do via an AJAX call must be re-done on the server when you actually submit the form.
If you do that, then yea, AJAX validation is, again, hip and slick and awesome. So go for it. To submit a form using javascript (e.g. in the AJAX call-back handler function) you would say:
if(formwasValid)
{
document.getElementById('idOfForm').submit();
$('#idOfForm').submit(); //jQuery
}
else
{
alert('Invalid text');
}

I stopped doing extensive form validation on the client side as the code has to be duplicated on the server side anyway.
On the client-side, I just do some basic syntax checking of fields via regular expressions. These checks will be immediately triggered when the user starts typing, but they just give a visual notice as to when something went wrong (red border, different background color, a red 'X' next to the field...).
I don't prevent the user from submitting even invalid forms: Then, the server-side code with it's more detailed checks gets to work, which can easily restructure the form to separate valid from invalid fields and generate in-depth explanations as to why a check failed.

Related

Prevent user to send empty fields

My jQuery validation form warns user if he tries to send empty data if he clicks "Next" button.
Anyway, user still able to send empty data by pressing Enter.
So I used code below, it makes pressing Enter same with clicking "Next" button;
// this script makes pressing Enter gives error. But empty data still goes to database.
$('.form-horizontal').keypress(function (event) {
if (event.which === 13) {
$(".next").trigger('click');
}
});
This code only prevents user to go next step. But when user hits the Enter data being written to database even though he sees "Error Message".
*
Well, server-side verification prevents that easily. But why it's necessary keep server busy with that if we can prevent earlier?
Here is JsFiddle you can test the whole thing:
http://jsfiddle.net/6zu2vsj7/3/
*
Is there any way to make it work without keeping servers busy with empty fields? And I don't want to prevent user pressing Enter because this is not cool at all and not good for user experience.
You can add a condition to check whether the form is valid or not before you sending the data to server as below. hope this helps...
// Let's act like we send to database.
$(function(){
$('input[type=submit]').click(function(){
if($("#myform").valid()){
$.ajax({
type: "POST",
url: "sent.php",
data: $("#myform").serialize(),
beforeSend: function(){
$('#stepsuccess').html('Sent to the database. Strange.');
},
success: function(data){
$('#stepsuccess').html(data);
}
});
}
});
});
You just need to prevent the default behavior for that event
you can use this
$('.form-horizontal').keypress(function (event) {
if (event.which === 13) {
event.preventDefault();
$(".next").trigger('click');
}
});
Try this:
$(".form-horizontal").submit(function(e){
//do somethings or other validations
return false;
});
well! server side validation is necessary because client side validation is just for normal users! not hackers and robots! got it?!
in fact client side validation can be easily pass.

Trouble updating a <div> after successful validation using jQuery Validation plug-in

I am validating a form using the jQuery Validation plug-in, and I'm having some trouble updating a <div> with the status once the form is submitted (called using submitHandler). Once the user clicks to submit the form, it should update the #inviteStatus element with a status ("Adding user"). Then, once the response is received from the server (1-2 seconds) it should update #inviteStatus again with a result ("Success" or "Fail"). However, my script is jumping directly to the latter update ("Success" or "Fail"), and skipping the first "Adding user" update.
http://jsfiddle.net/bhall7x/Mf7sq/4/
I tried inserting a delay(5000); after the first <div> update, but the script seems to just stop at that point, and never continues on to the second result update message.
Any ideas why this is happening? Thanks!
UPDATE: I've created an updated Fiddle that has the actual code that I'm using. I can't get the .ajax() query to actually work on JS Fiddle, but this way you can see what I'm trying to accomplish. Basically, I'd like to first update #inviteStatus, show it, then
update it with the results of my .ajax() query. Here's the code I'm using in the submitHandler of the jQuery Validation plug-in after the form is successfully validated:
// form successfully validated, provide user notification
$("#inviteStatus").html("<div class=\"alert alert-info\">Adding user</div>");
$("#inviteStatus").show(500);
// get form values
var postData = $(form).serializeArray();
// submit form
$.ajax({
type : "POST",
data : postData,
async : false,
cache : false,
url : "inviteScript.php",
success: function(result) {
// Provide the results of the ajax call
$("#friendInviteStatus").html(result);
$("#friendInviteStatus").show(500).delay(5000).hide(500);
}
});
You need to add an anonymous function to the show() call instead of altering the html on a different line.
$("#inviteStatus").show(500);
// submit form here via ajax() call
$("#inviteStatus").html("<div class=\"alert alert-success\">Success!</div>");
Should be
$("#inviteStatus").show(500,function() {
// submit form here via ajax() call
$("#inviteStatus").html("<div class=\"alert alert-success\">Success!</div>");
});
http://jsfiddle.net/Mf7sq/7/
it is working fine, to simulate the ajax you need to give a delay
// Form actions
$("#addForm").validate({
debug: true,
rules: {
invitee: "required"
},
messages: {
invitee: "Please enter a username"
},
submitHandler: function (form) {
$("#inviteStatus").html("<div class=\"alert alert-info\">Adding user</div>");
$("#inviteStatus").show(500);
// submit form here via ajax() call
//simulate the ajx call
setTimeout(function () {
$("#inviteStatus").html("<div class=\"alert alert-success\">Success!</div>");
$("#inviteStatus").show(500).delay(5000).hide(500);
}, 2000)
}
});
Demo: Fiddle
Another slightly modified version is http://jsfiddle.net/arunpjohny/9jLb5/2/ - It is not recommended since it delays sending the ajax request till the message is completely shown
I was actually able to get this to work by removing the async:false on the .ajax() call.

JS/JQuery/PHP - How to echo errors on form validate failure, and jump to div on success?

I have a fixed-position form that can be scrolled out onto the document and filled out anywhere on the page. If they fail to fill out the form properly, the errors are currently echod out onto the form, which is the intended design for that aspect. What I don't currently know how to do is, if the form is completed and $errors[] is empty, to use jQuery scrollTop() to jump down to the bottom.
Could anyone help me out with this? Current javascript involved is:
$("#A_FORM_submit_button").click(function() {
$("#FORM_A").submit( function () {
$.post(
'ajax/FORM_A_processing.php',
$(this).serialize(),
function(data){
$("#A_errors_").html(data);
}
);
return false;
});
});
The PHP involved is simply
if (!empty($errors)){
// echo errors
} else { // echo success message} <-- would like to jump to div as well
edit-- for clarity: not looking to make the page jump happen in the php file, so much as return a value for the jq $.post function to check and then perform an if/else
I might be jumping the gun here but I believe your design is wrong which is why you are running into this problem.
The ideal way of handling form validation is to validate forms via Javascript and when users enter in their information you immediately show some indicator to ask them to correct it. As long as the validation is incorrect, you should not be accepting a form request or making any AJAX calls.
In the off-chance that they do successfully send the data, you should be doing a validation check via PHP as well which, if failed, would redirect to the original page with the form. From there you could do whatever error handling you want but ideally you would retain the information they entered and indicate why it was wrong (Javascript should catch this but I guess if it gets here the user might have JS off or your validation logic might be wrong)
If I understand correctly, it seems like you are doing your error handling with Javascript (that's fine) but showing the error via PHP. As Hydra IO said don't confuse client-side and server side. Make them handle what they need to handle.
Hope this helps.
#aug described the scenario very clearly.
In code it translates in something like this
$('form').submit(function(){
form_data = $(this).serialize();
if(!validate(form_data))
{
// deal with validation, show error messages
return false;
}
else
{
// Submit form, either via Ajax $.post() or by just returning TRUE
}
});
The validate() function is up to you to work out.

Checking for duplicate username

I am doing a registration page, for my mobile app, and want to check for duplicate usernames entered by the user/client
I have a button on the page that when clicked, checks availability of the username. However I would like to also incorporate that automatically, if not already done so, when the client clicks submit/go to step 3,
I want to perform the check for duplicate usernames using Ajax and if there exists a duplicate, then refresh the SAME page with the error message for duplication, else proceed to step 3.
In my HTML file I have some js that does the following:
$("#check-username").click(function() {
(...this works as I am able to click the CHECK button
and see if the username exists)
I have another js file, that is sourced in my HTML that does the following:
submitHandler : function() {
$("#reg1").hide();
$("span#step").html("2");
$("#check-username").click;
$("#reg3").show();
scrollTop();
}
When I click on Go to next step which is reg3, It does not do the validation for check-username. Is my method/syntax for calling check-username correct?
$("#check-username").click;
^^----- Missing Braces
supposed to be
$("#check-username").click();
The problem is you need to go to step 3 only after the validation ajax request returns from the server. You also are going to need to look at the response from the server to see if it's a duplicate. For example:
$("#check-username").click(function() {
validateUser();
});
function validateUser(){
return $.ajax({
url: '/path/to/validate'
});
}
And your submit handler stuff:
submitHandler : function() {
$("#reg1").hide();
$("span#step").html("2");
validateUser()
.done(function(r){
//for example...
if(r.isValidUser){
$("#reg3").show();
scrollTop();
}
});
}

How to specifically validate a certain form field using Jquery Validation plugin

I'm using the Jquery Validation plugin to validate my form on the client before submitting.
There is a specific field in my form that I want to validate using ajax to the server, once the user has filled out that field (onblur).
(Basically it's the username field, I want to check on the server if the username is available and show a message accordingly)
Here is the code I'm using to validate my form:
$(document).ready(function()
{
$("#signupForm").validate({
submitHandler: ajaxSubmitForm});
});
(ajaxSubmitForm is just the js code that submits the form)
How can I use the Jquery Validation plugin to have the username field send its value to the server (using ajax) when it has changed and have the server return a result that somehow marks that field as valid on the client so the rest of the validation works?
Thanks
You can do this using the remote rule on that element. You'd apply like so:
$('#signupForm').validate({
rules: {
username: {
remote: 'check_username.php' // this is the service page that returns true/false
}
}
});
Then to trigger the validation on blur, you add the following:
$('input[name="username"]').on('blur', function() {
$('#signupForm').validate().element(this); // this triggers the single element validation
});
submitHandler won't fire until the form is submitted for the first time. If you want to check username uniqueness while the user is filling out the form for the first time, you'd need a separate function. The example below assumes you have a page that runs a SQL query to see if the provided username exists in the database, then returns a json string like "{taken:false}" if the username is unique
$('#yourForm [name="username"]').on('blur',function(){
var username = $(this).val();
$.get('check/username.php',{username:username},function(data) {
if(data.taken) {
// highlight the field and indicate that the username is already taken
}
},'json');
}
The specifics of the call to $.get would depend on how your backend is set up. But in general, the process would go:
user enters a username
user blurs out of field
$.get or $.ajax call is made to the server to check uniqueness of username
if the response from the server indicates that the username is not unique, handle your validation (higlight the field, add an X icon, etc) and either
prevent form submission until the username IS unique, or
let the form submit and return an error for duplicate username
UPDATE
If you want to create a new rule for the validation plugin, you can do something like:
function isUsernameUnique(username,field) {
var unique = false;
$.ajax({
url: 'path/to/usernameCheck/',
data: { username: username },
async: false,
success: function(data) { unique = data.unique; }
});
return unique;
}
$.validator.addMethod(
'uniqueUsername',
isUsernameUnique,
'That username is already in use. Please choose a unique username.'
);
Then, in your form's validate function:
$('#yourForm').validate({
...
rules: {
username: { uniqueUsername: true }
...
}
...
});
And, a separate blur function for your username field:
$('[name="username"]').on('blur',function(){
var unique = isUsernameUnique($(this).val(),$(this));
if(!unique) {
// handle error
}
});
This lets you reuse the same function for both your pre-submit validation and your validation plugin. However, I see two issues here:
1 - After your first submit, $.fn.validate() will eagerly validate your username field, meaning the blur event on the username field is no longer required. perhaps you can disable it after the first submit to prevent unnecessary ajax calls
2 - It's not 100% DRY, as you'll need to do your own error handling in the blur event handler

Categories