I was trying to validate username whether exist or not with the following code. But it somehow don't work to prevent the existing username.
**NOTE: checkusr2.php is a simple php to check wheter the username in database.
function verifyUser() {
var usr = $("#username").val();
$.ajax( {
type: "POST",
url: "checkusr2.php",
data: "username="+ usr,
success: function(msg) {
$("#txtHint").ajaxComplete(function(event, request, settings){
FormErrors = false;
if(msg == 'OK') {
FormErrors = true;
$('#formElem').data('username',FormErrors);
} else {
$('#formElem').data('username',FormErrors);
}
});
}
});
}
/** calling the function to check. **/
verifyUser();
if($('#formElem').data('username')){
alert('Username exist, please try another username.');
return false;
}
Use an http proxy like Charles, Fiddler, WireShark, etc... to view the ajax request you are sending and verify that the response is what you expect.
For one thing, you are making an asynchronous call (the A in Ajax) to get the response for whether the username exists. The check, immediately after the verifyUser call is being called as soon as you call the verifyUser and the the request to checkusr2.php may or may not have actually returned by then.
I have also never seen the ajaxComplete set inside of the success handler. I think you may want to change it like this:
function verifyUser() {
var usr = $("#username").val();
$.ajax( {
type: "POST",
url: "checkusr2.php",
data: "username="+ usr,
success: function(msg) {
if(msg != 'OK') {
alert('Username exists, please try another username.');
$("#username").val("");
}
};
});
}
Your problem is in trying to use verifyUser synchronously. The code seems fairly sound, the problem is that $.ajax executes asynchronously using XMLHTTPRequest. This means that your code immediately following the call to verifyUser cannot depend on the side effect of its completion.
What you need to do is run the verifyUser callback earlier (like, say, when the user un-focuses the username field), so that when it comes time to submit you've already got the result.
For example:
$('#username').blur(function() { verifyUser() });
A further change would be instead of preventing submit, you can make verifyUser show a div with a message next to the field when the username is invalid. You'd make these changes to your handler:
if(msg == 'OK') {
FormErrors = true;
$('#username_invalid').show();
} else {
$('#username_invalid').hide();
}
Then you could show the user the username cannot be chosen immediately, without wasting their time submitting it.
Try this
$("#txtHint").ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html' && xhr.responseHTML=="Ok") {
FormErrors = true;
$('#formElem').data('username',FormErrors);
} else {
$('#formElem').data('username',FormErrors);
}
})
Thanks for bringing up this .ajaxComplete() that I didn't know about. I think it will be of great help for me in the future.
But anyway I don't think it's what you want to use in this specific case:
function verifyUser() {
var usr = $("#username").val();
$.ajax( {
type: "POST",
url: "checkusr2.php",
data: {'username':usr},
success: function(msg) {
if ( msg != 'OK' ) {
alert('Username exist, please try another username.');
return false;
}
});
});
}
The function that you want to execute after the Ajax call must be passed as a callback of the Ajax function, otherwise, and even if you put it after your Ajax function, it will execute before the server's response.
Related
I need to validate a HTML form before executing the action attribute. But it gives me a hard time.
Please see the comment in the else statement, and the comment after returning false for an explanation of this issue
$(document).ready(function(){
$("#ajax-payment-form").submit(function() {
var str = $(this).serialize();
$.ajax({
type: "POST",
url: templateDir+"/payment_form/payment_process.php",
data: str,
success: function(msg) {
// Message Sent - Show the 'Thank You' message and hide the form
if(msg == 'OK') {
alert("success");
} else {
event.preventDefault(); // I have tried with or without this method
alert("fail");
}
}
});
return false; // when return false, the action will not execute. If false is removed the action will execute, even if event.precentDefault(); is called in the else statement.**
});
});
Thanks for your time,
Troels
Your ajax call is asynchronous. This means that this function is executed, and it doesn't wait for a response from the function before it proceeds forward. This means that return false; will always fire before the result of the ajax function returns to you. Given your current circumstances, the easiest thing to do is call this.submit() from within the success function, but always return false; under the default scenario. This will avoid recursion, and also the asynchronous call won't be problematic anymore.
$(document).ready(function(){
$("#ajax-payment-form").submit(function() {
var str = $(this).serialize();
$.ajax({
type: "POST",
url: templateDir+"/payment_form/payment_process.php",
data: str,
context: this, //needed to tell the ajax function that "this" belongs to the form, not the ajax call.
success: function(msg) {
// Message Sent - Show the 'Thank You' message and hide the form
if(msg == 'OK') {
alert("success");
this.submit(); //it's magic, john.
} else {
//no reason to prevent the default, as the form will automatically return false anyway.
alert("fail");
}
}
});
return false; //just leave this right here.
});
});
The issue is two fold: event is not declared in your function call, and that you are not submitting the form upon the success funtion. The logic of your submit event should be as follow:
Listen to submit event on the <form> element.
Prevent default form actions first, using e.preventDefault()
Make AJAX call. Depending on the outcome of the returned data, determine whether to proceed with submitting the form. I strongly suggest not using the deprecated jqXHR.success function, but the deferred functions jqXHR.done() or jqXHR.fail().
Also, you can always use console.log() to check your script, instead of relying on alert() which blocks downstream code execution. Here's the code:
$(function(){
$("#ajax-payment-form input[type='submit']").click(function(e) {
// Prevent form submission
e.preventDefault();
// Serialize data, make AJAX call
var str = $(this).closest('form').serialize();
$.ajax({
type: "POST",
url: templateDir+"/payment_form/payment_process.php",
data: str,
context: this // So that you can use $(this) later
}).done(function(msg) {
// If a response is received from your server
if(msg == 'OK') {
console.log('Validation passed, will submit form');
$(this).closest('form').submit();
} else {
console.log('Validation failed, will not do anything more');
}
}).fail(function() {
// Catch ajax errors here
console.log('AJAX error');
});
});
});
I am setting up a registration form.
This form has 7 fields that are being tested for validation.
2 of them have a special validation; I have an Ajax call to a PHP class where I send an email_string to this class, testing, if such an email already exists in my database (evading duplicates).
params = {};
params['source'] = 'checkEMail';
params['email'] = email
$.ajax({
type: 'POST',
url : 'some_class.php',
data : params,
success: function(msg)
{
if(msg > 0) /* email exists */
is_error = true;
}
});
And in my PHP Class I got something like this:
$final = mysql_fetch_assoc(foo);
echo ($final) ? 1 : 0;
I was testing the data and in fact - I get '1' if the email exists and '0' if it does not.
Funny thing is, that this snippet works fine AS LONG AS there are other errors in this form - like an empty username.
The "is_error" is a boolean that is set to false at the beginning of the script and if one validation fails, it gets true.
Then, finally, I got this:
if(is_error)
{
error.show();
error.empty().append('some html foo');
}
else
{
$('form').submit();
error.empty().hide();
}
So how can it be that I the form will be send although is_error is set to true?
Only reason I could think of is that the form is being send before the "is_error" is being testet - but the send of the form is at the very bottom of the script.
Oh and I am calling it this way:
<script type="text/javascript">
$("#reg_submit").click(function(event) {
event.preventDefault();
checkReg();
});
</script>
instead of having the if(is_error){ part at the end of the script, I would suggest you to do it in the ajax request completion to avoid race conditions:
$.ajax({
type: 'POST',
url: 'some_class.php',
data: params,
success: function(msg) {
if (msg > 0) /* email exists */
is_error = true;
},
complete: function() {
if (is_error) {
error.show();
error.empty().append('some html foo');
} else {
$('form').submit();
error.empty().hide();
}
}
});
Maybe it is caused by different output types that you are trying to match...
First, change your PHP output to
echo json_encode($final ? true : false);
Then, to work with JSON, I would add this line to ajax calling method, to be sure...
$.ajax({
type: 'POST',
dataType:'json',
...
success: function(msg)
{
if(msg!==true){
is_error = true;
}
}
});
I am using an Ajax request to post a form with Jquery.
$.ajax(
{
type: "POST",
url: "login.php",
data: $("#signin").serialize(),
dataType: "json",
cache: false,
success: function(data, textStatus) {
if (data.redirect) {
window.location.replace(data.redirect);
}
else {
$('#some').fadeOut(200);
$('#some2').fadeIn(200);
$("#some3").html(data.form);
$("#some").delay(2000).fadeOut(200);
$('#some2').delay(2800).fadeIn(300);
}
}
});
Now the ajax request will take place as soon as you click on a button "Login". The problem now is that if you press the button more than once the else case will be executed several times which will cause #some, #some2 and #some3 to fade out and in several times. So how could I check whether the request has allready been sent (without having to write something into my db)?
From here:
You can use .one() method and set it again in ajax callback.
function doAjax(){
// Your Ajax call.
$.ajax({..., complete: function() {
// Ajax call done, re-enabling the button/link
$("#buttonId").one('click', doAjax);
}, ...});
}
$("#buttonId").one('click', doAjax);
Make boolean flag, say, login_in_process, on login check this flag in true value. And check this flag on every click if it true then make empty return. In success and error callbacks set it in false state.
You can use a boolean value to record whether or not it has been clicked:
var loginClicked = false;
$('input_button_element').click(function(){
if (!loginClicked) {
loginClicked = true;
// your js here - you may want to add some visual feedback to the user also
}
});
You will have to store a boolean in a global scope, e.g. one stored on the window object:
if (!window.isClicked) {
window.isClicked = true;
...Do your ajax call here
}
Remember to ALWAYS restore the value of window.isClicked, not only in the success callback of ajax():
var jqxhr = $.ajax( ... )
.done(function() { })
.fail(function() { })
.always(function() { window.isClicked = false });
you can make a global var
var loginClick = false;
Inside your method you first check that value
if (!loginClick) {
loginClick = true;
//your ajax code;
}
I'm using jQuery and AJAX to validate my form when someone creates a new user on my website. I'm programming in OOP PHP, together with the jQuery and AJAX.
I'm using this code:
$.ajax({
type: "POST",
url: "includes/classes/handler.php?do=addLogin",
data: dataString,
success: function() {
$('.sideBarNewUserWrap').fadeOut();
}
});
return false;
But how do I return an error message, if the e-mail already exists?
Hope it's info enough, else I'll just add some more.
Thanks in forward :)
* UPDATE *
This is my PHP checking if email exists:
$email_count = mysql_num_rows($check_email);
if($email_count){
return false;
}
* UPDATE *
success: function(data){
if(data.error){
$('.sideBarNewUserWrap').fadeOut();
} else {
$('.sideBarNewUserError-email').fadeIn();
}
Now this looks pretty much as a failure because.
if(data.error) then it's okay?
Shouldn't it be something like:
if(date.error){
//Error message
}
And not the other way around?
Well, If I try to enter an email which already exists, it tells me as it should, but why does this work? In my eyes I'm doing something wrong here?
php:
$result = array('error' => true); // or $result = array('error' => false);
echo json_encode($result);
js:
success: function(response) {
if (response.error) {
// ...
}
}
You can get the response in the function:
$.ajax({
type: "POST",
url: "includes/classes/handler.php?do=addLogin",
data: dataString,
success: function(response) {
if (response == "ok")
{
$('.sideBarNewUserWrap').fadeOut();
}
else
{
// error happend
}
}
});
return false;
You can return string, int in PHP or even XML, JSON, whatever you want to validate on client side
You can return data by using an echo in your handler.php file.
To receive this in jQuery just place a parameter in the success function of the Ajax function.
success: function(returnedValue)
{
// Here you check if returned value e.g. "returnedValue == 1"
}
basically in the handler.php you should verify whether email already exists or not and then send to the client (at least) two different responses (eg. 0: email exists, 1:ok).
In the success callback you can read the response data so you can tell the user the operation status
I have a JQuery Function
(function ($) {
jQuery.fn.saveUser = function(destinationUrl) {
this.click(function() {
var formData = 'option=saveuser&'+$('form#save-user').serialize();
$.ajax({
type: 'POST',
url: 'process.php',
data: formData,
success: function(msg){
if(msg === 'empty') {
alert('Required Values Missing');
} else if(msg === 'duplicateEmail'){
alert('Email already exist');
} else {
window.location = destinationUrl;
}
}
});
});
}
now based on some actions and events, i redirect it to different pages, in this case i need it to redirect it to two different url.
1) reload the same page preserving all $_GET variables via URI
2) reload to the specified url.
the below jQuery code can redirect me to any specific url.
$('form#save-user button[name="save-user-close"]').saveUser(function() {
return 'index.php?users';
});
however i am not getting how do i make it redirect to the same page for example.
$('form#save-user button[name="save-user-close"]').saveUser(function() {
return location.reload(true);
});
i know the above code will not work, i am confused on how do i go with this?
You are never calling the function in your code, so it would not work whatever you put in the function. Intead of:
window.location = destinationUrl;
you should call the function, and let the function do the redirection:
destinationUrl();
(And you probably want to rename the parameter to reflect the change of usage.)
So your functions should do the redirection instead of returning the URL, so that you can use the reload method in the second one:
$('form#save-user button[name="save-user-close"]').saveUser(function() {
window.location = 'index.php?users';
});
and:
$('form#save-user button[name="save-user-close"]').saveUser(function(e) {
location.reload(true);
});
window.location.href=window.location.href;
or
location.replace(URL);
but preserving the variables u can approach querystring or session variables