I'm using jquery-ajax to send data to a php. Upon success or failure the php sends back a response. so far everything works fine. Now my questions is how do I use an if statement in jquery to do some action using the response?
See example:
$.post("php/send.php",
{
email:$( '#email' ).val(),
name:$( '#name' ).val()
},
function(response) {
alert(response) // shows "Error!"
if (response != "" || response != "Error!") {
//do A...
} else {
//do B...
}
)};
My if statement does not work. Even the response from the php is "Error!" it will //do A.How do I fix this?
In your if conditional, the expression to the left of the short-circuit OR (ie. ||) returns true if response is not an empty string. When response = "Error!", ie. not empty, the first part of || becomes true, and //do A will execute. The expression to the right of ||, in this case response != "Error!", is simply ignored when the expression to the left of || is true.
The code posted should work if the only output from send.php is something like <?php echo "Error!"; ?>, and, i don't know if it is a typo, but closing brackets for the $.post function should be });
Method 1
Good practice is to use json format ( json_encode() ) for the response, for example:
php
<?php
// if there is an error fill the error data
$response['error'] = 'Error message!';
// else fill the correct data
$response['data'] = [ 'foo' => 'Some data', 'bar' => 'Some other data' ];
header( 'Content-Type: application/json' );
die( json_encode( $response ) );
?>
js
$.post( "php/send.php", { email: $( '#email' ).val(), name: $( '#name' ).val() } )
.done( function( response ) {
if ( response.error ) {
console.log( response.error );
return;
}
console.log( response.data );
});
Method 2
Alternatively, HTTP response code can be set manually ( http_response_code() ), so that the fail() method of jqXHR object is invoked, like this:
php
<?php
// if case of an error
http_response_code(400);
die( 'Error message!' );
?>
js
$.post( "php/send.php", { email: $( '#email' ).val(), name: $( '#name' ).val() } )
.done( function( response ) {
// success
})
.fail( function( jqXHR ) {
console.log( jqXHR.responseText );
});
Usually is not safe to respond with pure text from a php page, i suggest you to use json for the comunication between php and ajax, anyway, your code seems ok, try to add a trim() to the returned string in php
Related
I tried to pass a json object from my test.php to my jquery in index.html but i can't.
here is my test.php script:
<?php
if(isset($_POST["view"]))
{
$output .= '
<li>No Notification Found</li>
';
$total_row=2;
$data = array(
'notification' => $output,
'unseen_notification' => $total_row
);
echo json_encode($data);
}
?>
and here is my jquery script , "the alert in js show undefined as result":
function load_unseen_notification(view = '')
{
$.ajax({
url:"test.php",
method:"POST",
data:{view:view},
dataType:"json",
complete:function(data)
{
alert(data.notification);
$('.dropdown-menu').html(data.notification);
if(data.unseen_notification > 0)
{
$('.count').html(data.unseen_notification);
}
}
})
}
In PHP, you need to put a header response from the server so that the browser knows what it got in response (see: https://www.iana.org/assignments/media-types/media-types.xhtml , http://php.net/manual/en/function.header.php):
<?php
header("Content-Type: application/json");
In JavaScript, you need to use success event:
$.ajax({
url: "test.php",
method: "POST",
data: {
view: 10
},
dataType: "json",
success: function(data) {
alert(data.notification);
}
});
success - A function to be called if the request succeeds.
Arguments: ( Anything data, String textStatus, jqXHR jqXHR ).
complete - A function to be called when the request finishes (after success and error callbacks are executed).
Arguments: ( jqXHR jqXHR, String textStatus )
Documentation: http://api.jquery.com/jquery.ajax/
If to use complete, then access to data can be got by means of jqXHR Object (see: http://api.jquery.com/jQuery.ajax/#jqXHR):
complete: function(jqXHR) {
if (typeof jqXHR.responseJSON !== 'undefined') {
alert(jqXHR.responseJSON.notification);
}
}
Of course if necessary it is possible to combine different event handlers.
P.S. For debugging use console.log(data) instead of alert(data) and look through the log in the browser. For example, for Google Chorme (F12, Tab: Logs): https://developers.google.com/web/tools/chrome-devtools/console/get-started
It might be a good idea as well to set the content-type header at the top of your PHP script:
<?php
header("Content-Type: application/json");
jQuery will probably interpret the body as JSON instead of 'text'.
I added $.trim()to my data.responseText and finally it's working (i don't know why :) )
var obj = JSON.parse($.trim(data.responseText));
$('.dropdown-menu').html(obj.notification);
Thx a lot for you all for your assisting
I would like to pass a variable to a specific page. I found a simple example explaining how to use ajax with wordpress.
JavaScript:
jQuery(document).ready(function($) {
// We'll pass this variable to the PHP function example_ajax_request
var fruit = 'Banana';
// This does the ajax request
$.ajax({
url: ajaxurl,
data: {
'action':'example_ajax_request',
'fruit' : fruit
},
success:function(data) {
// This outputs the result of the ajax request
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
Piece of PHP to insert in functions.php
function example_ajax_request() {
// The $_REQUEST contains all the data sent via ajax
if ( isset($_REQUEST) ) {
$fruit = $_REQUEST['fruit'];
// Let's take the data that was sent and do something with it
if ( $fruit == 'Banana' ) {
$fruit = 'Apple';
}
// Now we'll return it to the javascript function
// Anything outputted will be returned in the response
echo $fruit;
// If you're debugging, it might be useful to see what was sent in the $_REQUEST
// print_r($_REQUEST);
}
// Always die in functions echoing ajax content
die();
}
add_action( 'wp_ajax_example_ajax_request', 'example_ajax_request' );
wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
Unfortunately I cannot pass the variable. I inspected the code and I get this error:
Error: ajax_object is not defined
Do you maybe know another way to obtain the same result?
You are very near, but there is some little things missing…
What I mean in my comment, is that you need to use it this way using 'ajax-script' in both:
add_action('wp_enqueue_scripts', 'add_js_scripts');
add_js_scripts(){
wp_enqueue_script( 'ajax-script', get_template_directory_uri().'/js/script.js', array('jquery'), '1.0', true );
wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
Changed $_REQUEST to $_POST:
function example_ajax_request() {
// The $_REQUEST contains all the data sent via ajax
if ( isset($_POST) ) {
$fruit = $_POST['fruit'];
// Let's take the data that was sent and do something with it
if ( $fruit == 'Banana' ) {
$fruit = 'Apple';
}
// Now we'll return it to the javascript function
// Anything outputted will be returned in the response
echo $fruit;
// If you're debugging, it might be useful to see what was sent in the $_POST
// print_r($_POST);
}
// Always die in functions echoing ajax content
die();
}
Added add_action( 'wp_ajax_nopriv_ … ):
add_action( 'wp_ajax_nopriv_example_ajax_request', 'example_ajax_request' ); // <= this one
add_action( 'wp_ajax_example_ajax_request', 'example_ajax_request' );
For your jQuery script script.js file, there is 2 important missing little things:
jQuery(document).ready(function($) {
/* We'll pass this variable to the PHP function example_ajax_request */
var fruit = 'Banana';
/* This does the ajax request */
$.ajax({
url: ajax_object.ajaxurl, /* <====== missing here */
type : 'post', /* <========== and missing here */
data: {
'action':'example_ajax_request',
'fruit' : fruit
},
success:function(data) {
/* This outputs the result of the ajax request */
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
This should work now…
References:
Using AJAX With PHP on Your WordPress Site Without a Plugin
How to use Ajax with your WordPress Plugin or Theme?
You are using wp_localize_script wrong. In the PHP code, remove the wp_localize_script line.
Optionally you can (and should) add the following
// this line is for users who are not logged in
add_action( 'wp_ajax_nopriv_example_ajax_request', 'example_ajax_request' );
Everything is correct except you have to add
ajax_object.ajax_url rather than ajaxurl in url: parameter of $.ajax function as
jQuery(document).ready(function($) {
// We'll pass this variable to the PHP function example_ajax_request
var fruit = 'Banana';
// This does the ajax request
$.ajax({
url: **ajax_object.ajax_url**,
data: {
'action':'example_ajax_request',
'fruit' : fruit
},
success:function(data) {
// This outputs the result of the ajax request
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
copy and paste above script in place of your $.ajax function
If you want to see what is ajax_object.ajax_url then
alert it inisde your code and it will alert path to your admin ajax file
which is required for using ajax in wordpress
Using jQuery to call an endpoint and populate the data on the frontend is a common task. After searching and using multiple solutions the below is my current blueprint for any ajax calls.
How can I improve the following to be faster and more efficient? I realize doing it in pure javascript will be faster but at this point I assume jQuery will be present.
Frontend - Javascript:
$(document).ready(function()
{
function callEndpoint( call_url, payload ){
return $.ajax({
url: call_url,
type: 'GET',
data: payload
});
}
$( '.get-endpoint' ).click( function() {
sSelected = $( this ).text();
console.log( sSelected );
oRequest = callEndpoint( '/play/endpoint2.php', { 'type': sSelected } );
oRequest.done(function( sJson ) {
aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
Frontend - Html:
<body>
<button class="get-endpoint">Games</button>
<button class="get-endpoint">Books</button>
<button class="get-endpoint">Comics</button>
<div class="from-endpoint">Coming soon...</div>
</body>
Backend - PHP:
$aReturn[ 'text' ] = '';
if( !empty( $_GET ) )
{
if( $_GET[ 'type' ] == 'Games' )
{
$aReturn[ 'text' ] = 'Text for games';
}
else if( $_GET[ 'type' ] == 'Books' )
{
$aReturn[ 'text' ] = 'Text for books';
}
else if( $_GET[ 'type' ] == 'Comics' )
{
$aReturn[ 'text' ] = 'Text for comics';
}
}
$sJson = json_encode( $aReturn, 1 );
header( 'Content-Type: application/json' );
echo $sJson;
I don't think that this code can be more efficient in jQuery.
But you have some options left to give a more efficient feeling :
You can use pagination to get a portion of your data each time. The
less data to load, the quicker it get. And your application will be
more responsive to the user's actions. This solution is a trick for
the user, because it will take in reality more time than before to load all the data.
You can keep previous loaded data so when you click back on a button,
it won't load again the data. But, this can only be used if the data
won't change much between each click. The first time you will click
on a button, it will take the same time as before, but the next time,
it will be immediat.
Be aware that the more HTML code you load, the more it will take time to initiate JavaScript behavior on it.
Looks like your categories won't change often. You can save some bandwidth by using JavaScript localstorage or cookies to cache data. If you plan on connecting to a mysql database at somepoint you can use StoredProcedures which are variablized precompiled statements.
Since you are anyways going to use JSON and jQuery, I would suggest that you should check out the getJSON method of jQuery. I feel that it would reduce some lines of code, though I am not sure if it would help it become more efficient.
Anyways getJSON is just a shorthand of AJAX and I thought I should suggest this.
This could be a good approach for AJAX data transport browser->server->browser. Hope it suites your needs.
jQuery
$( function () {
function fetch( data ) {
var encoding = data.encoding,
url = data.url,
params = data.params,
type = ( data.type ) ? : 'GET',
cache = ( data.cache ) ? : 'false',
async = ( data.async ) ? : 'true';
return $.ajax({
url: url,
async: async,
cache: cache,
data: params,
dataType: encoding,
type: type
});
}
var options = {
url: 'controller.php',
params: {
param_one: value_one,
param_two: value_two,
param_n: value_n
},
encoding: 'json'
};
// Get the JSON feed from the server
$.when( fetch( options ) ).then( function ( response ) {
// Is there anything in the pool?
if ( response ) {
// Store the response and use it in your code
var data = response.data;
console.log( data.responseOne );
console.log( data.responseTwo );
}
});
});
PHP Controller
// Set header to application/json
header( 'Content-type: application/json' );
// Create the DB connection object
$dbc = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME );
// Initialize parameters array
$params = array();
// Store the query variables in an array
$query_type = ( $_GET ) ? : $_POST;
// Run foreach and store the values in an array
foreach ( $query_type as $key => $value ) {
$params[ $key ] = mysqli_real_escape_string( $dbc, $value );
}
// Now you can access passed parameters like $params['param_name']
// This would be the data obtained from DB or some server array processing, whatever
$response = array(
'data' => array(
'response_one' => 'some_value',
'response_two' => 'another_value'
)
);
// Encode the result
echo json_encode( $response );
If you don't want use pure javascript, you can improve your jQuery code with better selectors
For example, you can add an id in <div class="from-endpoint">
You can add tag in selector like this:
$('button.get-endpoint')
You can drop your getEndpoint method and just use the $.get method.
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
sSelected = $( this ).text();
console.log( sSelected );
oRequest = $.get('/play/endpoint2.php', { 'type': sSelected });
oRequest.done(function( sJson ) {
aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
You can make your code lint compliant.
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
oRequest = $.get('/play/endpoint2.php', { type: sSelected });
oRequest.done(function( sJson ) {
var aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
Use success instead of done & move the callback to it's own function
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
$.get(
'/play/endpoint2.php',
{ type: sSelected },
insertData
);
});
});
function insertData( sJson ) {
var aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
}
Use $.getJSON instead of $.get or $.ajax
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
$.getJSON(
'/play/endpoint2.php',
{ type: sSelected },
insertData
);
});
});
function insertData( data ) {
$( '.from-endpoint' ).text( data.text );
}
Through ajax I ask for a php page which will get some information from database. When data are processed I echo them to some tag and through JS I target those tags and get their content. This is the only way how I can pass data between php and JS but I feel it's not quite right. Whats the best way to get value of php variable:
$var1 = 24515875;
into JS variable?
When calling between PHP and JavaScript using AJAX, I suggest you always encode using JSON (Javascript Object Notation).
<?php
// Set Header (Always should be first commands just in case of thrown errors)
header('Content-type: application/json');
$data = array(
'message' => 'Hello World',
'error' => false
);
echo json_encode($data);
?>
For the javascript, you can use XMLHttpRequest. I don't suggest using jQuery unless you need it for other aspects of your script.
function request(url,callback) {
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if(req.readyState == 4 && req.status == 200) {
var json = JSON.parse(req.responseText);
if(typeof callback === "function") {
callback(json);
}
}else{
// Handle Error
}
}
req.open("GET",url,true);
req.send();
}
function callback_func(json) {
// Function gets called when Ajax is finished
console.dir(json);
}
request("ajax.php",callback_func);
I don't know if the following suggestion is too complex, but:
you could use jQuery Ajax Get for requesting JSON data from PHP.
This is good for passing arrays, like results sets from a database to the client-side.
On PHP side you would do a simple:
<?php
header('Content-type: application/json');
echo json_encode($myData);
?>
On JS side you would access this with:
$.getJSON( "getjsondata.php", function( data ) {
alert(data);
// do whatever, like appending to html element
// next code section is the answer to your question from the comment:
// how to iterate over the data result set?
// create new DomElement for insertion: here foreach row a new list item
var items = [];
$.each( data, function( key, val ) {
items.push( "<li id='" + key + "'>" + val + "</li>" );
});
// then insert the list items into a UL and append that to the body
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "body" );
// to access the individual properties you would do
alert(data.property);
});
http://api.jquery.com/jquery.getjson/
My problem is how JQuery knows when to receive data, when I watch the browser's console I see that GET call is first and then the POST call is second.
It should be POST first, then GET.
I tried solving my problem with .ready,and with some IF statements and so on but I still have not achieved what I wanted to achieve. Should I use some events?
My Javscript:
(function($) {
$(document).ready(function() {
$("form#userdata").submit(function(){
$.post( "savedata.php", $("form#userdata").serialize())
.done(function( data ) {
alert( "Send data" + data );
});
return false;
alert("Error by passing data to php");
});
})})(jQuery);
$.when($.ajax("savedata.php")).then(function(){
$.get("savedata.php", function(data){
alert("Php returns validation errors:+data);
});
});
My php script:
// Get POST data
$postData = $_POST;
// Print out for testing
// print_r($postData);
// Read data
$fistname = $_POST['firstname'];
$surname=$_POST['lastname'];
$email=$_POST['email'];
// VALIDATION
// Build return array and return JSON
$returnData = $postData;
//print(json_encode($returnData));
echo json_encode($returnData);
?>
$.get is called unconditionally, while the page is loading, because you didn't put it in an event handler.
$.post is only called when you submit the #userdata form, because it's called from the .submit() event handler.
You can try something like this:
PHP:
// Get POST data
$postData = $_POST;
// Print out for testing
// print_r($postData);
// Read data
$fistname = $_POST['firstname'];
$surname=$_POST['lastname'];
$email=$_POST['email'];
// VALIDATION
if(//validationError){
echo json_encode(array('error' => //Your error message here));
exit();
}
$returnData = $postData;
//print(json_encode($returnData));
echo json_encode(array('success' => $returnData));
?>
Then...
JS:
(function($) {
$(document).ready(function() {
$("form#userdata").submit(function(){
$.post("savedata.php", $("form#userdata").serialize())
.done(function( data ) {
if(data.error)
alert("Validation error: " + data.error);
else
alert( "Send data" + data.success );
})
.fail(function(){
alert("Error by passing data to php");
});
});
})})(jQuery);
You have your script incorrect
(function($) {
$(document).ready(function() {
$("form#userdata").submit(function(){
$.post( "savedata.php", $("form#userdata").serialize())
.done(function( data ) {
alert( "Send data" + data );
});
return false;
alert("Error by passing data to php");
});
})})(jQuery);
$.when($.ajax("savedata.php")).then(function(){
$.get("savedata.php", function(data){
alert("Php returns validation errors:"+data); // You did not close the string literal and it would throw an error
});
});