this the first function of the Ajax call runs on focusout woocommerce input fields with check_country_fees action and url '<?php echo admin_url('admin-ajax.php'); ?>' so how to pass the returned data and passing them as arguments normally?
function addEvtListenerToCheckoutPage()
{
?>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", (event) => {
$(document).ready(function() {
document.getElementById('billing_first_name').addEventListener("focusout", function() {
alert("Hello World!");
if (document.getElementById('billing_first_name') !== "") {
var billing_first_name = document.getElementById("billing_first_name").value;
alert("testajax");
var data = {
action: 'check_country_fees',
billing_first_name: document.getElementById("billing_first_name").value
};
jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
if (response.success == true) {
// Handle Success
// let resp = JSON.parse(response.data.json_response);
if (response.success) {
alert(response);
console.log(response);
alert(response);
alert("Sucess");
// Hanle Success Response
}
} else {
console.log(response);
console.log(data);
alert("Sucess");
}
}).fail(function(response) {
// Handle Error
console.log("failing");
console.log(response);
alert("FAIl");
});
}
});
});
});
// document.getElementById("#billing_first_name").addEventListener("input", myFunction);
</script>
<?php
?>
<script language="javascript">
alert("sended addevent");
</script>
<?php
}
when I run the action call function add_action('wp_ajax_check_country_fees', 'testing_ajax_action'); the result printed in the browser console like that
</script>
<script>
alert("sended datasuccess");
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
testing ajaaaaxnullArray
(
[action] => check_country_fees
[billing_first_name] => Stevea
)
Stevea</br>
<script>
alert("test ajaxbilling name");
</script>
SteveaArray
(
)
Receiving data function
function testing_ajax_action()
{
echo "testing ajaaaax";
if (isset($_POST['billing_first_name'])) {
$billing_first_name = $_POST['billing_first_name'];
$billing_first_name = json_decode($billing_first_name);
extract($_POST);
print_r($_POST);
$billing_first_name2 = json_decode($_POST['billing_first_name_post']);
//testingajax($billing_first_name);
testingajax($billing_first_name);
} else {
return 0;
}
}
You need to send the data back from the backend to the frontend.
Here is a crude basic diagram of an ajax request:
Event → JS request → PHP Processing → PHP Response → JS Handling
If you're not sending any data with your PHP response then you can't handle it on the front end.
You can use wp_send_json_success() and wp_send_json_error() to send the appropriate response success/error status and attach to it any relevant data you want to handle on the front end.
By convention, the PHP Processing function is usually anonymous.
From a security standpoint you should implement a nonce system too. You can refer to the following answer about using Ajax the right way in WordPress.
Coming back to your problem, you can pass an array through wp_send_json_success.
<?php
add_action( 'wp_ajax_{$action}', function () {
if ( check_ajax_referer( '_ajax_nonce' ) ) {
//...
$data = array(
'timestamp' => time(),
'key' => 'value',
//...
);
wp_send_json_success( $data );
} else {
wp_send_json_error();
};
} );
On the javascript handling side, you would intercept it and do something with it:
$.ajax({
//...
success: ( response ) => {
console.log( response.data );
//...
},
//...
});
Related
I am adding a function that should be called when a button is clicked, i have a js file with the following jquery code and the ajax call :
jQuery(document).ready( function() {
function getUrlParameter(sParam){
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++) {
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam) {
return sParameterName[1];
}
}
}
jQuery('#upload_btn').click( function(e) {
e.preventDefault();
var flag = true;
var postId = getUrlParameter('preview_id');
var files = jQuery('#file_tool').prop('files');
console.log(files);
var dataS = {
'action': 'upload_button',
'preview_id': postId,
'files': files,
'set': flag
}
jQuery.ajax({
type : 'post',
url : diario.upload,
processData: false,
contentType: false,
data : dataS,
success: function(response) {
if(response.type == "success") {
console.log('jquery works');
} else console.log(response);
}
});
});
});
When i click the button the console.log shows the files obj so at least the onClick works, but just after that it shows up jquery.js:4 POST custom/wp-admin/admin-ajax.php 400. This is how my functions.php looks like :
add_action( 'wp_enqueue_scripts', 'enqueue_onClick_upload' );
//custom_js_enqueuer
function enqueue_onClick_upload() {
wp_register_script( 'onClick_upload', WP_CONTENT_URL.'/themes/microjobengine/onClick_upload.js', array('jquery') );
wp_localize_script( 'onClick_upload', 'diario', array( 'upload' => admin_url( 'admin-ajax.php' )));
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'onClick_upload' );
}
add_action('wp_ajax_upload_button', 'upload_button');
add_action('wp_ajax_nopriv_upload_button', 'upload_button');
// upload button function
function upload_button() {
$postID = $_POST['preview_id'];
if ($_POST['set']) {
if($_POST['files']['size'] === 0 )
echo "<script>console.log('There's no images.');</script>";
}
$result['type'] = 'success';
echo json_encode($result);
wp_die();
}
I have no idea why it doesn't find the action, it's all done as wp says it should, I hope somone could give a hand, thanks.
--EDIT--
Okay so now i tried to only pass 'action': 'upload_button', the error does not appear but the response doesn't get success, I did this with all the code inside my function commented and just leaving the las 3 lines, in order to return the success, but it doesn't, so it might find the function but for some reason it doesn't get performed, and of course that means something wrong happens when i pass the extra data, any thoughts about why this happens?
Sorry i wasn't getting the right thing to get feedback from the functions, i just had to delete all echos and save everything i needed into an array and returne it json encoded.
Hello all and thanks in advance,
Short story, I am using a plugin to dynamically populate select options and am trying to do it via an ajax call but am struggling with getting the data into the select as the select gets created before the ajax can finish.
First, I have a plugin that sets up different selects. The options input can accept an array or object and creates the <option> html for the select. The createModal code is also setup to process a function supplied for the options input. Example below;
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
let dueDate = {};
for (let i = 1; i < 32; i++) {
dueDate[i] = i;
}
return dueDate;
}
}
});
What I am trying to do is provide an object to the options input via AJAX. I have a plugin called postFind which coordinates the ajax call. Items such as database, collection, etc. are passed to the ajax call. Functions that should be executed post the ajax call are pass through using the onSuccess option.
(function ($) {
$.extend({
postFind: function () {
var options = $.extend(true, {
onSuccess: function () {}
}, arguments[0] || {});
options.data['action'] = 'find';
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof options.onSuccess === 'function') {
options.onSuccess.call(this, obj);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
}
});
}(jQuery));
The plugin works fine as when I look at the output it is the data I expect. Below is an example of the initial attempt.
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
$.postFind({
data: {
database: 'dashboard',
collections: {
accountTypes: {
where: {status: true}
}
}
},
onSuccess: function (options) {
let dataArray = {};
$.each(options, function (key, val) {
dataArray[val._id.$oid] = val.type;
});
return dataArray;
}
})
}
}
});
In differnt iterations of attempting things I have been able to get the data back to the options but still not as a in the select.
After doing some poking around it looks like the createModal script in executing and creating the select before the AJAX call can return options. In looking at things it appears I need some sort of promise of sorts that returns the options but (1) I am not sure what that looks like and (2) I am not sure where the promise goes (in the plugin, in the createModal, etc.)
Any help you can provide would be great!
Update: Small mistake when posted, need to pass the results back to the original call: options.onSuccess.call(this, obj);
I believe to use variables inside your success callback they have to be defined properties inside your ajax call. Then to access the properties use this inside the callback. Like:
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
myOptions: options,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof this.myOptions.onSuccess === 'function') {
this.myOptions.onSuccess.call(this);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
It's not clear to me where the problem is without access to a functional example. I would start with a simplified version of what you want to do that demonstrates the proper functionality. My guess is the callbacks aren't setup exactly correctly; I would want to see the network call stack before making a more definitive statement. A few well-placed console.log() statements would probably give you a better idea of how the code is executing.
I wrote and tested the following code that removes most of the complexity from your snippets. It works by populating the select element on page load.
The HTML file:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<select data-src='test.php' data-id='id' data-name='name'></select>
</body>
</html>
<html>
<script>
$('select[data-src]').each(function() {
var $select = $(this);
$select.append('<option></option>');
$.ajax({
url: $select.attr('data-src'),
data: {'v0': 'Alligator', 'v1': 'Crocodile'}
}).then(function(options) {
options.map(function(option) {
var $option = $('<option>');
$option
.val (option[$select.attr('data-id')])
.text(option[$select.attr('data-name')]);
$select.append($option);
});
});
});
</script>
And the PHP file:
<?php
header("Content-Type: application/json; charset=UTF-8");
echo json_encode([
[ 'id' => 0, 'name' => 'Test User 0' ],
[ 'id' => 3, 'name' => $_GET['v0'] ],
[ 'id' => 4, 'name' => $_GET['v1'] ]
]);
Here's a fiddle that also demonstrates the behavior.
Here is the code I am working on for my Wordpress site:
jQuery:
jQuery(document).ready(function($)
{
var actionValue;
$(".tabRow li").on('click', function(event)
{
event.preventDefault(); //override default behaviour
var clicked = $(this); //caches click so we don't scan DOM again
if(clicked.attr('id')=="tabAddData") //tab1 clicked
{
actionValue = "tab1Clicked";
}
$("li").removeClass("selected");
clicked.addClass("selected");
alert ('starting ajax call');
$.ajax(
ajaxObject.ajaxurl, //request gets sent to this url
{ //start of [options]
type: 'POST',
dataType: 'json', //type of data expected back from server
//data to send to server (JSON format)
data:
{
action: 'ajaxAction',
nonce: ajaxObject.nonce,
actionName: actionValue
}
} //end of [options]
) //end ajax(), the other fuctions are chained to it (.done .fail .always)
.done (function(data)
{
alert ('success function');
if(actionValue == "tab1Clicked") //tab1 clicked
{
$('#dataSection').empty();
$('#dataSection').append(data);
}
}) //end of done (success) function
.fail (function(xhr, desc, err)
{
alert ('error function');
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}) //end of fail (error) function
}); //end of onclick
});
PHP:
<?php
$my_action='ajaxAction';
if(defined('DOING_AJAX') && DOING_AJAX)//check if AJAX is loaded and working
{
//for logged in users
add_action('wp_ajax_'.$my_action, 'ajaxResponse');
}
function ajaxResponse()
{
if(wp_verify_nonce($_POST['nonce'], 'ajaxAction'))
{
if($_POST['actionName'] == "tab1Clicked")
{
$addDataSection = getAddDataSection();
$response=array(
'status' => 'success',
'addDataSection' => $addDataSection
);
header('Content-type:application/json;charset=utf-8');
echo json_encode($response);//encodes the jQuery array into json format
die;
}
}
}
function getAddDataSection()
{
//lots of echo statements which builds the html code
}
?>
When I first load my page, my PHP function getAddDataSection() generates the HTML inside my <div id='dataSection>. This works fine.
When I click on tab1, my jQuery AJAX call is supposed to reuse the same PHP function to generate my HTML. This is not working fine.
After I click on tab1, the jQuery fail function is triggered.
When I check Firebug, the response data contains the html generated by my PHP function getDataSection(), followed by a JSON string
{"status":"success","addDataSection":null}
When replying, keep in mind I'm a newbie. Thanks :)
Updated to include Console error:
Details: parsererror
Error:SyntaxError: JSON.parse: unexpected character at line 2 column 1 of the JSON data
I think I found a solution.
In my jQuery, I changed the dataType from json to html.
Then in my PHP, I changed this:
if($_POST['actionName'] == "tab1Clicked")
{
$addDataSection = getAddDataSection();
$response=array(
'status' => 'success',
'addDataSection' => $addDataSection
);
header('Content-type:application/json;charset=utf-8');//still works without this line
echo json_encode($response);//encodes the jQuery array into json format
die;
}
to this:
if($_POST['actionName'] == "tab1Clicked")
{
$addDataSection = getAddDataSection();
echo $addDataSection;
die;
}
This issue works fine when calling ajax from PHP, but I can't seem to get it working with Laravel 5.2. All I'm trying to do is send an email using AJAX when submitting a form.
This is my routes.php entry for sending the email:
Route::post('/send', 'CommsController#send');
And this is my layout.blade.php file:
<head>
<meta name="csrf-token" content="{{ csrf_token() }}" />
</head>
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
...
$( "#send" ).button().click(function(event) {
var form = $( "#contact-form" ),
postAction = form.attr('action'),
isValid = form.valid(),
valSum = $(".validation-summary");
if ( isValid ) {
var postData = {
message_type: "contact"
,first_name: first_name.val()
,last_name: last_name.val()
,email: email.val()
,message: message.val()
};
// process the form
$.ajax({
type: "POST",
// our data object
url: postAction, // the url where we want to POST
data: postData
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
// here we will handle errors and validation messages
if ( ! data.success ) {
valSum.removeClass( "success" );
valSum.addClass( "validation-summary error" );
valSum.html( data );
} else {
// $( ".validation-summary" ).html( "Message sent." );
valSum.html( data.message );
}
})
// using the fail promise callback
.fail(function(data) {
// show any errors
// best to remove for production
console.log(data);
valSum.removeClass( "success" );
valSum.addClass( "validation-summary error" );
valSum.html( "Server Error: " + data.statusText + " processing your request, please contact Dorothea or report a bug." );
});
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
} else {
return false;
}
});
And finally here is my CommsController send() function:
public function send(Request $request) {
//check if its our form
if ( Session::token() !== Request::get( 'csrf-token' ) ) {
return Response::json( array(
'message' => 'Unauthorized attempt to create setting'
));
}
$message_type = strval(Request::input('message_type'));
$first_name = strval(Request::input('first_name'));
$last_name = strval(Request::input('last_name'));
$email = strval(Request::input('email'));
$message = strval(Request::input('message'));
$to = "robinson.jeanine6#gmail.com";
// subject
$subject = "Dorothea - Contact Us";
Mail::send('email.contact', ['request' => Request::all()], function ($message) use ($request) {
$message->from($this->email, $this->email);
$message->to($user->email, $user->email)->subject($subject);
});
$response = array(
'status' => 'success',
'message' => 'Message sent.',
);
return Response::json( $response );
}
This question is related to the one I posted here, but instead of getting a MethodNotAllowedHttpException, all that been returned now from the AJAX call is the CSRF-token value.
Replace .done callback with .success to get the return data.
.success(function(data) {
if (data.status != 'success' ) {
valSum.removeClass( "success" );
valSum.addClass( "validation-summary error" );
}
// eventually, print out the return message
valSum.html(data.message);
})
Just wanted to let everyone that tried to help me out know that sending of emails works fine in Laravel if I change the post request to a get request.
Not too sure why this is, so if anyone can shed some light as to why this would be the case that would be great.
here's the deal, i've created a search results page and i'd like to open a modal and retrieve profile data via ajax in php but i'm not too sure on how i can implement it. I've created the modal but but i don't know how i would go about getting the 'id' from clicking the search result, passing it onto ajax to retrieve the profile details.
Twitter has this kinda feature; when you click a username in a feed and it opens a modal and gives you a brief overview of the profile with a link to the full profile.
It would mean so much to me if someone could help me out or point me in the right direction! :)
P.S. I'm using codeigniter, if anyone is wondering what framework i'm using.
EDIT: here's the code
<?php
/*** PHP Search Results Loop ***/
if ($num > 0){
foreach ($query->result_array() as $row)
{
echo "link to ajax"'>";
}
} else {
echo "<strong>results not found :(</strong>";
}?>
<script> /* jQuery Runs When Result Has Been Clicked */
$('#ResultText').click(function() {
var targetid = {
id: /*Profile Id*/,
ajax: '1'
};
/* Modal Code */
$('.modal-backdrop, .modal-profilebox').css('display', 'block');
$('.modal-backdrop').animate({'opacity':'.50'}, 100, 'linear');
$('.modal-profilebox').animate({'opacity':'1.00'}, 200, 'linear');
$.ajax({
url: "<?php echo site_url('finder/modal'); ?>",
type: 'POST',
data: form_data,
success: function(profileData) {
$('.modal-profilebox').html(profileData);
}
});
return false;
});
</script>
Try something like this
public function ajax_user_profile($user_id)
{
if( !$this->input->is_ajax_request() )
{
redirect('/'); //only allow ajax requests
}
try
{
$user_profile = ''; //grab user object from DB
if( !$user_profile )
throw new Exception("Error Message");
}
catch(Exception $e)
{
log_message('error', $e->getMessage());
echo json_encode(array(
'error' => 1
));
exit;
}
$data = $this->load->view(array(
'some_view' => 'some_view',
'user' => $user_profile
), TRUE); //NO Template, just the view by adding TRUE
echo json_encode(array(
'error' => 0,
'data' => $data
)); //return view data
}
--
<a rel="modal" data-user-id="1" >Joe Bloggs</a>
--
(function($){
var userObj = {
init : function(){
this.getProfile();
},
getProfile : function(){
var modalSearch = $("a[rel='modal']");
modalSearch.on('click', function(){
//trigger the modal window
//request ajax
$.ajax({
url : BASEPATH + 'users/profile/' + $(this).data('user-id'),
type : 'POST',
dataType: 'json',
success : function(callback){
if(callback.error ==0)
{
$('.modal-profilebox').html(callback.data);
}
}
});
});
}
}
$(function(){
userObj.init()
});
})(jQuery);