I have been developing a registration form and slowly but surely I have been learning some javascript and jquery along the way, to further support my knowledge of that and all. I have come across a problem however, the problem is I can't get the response from a AJAX request.
My AJAX request is in a separate function, I have multiple purposes for it. I have put alert();'s in the code for debugging purposes.
function validate_input ( input, type ) {
$.ajax({
type:'post',
url: 'ajax_request.php',
data: "type=" + type + "&input=" + input,
success: function( response ) {
if( response == "true" || response == "false" ) {
alert( "working" );
console.log(response);
return response;
} else {
alert( "AJAX/jQuery Error" );
alert( "Reponse !== true or false" );
}
}
});
}
I can confirm that the ajax_request.php file is echoing true or false correctly, however, for those interested here is the coding.
if (!defined('BASEPATH') &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest')
exit('Direct Access to this file has been disabled.');
include('core/db.php');
$validateType = intval( $_POST['type'] );
$input = escape_string( $_POST['input'] );
if( $validateType == 1 ) // validate username
{
echo ( user_exists( $input ) ? "true" : "false" );
} else if( $validateType == 2 ) // validate email
{
echo "true"; // not coded yet
}
Finally, I call the function when it is necessary( using .blur() ), you can see below;
var username_value = "Jake"; // for debugging purposes, var definitely contains something
validate_input( username_value, 1 );
alert( validate_input( username_value, 1 ) ); alerts "undefined"
I am just wondering if anyone can see any issues with the code that would be causing this, and please don't suggest for me to use a validator plugin, that is not an answer to the question.
Thanks,
Ajax calls are asynchronous, you can't return the response like that. Using ajax you define a callback function which is called when the response is received. Code execution does not stop and wait for the response before continuing.
So you need to do whatever you want to do within the success function, or call another function from there.
The ajax "type" is set to POST, yet your script is checking the $_GET array for parameters. Change $_GET to $_POST or ajax type to "get".
alert( validate_input( username_value, 1 ) );
alerts "undefined"
This will not work like that. First - you are using asynchronouse ajax call.
Second:
success: function( response ) {
if( response == "true" || response == "false" ) {
alert( "working" );
console.log(response);
return response;
} else {
alert( "AJAX/jQuery Error" );
alert( "Reponse !== true or false" );
}
}
In code above return belogns to success handler function, not to validate_input function. Basically, you return your response to nowhere.
So, instead of return response; you should do whatever you need to do with response:
success: function( response ) {
if( response == "true" || response == "false" ) {
alert( "working" );
console.log(response);
alert(response);//here you do what you need.
} else {
alert( "AJAX/jQuery Error" );
alert( "Reponse !== true or false" );
}
}
.get, .post, .load will work in the same way as they use $.ajax in behind
Related
For some reason, I need to pass an ID via AJAX to a PHP function on the same page and run a query and return the result back to AJAX which would then append the final result into a div.
As I did some research, I came across this solution, but there are some shortcomings with it.
function1($_GET['id']);**//not getting the id's value**
echo "This is function 1 AND id=".$param;**//this string must be
passed back to the previous ajax request.**
AJAX request (efund.phtml)
$.ajax({
type:'GET',
url:'efund.phtml',
data:"function_to_call=0?id"+cl[3],
success: function(data){
// alert('successful');
}
});
PHP (efund.phtml)
switch ($_GET['function_to_call']) {
case 0:
function1($_GET['id']); // not getting the id's value
break;
case 1:
function2();
break;
default:
break;
}
//And your functions.
function function1($param) {
echo "This is function 1 AND id=".$param; // This string must be passed back to the previous AJAX request.
}
function function2() {
echo "This is function 2";
}
The most common way to communicate between server/client tends to be to use XML or JSON, for your case I recommend you use JSON:
$.ajax({
method: "GET",
url: "efund.phtml",
data: { function_to_call: 0, id: cl[3] }
})
.done(function( msg ) {
var obj = jQuery.parseJSON( msg );
alert( "ID obtained from server is " + obj.id );
});
And then in the server get them using:
$_GET['function_to_call'] // To obtain 'function_to_call' param
$_GET['id'] // To obtain 'id' param
To send information back as response from the server I recommend you, use the same approach and use json_encode for parse an array as JSON and return it using:
in your case for function1 it would be:
function function1($param) {
return json_encode(array ( "id" => $param ) );
}
Also, maybe you should consider if you should use GET or POST for the Http request. You can see more information about it here:
www.w3schools.com/tags/ref_httpmethods.asp
Edit:
If you have problems with the ajax request and you want to check if the ajax request is executed correctly modify the Ajax code like this:
$.ajax({
method: "GET",
url: "efund.phtml",
data: { function_to_call: 0, id: cl[3] }
}).fail(function() {
alert( "error" );
}).always(function() {
alert( "complete" );
}).done(function( msg ) {
var obj = jQuery.parseJSON( msg );
alert( "ID obtained from server is " + obj.id );
});
Change
data:"function_to_call=0?id"+cl[3],
to
data: {function_to_call: 0,id : cl[3]},
in this case data work as object and it is easy to fetch value.
According to your only first condition called every time because you are passing function_to_call=0
attempting to implement some server side error checking for input in the very useful "handsontable" jscript library.
the following call works great:
jQuery.ajax({
url: "index.php?option=com_catalogscontroller=batchsave",
data: {"formData": querydata.getData().splice( 0, 1 ) },
dataType: 'JSON',
type: 'POST',
success: function ( response ) {
if( response.success ) {
} else {
querydata.loadData( response.data );
}
}
});
I thought the most effective way to do error checking is on the server (PHP) side, to create a multidimensional array to track any errors discovered by the server and then return that array with the form data in the same ajax call. So I modified the server code to return both the form data and the error array back to the javascript ajax call. i.e.:
if( !empty( $errors ) ) // $errors is an multi dimensional array same size as the form data
$result['success'] = false;
$result['msg'] = 'There were errors detected';
$result['data']['form'] = $formData;
$result['data']['errors'] = $errors;
}
echo json_encode( $result );
and then on the client side, the javascript routine above has been modified to:
jQuery.ajax({
url: "index.php?option=com_catalogscontroller=batchsave",
data: {"formData": querydata.getData().splice( 0, 1 ) },
dataType: 'JSON',
type: 'POST',
success: function ( response ) {
if( response.success ) {
} else {
formErrors = response.data.errors; // formErrors is a global
querydata.loadData( response.data.form );
}
}
});
The original function of the form is preserved (the form data is retrieved and properly inserted in the html), but formErrors returns with a result to me that is baffling. An alert immediately after the assignment 'alert( formErrors )' shows something like a list:
true,true,false,true,true
and I can also alert on a specific index without problem e.g. alert( formErrors[0][2] ); would display 'false'. But outside of the ajax call, the array seems to be inaccessible, giving 'undefined' errors. And both in the ajax call, and in routines outside of the ajax call alert( typeof formErrors ) displays 'object' and alert( formErrors) gives the same comma list as above, but I don't want an object, I am expecting an array OR i'd be happy with an object as long as i could access it by indices. What am I missing here?
The problem I was having appear to be centered around JSONing.
Most docs identify the requirement to JSON variables in php routines supporting a Javascript AJAX call. The use of the jQuery.ajax call alleviates some of the requirement, but if you don't know what you're doing (like me), its easy to get in trouble.
My php routine JSON encodes the complete response record with the statement:
return json_encode( $result );
Because of my:
dataType: JSON
parameter in the jQuery.ajax() call, this results in an automatic json.parse() of the result returned by the PHP routine to the jQuery javascript function. This is not successful however because the php json_encode call in the server code is not recursive, so while the result array is decoded, any arrays within that result are not.
the solution then is to json encode the components of the multidimensional array and then decode them on the client side. e.g.
if( !empty( $errors ) )
$result['success'] = false;
$result['msg'] = 'There were errors detected';
$result['data']['form'] = json_encode( $formData );
$result['data']['errors'] = json_encode( $errors );
}
echo json_encode( $result );
And then on the client side, parse (decode) these arrays specifically:
jQuery.ajax({
url: "index.php?option=com_catalogscontroller=batchsave",
data: {"formData": querydata.getData().splice( 0, 1 ) },
dataType: 'JSON',
type: 'POST',
success: function ( response ) {
if( response.success ) {
} else {
formErrors = JSON.parse( response.data.errors ); // formErrors is a global
querydata.loadData( JSON.parse( response.data.form ) );
}
}
});
I confess freely that I don't really know what I'm doing, but the code structured above seems to make sense for the logic I've developed to explain it AND it is working for me.
Anyway, thanks again to Nathan and pdoherty926.
I know this had been disputed a lot and the short answer would be that I can't simply pass a javascript variable to a php variable in the same file. So instead here would be what I want to try: My user inputs a code, I send it to a php file by POST. There I check if the code matches a code from my database and I post again a boolean from there. Then in my first file, I tell the user whether the code is correct or not. Can this be achieved this way? I am a webdev newbie and I am trying to learn.
To pass a value from the client side to the server you can either send it on the URL or as a post variable.
This can be accomplished easily with ajax.
I recommend using jquery. example:
$.get("http://example.com/?var1=value&var2=othervalue", function (data) {
// your response
});
jQuery:
$.get( url, { userinput: value }, function( response ) {
if( response.status ) alert( "Matches found" );
else alert( "No matches" );
}
javascript:
function get( url ) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false );
xhr.send();
return xhr.responseText;
}
var response = JSON.parse( get( url ) );
if( response.status ) alert( "Matches found" );
else alert( "No matches" );
php:
header( 'Content-type: text/json' );
if( get_matches( $_GET['userinput'] ) ) exit( '{ "status": true }' );
else exit( '{ "status": false }' );
You can post that code through AJAX to your server, have your server return a boolean, and then output a message to your user, this is quite common.
Common implementations of this logic include autosuggest, username validity verifications, simple turn on / turn off interfaces, etc.
Workflow:
User inputs code
Javascript sends AJAX request to server
Server verifies code and returns boolean
Javascript reads boolean, generates HTML and appends it to the document
User reads output
Edit: Even though i advice you to try doing it with pure javascript first (for educational reasons), you should use jQuery or other equivalent framework if you are on a schedule.
I have build a simple but working AJAX form using jQuery. The form is validated with jQuery before submit and then after successful submit again with PHP.
The only problem is the error handling. When the PHP-check returned that all fields are ok, I display a success message. If there was an error, I simply display "there was an error".
How can I send back data from PHP to jQuery so invalid fields can be marked as invalid?
Or is such form of error handling unnecessary as the dynamic highlighting needs JavaScript turned on and if JavaScript is turned on, the form can't be submitted wrong?
Basically, my valid checks look like this (simplified of course):
function checkSomething( $something ) {
$valid = true;
if ( strlen( $something ) === 0 ) {
$valid = false;
}
return $valid;
}
At the end of the script, I do it like this:
if ( checkSomething( $something ) && checkThis( $this ) && checkThat( $that ) ) {
echo "success";
} else {
echo "error";
}
And in my JavaScript/jQuery code it looks like this:
$.ajax({
url: "form.php",
type: "POST",
data: string,
success: function ( result ) {
if ( result == "success" ) {
alert( "success" );
} else {
alert( "error" );
}
}
});
Your form submission has 3 steps: JavaScript Validation & Submission, PHP validation/Processing, and JavaScript on complete ( 'so invalid fields can be marked as invalid')
It sounds like you have step 1 completed and most of step 2.
In your PHP code you should have some data structure, preferably an array, which holds which values are invalid. You can return this data to the browser by echo`ng it to the browser
<?php
...
...
if( count( $invalidFieldArray ) ){
echo json_encode( array( 'status' => 'Fail',
'data' => $invalidFieldArray ) );
}else{
echo json_encode( 'status' => 'Success' );
}
The code above will return the success/fail to your JavaScript form.
I personal use a jQuery form plugin to handle form submissions, and I recommend you give it a try. It has many nice out of the box features.
$.ajax({
url: "form.php",
type: "POST",
data: string,
dataType: json,
success: function ( result ) {
if ( result.status === "Success" ) {
alert( "success" );
} elseif (result.status === 'Fail'){
for (field in result.data) {
/* Invalid field handling */
...
}
}
}
});
Tip : Slightly off-topic, but when using comparisons in JavaScript always use triple equal ( === ), double equal ( == ) is not the same in JavaScript as in other languages; JavaScript does type coercion with double equals, which provides for inconsistent results.
I think you should have only one service in PHP. You send the data from the form, if there is any invalid data, you might want to return a JSON indicating which fields are wrong, so you can parse and show it. If it went ok, you just simply display that success message.
I'm not sure I get your problem, though.
You could send the data from PHP and store it in URLs, like this url.com/#value=1
Basically I was trying to replicate one of the things that xajax gave me with Jquery -> The ability to define what my response modifies server side without setting anything up client side. Works perfectly as is, but each time I want to call a different Jquery function, I have to add it to my if statements.
Each element in the response array contains something to be changed client side.
I should be able to take out almost all of the this.action == 'blah' if statements and replace with some clever javascript, but apparently I'm not clever enough. :)
$.showMessage is simply my replacement for alert, with a timeout and sticky bit.
My client Jquery function:
$.doAjax = function(func,values) {
$.ajax({ data: values, url: '/time/ajax/' + func, type: 'POST', dataType: 'json', timeout: 5000,
error: function(xhr, ajaxOptions,thrownError){ $.showMessage('Error processing request: ' + func,10000);$('#debug').html(xhr.responseText); },
success: function(data){
if(data){
$.each(data, function(){
if ( this.action == 'attr' ) $(this.target).attr(this.content);
if ( this.action == 'removeAttr' ) $(this.target).removeAttr(this.content);
if ( this.action == 'addClass' ) $(this.target).addClass(this.content);
if ( this.action == 'removeClass' ) $(this.target).removeClass(this.content);
if ( this.action == 'html' ) $(this.target).html(this.content);
if ( this.action == 'text' ) $(this.target).text(this.content);
if ( this.action == 'val' ) $(this.target).val(this.content);
if ( this.action == 'eval' ) {
try {
eval(this.content);
}
catch(err) {
$.showMessage(err,5000);
};
};
});
}
}
});
return this;
};
My server side code:
header("Content-type: text/plain");
$response = array();
$response[] = array('action'=>'html','target'=>'#booked_time_group_unbilled','content'=>get_booked_time_group_unbilled());
$response[] = array('action'=>'html','target'=>'#booked_time_my_unbilled','content'=>get_booked_time_my_unbilled());
$response[] = array('action'=>'eval','target'=>'','content'=>"$.showMessage('The selected time has been deleted',5000,true)");
echo json_encode($response);
This should work:
$(this.target)[this.action](this.content);
I'm not exactly sure what you're asking? Stylistically, I would write it like this:
var handlers = {
attr: function() { $(this.target).attr(this.content) },
removeAttr: function() { $(this.target).removeAttr(this.content) },
// etc.
};
$.each(data,function() {
handlers[this.action].call(this);
});
If you just want to execute whatever the server sends back, which not just always send back an eval action?