This is partly a continuation from this thread: jquery - return value from callback function (in post request) into the function its inside of?
because I updated the code, yet trouble persists. I'm validating a simple html form with jquery, and despite all my other if/else statements working, the ajax call never gets made. Here's the javascript code:
var pass_form = $('#pass_form');
pass_form.submit( valid_pass_sett );
function valid_pass_sett() {
//remove old errors - snipped
pass_old = $('input[name=pass_old]').val();
pass_new = $('input[name=pass_new]').val();
pass_confirm_new = $('input[name=pass_confirm_new]').val();
if (pass_old === "") {
//display error on form - snipped
return false;
} else if (pass_new === "") {
//display error on form - snipped
return false;
} else if (pass_new != pass_confirm_new) {
//display error on form - snipped
return false;
} else if (pass_new.length < 8) {
//display error on form - snipped
return false;
} else {
$.post("http://www.example.com/ajax/validate.php",{ // async validation
type: 'valid_old_change_pass',
pass_old: pass_old,
pass_new: pass_new
}, valid_pass_combo_callback);
alert('after the ajax call...');
}
return false; // cancel form submission
}
and here's the relevant part of the validate.php:
$username = $_SESSION['username'];
$pass_old = $_POST['pass_old'];
$pass_new = $_POST['pass_new'];
if (empty($pass_old) || empty($pass_new)) {
echo "invalid";
} else if (!User::valid_user_pass($username, $pass_old)) {
echo "invalid_old";
} else if (!Sanitize::is_legal_password($pass_new)) {
echo "invalid_new";
} else {
echo "valid";
}
When I'm debugging with Firebug, and all other form inputs are correct, the script gets to the ajax call, then submits the form, even though it's supposed to call the callback function. This is the code for the callback function:
function valid_pass_combo_callback( data ) {
if (data == 'valid') {
//only if the form is valid!
pass_form[0].submit();
}
else if (data == "invalid_old") {
//display error on form - snipped
}
else if (data == "invalid_new") {
//display error on form - snipped
}
else {
//it always jumps to here..., even though data *is* the correct value
}
}
EDIT redux: Ok, I fixed the error in my callback function, as seen in the first answer, and now, a bit of a different problem has emerged. I debugged the function valid_pass_combo_callback and it's getting the correct value from validate.php; in this case, invalid_old is the value being returned. When I debug, data is equal to invalid_old. However, the comparison fails... so the code always jumps to the last else statement, no matter what. Nothing happens, because there isn't any behaviour there, so why is the comparison always failing?
EDIT, SOLVED: I decided to forgo binding this function to submit, and instead bound to an onclick event for a button on the form (which I'm using in place of a submit button) and that solved the problem. Validation is called when the button is clicked, and if client-side validation passes, then the form is submitted to the server for validation there.
One problem here is you're invoking your callback, not passing the function itself:
$.post("http://www.example.com/ajax/validate.php",{ // async validation
type: 'valid_old_change_pass',
pass_old: pass_old,
pass_new: pass_new
}, valid_pass_combo_callback); // Remove (data) so the callback
// isn't invoked immediately.
Looking at your code you dont have to submit the form but make an ajax call but you say the form is getting submitted. I think there is some js error in the below peice of code because of which the form is getting submitted.
$.post("http://www.example.com/ajax/validate.php",{ // async validation
type: 'valid_old_change_pass',
pass_old: pass_old,
pass_new: pass_new
}, valid_pass_combo_callback(data));//Here is the issue, it will call the method right away
alert('after the ajax call...');
Why dont you prevent the default behavior of form submit.
function valid_pass_sett(e) {
e.preventDefaul();//This will ensure the form will never be submitted.
And in the callback method make a small change to unbind the submit handler and then submit the form. This is because we already have one submit handler and we dont want to call it next time when we submit in the below method.
function valid_pass_combo_callback( data ) {
if (data === 'valid') {
//only if the form is valid!
pass_form[0].unbind('submit').submit();
}
else if (data === "invalid_old") {
//display error on form - snipped
}
else if (data === "invalid_new") {
//display error on form - snipped
}
}
Related
I hope this isn't a duplicate; the other similar questions I read didn't help me solve my problem.
I'm receiving a blank response (i.e. data = "") from a jQuery Ajax call to my PHP script, used to validate a user's submitted CAPTCHA value. I'm using Cryptographp for my CAPTCHA, and it works as expected, so I'm thinking it's most likely an error either in my Ajax call or the PHP script.
Firebug showing correct POST values ('code' is the submitted CAPTCHA value to test):
code a
email a#a.com
emailtext a
firstname a
lastname a
phone
Ajax function called onsubmit to determine whether or not to submit the form:
function validateCaptcha()
{
// Assume an invalid CAPTCHA
var valid = false;
// The form containing the CAPTCHA value
var data_string = $('form#emailform').serialize();
// Make the Ajax call
$.ajax({
url: "captcha.php",
data: data_string,
type: "POST",
async: false,
success: function (data) {
if (data == "true")
{
valid = true;
}
alert ("data: " + data);
}
});
return valid;
}
captcha.php
<?
$cryptinstall="crypt/cryptographp.fct.php";
include $cryptinstall;
// Begin the session
session_start();
//Check if CAPTCHA values match
if(chk_crypt($_POST["code"]))
return true;
else
return false;
?>
My expectation is that the above snippet should return a response of simply "true" or "false," but perhaps this is not the case.
Any help pointing out my error would be greatly appreciated!
You need to use "echo" instead of "return" and write is as a string. return is for returning results of functions.
<?
$cryptinstall="crypt/cryptographp.fct.php";
include $cryptinstall;
// Begin the session
session_start();
//Check if CAPTCHA values match
if(chk_crypt($_POST["code"]))
echo "true";
else
echo "false;
?>
From your captcha.php you are not echoing/printing anything so it's returning nothing. Just replace your return true; and return false; with echo.
Browser can only receive something when you'll print something from the script.
if(chk_crypt($_POST["code"])) echo true; // 1
else echo false;// 0
or
if(chk_crypt($_POST["code"])) echo 'true'; // true
else echo 'false';// false
I've been on a problem for hours without finding any issue...
I have a registration form for users to create accounts. When the submit button is pressed a validateForm function is called.
In this function I do some javascript tests that work, but then I need to verify that the username is available. For this I created an external PHP file and call it using $.ajax.
Here is part of the code :
function validateRegistration(){
// Some tests....
// Check if username is already used
// Call external php file to get information about the username
$.ajax({
url: 'AjaxFunctions/getUsernameAjax.php',
data: "username=" + $("#username").val(),
success: function(data){
// Username already in use
if(data == "ko"){
// Stop validateForm()
}
// Username not used yet
else{
// Continue tests
}
}
});
// Other tests
}
My question is how can I make validateForm() return false from inside the $.ajax ?
Could I for instance declare a js variable before the Ajax part and set it with Ajax ?
I guess the answer is obvious but I'm absolutely new to Ajax and I can't get it...
Thanks a lot for your help!
To achieve this you can either do a synchronous ajax call like described in this answer, but that's something which is incredibly dangerous for the performance of your website.
Alternatively - and this is the right way - you should have an external variable whether the username is available, as soon as the user inputs something you do the request and if it's valid you change the variable otherwise you show an warning message. Next in your validateRegistration() function you only check the external variable (+ possible some form of callback, depending on where you call it from). The advantage being that the user can still continue doing things (like filling out the rest of the form) whilst the request is pending.
You could make a synchronous ajax call, instead of an asynchronous, as you're doing now. This means that the Ajax call will complete before the next lines of code are executed.
To do so in jQuery, just add async: false to your request object:
var someVariable;
$.ajax({
url: 'AjaxFunctions/getUsernameAjax.php',
data: "username=" + $("#username").val(),
success: function(data){
// Username already in use
someVariable = "something";
if(data == "ko"){
// Stop validateForm()
}
// Username not used yet
else{
// Continue tests
}
},
async: false
});
alert(someVariable); // should alert 'something', as long as the ajax request was successful
In the php, if you print out JSON like:
echo json_encode(array("ko"=>"good"));
shows up as:
{
"ko":"good"
}
then in the function it would be
if(data.ko == "good"){
//do stuff
}
This is how I normally do it. You can get the variable by using the name you used in the JSON so you can have other things if you need.
If the goal is to check a username availability, how about checking it as or just after the username is typed in. For example you could either bind it to the keyUp event for keystrokes or the blur event for when you leave the text box.
This would mean that by the time the user gets to the submit button, that part of the form would already be validated.
The traditional solution here is to pass a callback function to validateRegistration which expects a boolean value. Have the Ajax function call the callback function when it completes.
The onsubmit handler expects a return value immeidately, so performing an asynchronous test within your submit event handler is a fairly unituitive way to do things. You should instead perform the test as soon as possible (e.g. as soon as the user enters a username) and then store the result of username validation in a global variable, which is later checked at submit time.
// global variable indicating that all is clear for submission
shouldSubmit = false;
// run this when the user enters an name, e.g. onkeyup or onchange on the username field
function validateRegistration(callback) {
shouldSubmit = false;
// number of ajax calls should be minimized
// so do all other checks first
if(username.length < 3) {
callback(false);
} else if(username.indexOf("spam") != -1) {
callback(false)
} else {
$.ajax({
....
success: function() {
if(data == "ko") {
callback(false);
} else {
callback(true);
}
}
});
}
}
Now call validateRegistration with a function argument:
validateRegistration(function(result) {
alert("username valid? " + result);
if(result) {
$("#username").addClass("valid-checkmark");
} else {
$("#username").addClass("invalid-xmark");
}
shouldSubmit = result;
});
Now use the global variable shouldSubmit in your form's submit event handler to optionally block form submission.
Basically whats happening is I have a php form to send an email. There are several different validation steps all along the way, which all work great. What i'd like to do is have a javascript alert pop up if there is a validation error when the form is submitted. I have this working with the following php:
// Validate email
if(!filter_var($EmailFrom, FILTER_VALIDATE_EMAIL))
{
echo "<script language=javascript>alert('Please Use a Valid Email Address')</script>";
exit;
}
The alert pops up but the page redirects to domain.com/sendemail.php which leaves the user with a blank page. I'd really like to have the alerts pop up without reloading the page. How would I do this?
You can use ajax to accomplish this. But if you don't want to use ajax, instead doing an exit on error, you could redirect back to the form page along with a query string parameter.
header("Location: http://www.example.com/form.php?error=1");
And on your form page you could put the script withing php if. Something like
<?php if(isset($_GET['error']) && $_GET['error']==1): ?>
<script>
....
</script>
<?php endif; ?>
That would achieve what you are looking for. In fact you can perform multiple checks and set error based on your checks. But I would still suggest Ajax will give a better user experience.
Edit: Super easy solution, use jQuery form plugin : http://jquery.malsup.com/form/
I do something similar in some of my web apps, you might find it useful.
I do my validation server side and if I encounter an error I do this :
json_die(array(
'status' => 'error',
'message'=> 'Your error message'
));
and for success :
json_die(array(
'status' => 'success',
'message'=> 'Your success message'
));
The json_die is function is :
function json_die($array) {
header("content-type: application/json");
die(json_encode($array, true));
}
Then on the front end I do something like this:
$.post('/your_url', {
'your': vars
}, function (r) {
if(r.status == 'success') {
alert(r.message);
} else if (r.status == 'error') {
alert(r.message);
//handle error
} else {
alert('server exploded / no connection');
}
},'json');
This is a script I used in some forms I created to validate them fast. It's very simple and effective, I hope it helps you.
<script type="text/javascript">
function validate(){
emailfilter = /^([a-zA-Z0-9_\.\-])+\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
condition = 1;
mensaje = "Complete: ";
//Validate 1st input (Check if empty)
if (document.formname.forminput1.value.length==0){
condition = 0;
msg = msg + "-Input 1 is empty "
}
//Validate 1nd input (Check email)
if (!emailfilter.test(document.formname.forminput1.value)) {
condition = 0;
msg = msg + "-Input 1 has a invalid email adresss "
}
if (condition == 0){
alert(msg)
document.formname.forminput1.focus()
return 0;
}
//send
alert("Form sended.");
document.formname.submit();
}
</script>
A new problem emerged from this thread: jquery form validator never makes ajax call, in that the data returned from the ajax request is accurate, but it always fails on a comparison. This is the code that makes the ajax request:
var pass_form = $('#pass_form');
pass_form.submit( valid_pass_sett );
function valid_pass_sett() {
//remove old errors - snipped
pass_old = $('input[name=pass_old]').val();
pass_new = $('input[name=pass_new]').val();
pass_confirm_new = $('input[name=pass_confirm_new]').val();
if (pass_old === "") {
//display error on form - snipped
return false;
} else if (pass_new === "") {
//display error on form - snipped
return false;
} else if (pass_new != pass_confirm_new) {
//display error on form - snipped
return false;
} else if (pass_new.length < 8) {
//display error on form - snipped
return false;
} else {
$.post("http://www.example.com/ajax/validate.php",{ // async validation
type: 'valid_old_change_pass',
pass_old: pass_old,
pass_new: pass_new
}, valid_pass_combo_callback);
alert('after the ajax call...');
}
return false; // cancel form submission
}
this is the code that the request is submitted to:
$username = $_SESSION['username'];
$pass_old = $_POST['pass_old'];
$pass_new = $_POST['pass_new'];
if (empty($pass_old) || empty($pass_new)) {
echo "invalid";
} else if (!User::valid_user_pass($username, $pass_old)) {
echo "invalid_old";
} else if (!Sanitize::is_legal_password($pass_new)) {
echo "invalid_new";
} else {
echo "valid";
}
and this is the callback function that processes it; the callback function is the one where the comparison always fails.
function valid_pass_combo_callback( data ) {
//breakpoint is set here
if (data == 'valid') {
//only if the form is valid!
pass_form[0].unbind('submit').submit();
}
else if (data == "invalid_old") {
//display error on form - snipped
}
else if (data == "invalid_new") {
//display error on form - snipped
}
else {
//it always jumps to here..., even though data *is* the correct value
}
}
I debugged this code, and validate.php is returning "invalid_old" which is correct (based on the test data I'm entering). So, data is storing "invalid_old" according to Firebug; however, the code always jumps down to the last else statement. Why is the comparison always failing?
Try placing an alert(data.toString()); above your checks temporarily to see what it returns. If it's not the string itself, then it's not returning the data you're expecting.
As stated in the comment, adding JQuery's trim function fixed the problem, as shown:
function valid_pass_combo_callback( data ) {
trimmed_data = $.trim(data);
if (trimmed_data == 'valid') {
//only if the form is valid!
pass_form[0].unbind('submit').submit();
}
else if (trimmed_data == "invalid_old") {
//display error on form - snipped
}
else if (trimmed_data == "invalid_new") {
//display error on form - snipped
}
else {
//it always jumps to here..., even though data *is* the correct value
}
}
Hello I am working with an ajax post function, where I send data and my callback from PHP returns some data back. Based on the data returned I make the decision, either to go forward or allow the user to stay on the page and make changes.
if (validateStep(step))
{
if(step==1)
{
var data = document.getElementById('hiddenContact').value;
$.post('/app/controller/action', {'data':data}, function(returndata){if(returndata.match('not Unique'))alert('Contact source already exists'); else if(returndata.match('not posted')){alert("Not posted to the database");return false;}});
}
step = step + 1;
form[0].action = '/app/controller/index/step:'+step;
document.getElementById('step').value = step;
form[0].submit();
}
Here I am trying to stop the application going ahead when the return data is matched to "not posted", and I am throwing an alert and then a return false to stop the operation. I am unable to stop the application from going to next step though. Though it is returned false, the operation continues to the next step, but when I comment the last 4 lines which increment the step, set the action and submit, it stays on the page and the alert is thrown.
Does anybody know what I should do in order halt my process from submission??
AJAX calls are asynchronous. The "false" you are returning is on the success callback, not on the handler you have shown there. So the last four steps always execute, before the AJAX call even reaches the server. You can fix this by changing ajax response callback to deal with this, like so:
if (validateStep(step))
{
var next_step = function() {
step = step + 1;
form[0].action = '/app/controller/index/step:'+step;
document.getElementById('step').value = step;
form[0].submit();
}
if(step==1)
{
var data = document.getElementById('hiddenContact').value;
$.post('/app/controller/action', { 'data':data }, function(returndata) {
if (returndata.match('not Unique')) alert('Contact source already exists');
else if (returndata.match('not posted')) alert("Not posted to the database");
else next_step();
});
}
else next_step();
}
your process to continue to the next step is outside of your IF statement and will always run.
can you not do this:
if (validateStep(step))
{
if(step==1)
{
var data = document.getElementById('hiddenContact').value;
$.post('/app/controller/action', {'data':data}, function(returndata){
if(returndata.match('not Unique')) {
alert('Contact source already exists');
step = step + 1;
form[0].action = '/app/controller/index/step:'+step;
document.getElementById('step').value = step;
form[0].submit();
} else if (returndata.match('not posted')){
alert("Not posted to the database");
return false;
}
});
}
}