Using Ajax in meta-box button on post.php - ajax

I have created a plugin that creates a custom Post Type called smm_newsletter, and used that Post Type to create newsletter template and send a newsletter email. Then, I made a meta-box for sending button include in that Post Type's post-new.php/post.php.
The script for wp_localize_script is this
function smm_admin_scripts() {
wp_register_script( 'smm-js-priv-script', plugins_url( '/js/private/smm-builder.js', __FILE__ ), array( 'jquery' ), '', true );
// localize admin URL
$php_localized_priv_script = array( 'admin_url' => admin_url() );
wp_localize_script( 'smm-js-priv-script', 'smm_priv_script', $php_localized_priv_script );
wp_enqueue_script( 'smm-js-priv-script' );
}
add_action( 'admin_enqueue_scripts', 'smm_admin_scripts' );
*I added exactly same localized admin URL to my public scripts function and it work fine in input submit button. This code too, it work fine in input submit button.
This is code for that button
// I do not use type="submit" because publish/update button use it.
<input id="smm_newsletter_send" name="smm_newsletter_send" type="button" value="Send Newsletter">
and ajax
jQuery( document ).ready( function($) {
/* Newsletter Section */
// I did localized script for path to wp-admin here
var wpajax_url = smm_priv_script.admin_url + 'admin-ajax.php';
var sendingNewsletter_url = wpajax_url + '?action=smm_newsletter_sender';
// out put form console: http://localhost/wordpressProject/wordpress/wp-admin/admin-ajax.php?action=smm_newsletter_sender
console.log(sendingNewsletter_url);
$( '#smm_newsletter_send' ).on( 'click', function( e ){
e.preventDefault();
$form = $( 'form#post' );
// setup our form data for ajax post
var form_data = $form.serialize();
console.log( form_data ); // here it work find
// submit form data with ajax post
$.ajax({
'method' : 'post',
'url' : sendingNewsletter_url,
'data' : form_data,
'dataType' : 'json',
'catch' : false,
'success' : function( data, textStatus ){
if( data.status == 1 ) {
// success
// notify the user of success
window.location.reload( true );
console.log( data.status + '\n' );
console.log( data.message + '\n' + '——————————' );
} else {
// error
// begin building our error message text
console.log( data.status + ' ' + 'error' + '\n' );
console.log( data.message + '\n' + '——————————' );
}
},
'error' : function( jqXHR, textStatus, errorThrown ) {
// ajax didn't work
console.log('A jQuery Ajax error has occurred! See details below...');
console.log(textStatus);
console.log(errorThrown);
}
});
// stop the form from submitting nornally
return false;
});
});
But, after I clicked that button ajax() only console.log undefined for me
undefined error
undefined
——————————
So, I tried another method to test my sending newsletter function [smm_newsletter_sender()] to make sure that function works, by changing $_POST to $_GET. And simply placed URL that look like this http://localhost/wordpressProject/wordpress/wp-admin/admin-ajax.php?action=smm_newsletter_sender?post_ID=123. It worked perfectly, by sending all of newsletter emails and returning the proper JSON. My email sending function is working fine, but the button for send not, why?.
At first, I had suspected about ajax(), may I did something wrong about it? But I did not found anything wrong. So, may be It about WordPress itself that prevent something that I don't know.

The first thing is to print our scripts only on the pages we need. This is important because we don't want our styles/scripts printing all over wp-admin.
add_action( 'admin_print_scripts-post.php', 'smm_admin_script');
add_action( 'admin_print_scripts-post-new.php', 'smm_admin_script');
Also:
check if it's the correct Post Type before printing the scripts:
localize the full admin-ajax URL
localize the security nonce
function smm_admin_script() {
global $typenow;
if( 'smm_newsletter' !== $typenow )
return;
wp_enqueue_script('my-ajax', plugins_url( '/my-ajax.js', __FILE__ ), array('jquery') );
wp_localize_script(
'my-ajax',
'my_plugin',
array(
'ajaxnonce' => wp_create_nonce( 'nonce_smm' ),
'ajaxurl' => admin_url( 'admin-ajax.php' )
)
);
}
The file my-ajax.js will use the localized values my_plugin.ajaxnonce and my_plugin.ajaxurl. The action is defined on the Ajax PHP function.
For testing I used button#send-ajax and div#aresponse.
jQuery(document).ready(function($) {
$( '#send-ajax' ).click( function(e) {
e.preventDefault();
var data = {
action: 'sendform_smm',
security: my_plugin.ajaxnonce,
form_smm: { 'input1': 'value1', 'input2': 'value2' }
};
/*
You can send the full form as an object using:
form_smm: $form.serializeArray()
*/
$.post(
my_plugin.ajaxurl,
data,
function( response ){
// ERROR HANDLING
if( !response.success ) {
// No data came back, maybe a server error
if( !response.data )
$( '#aresponse' ).html( 'AJAX ERROR: no response' );
else
$( '#aresponse' ).html( response.data.error );
}
else
$( '#aresponse' ).html( response.data );
}
);
});
});
The Ajax function checks the nonce, you make your thing and return Error or Success:
add_action( 'wp_ajax_sendform_smm', 'sendform_smm_callback' );
function sendform_smm_callback() {
check_ajax_referer( 'nonce_smm', 'security' );
# Form values sent by JS
$received_data = $_POST['form_smm'];
# Read the data sent and send it back just for testing purposes.
$text = 'Input Field: ' . $received_data['input1'];
# Your form actions
$do_your_thing = true;
if( !$do_your_thing )
wp_send_json_error( array( 'error' => __( 'Error message.' ) ) );
else
wp_send_json_success( $text );
}

Looks like your ajax url displaying undefined.
You need to localize your script first like:
wp_register_script('myscript', get_stylesheet_directory_uri() . '/js/myscript.js', array('jquery'), '1.0.1', TRUE);
$protocol = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://';
wp_localize_script('myscript', 'ajax_obj', array('admin_ajax' =>admin_url('admin-ajax.php',$protocol)));
// Enqueued script with localized data.
wp_enqueue_script('myscript');
Then in your .js file read admin URL like :ajax_obj.admin_ajax.

I had tried in many ways to solve this problem. OK, I don't know why, but this make it work. At first, I changed method form POST to GET and input button to a.
This is happen in custom meta-box.
// I created nonce url for security thing
$nonce_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=smm_newsletter_sender&post_ID=' . $post->ID ), basename( __FILE__ ), 'smm_send_newsletter_nonce' );
// and changed inupt to a tag
echo( '<div>Send Newsletter' );
and in jQuery ajax()
jQuery( document ).ready( function($) {
$( '#smm_newsletter_send' ).on( 'click', function( e ){
$.ajax({
'method' : 'GET',
'url' : $( this ).attr( 'href' ),
'dataType' : 'json',
'catch' : false,
'success' : function( data, textStatus ){
if( data.status == 1 ) {
// success
// notify the user of success
window.location.reload( true );
console.log( data.status + '\n' );
console.log( data.message + '\n' + '——————————' );
} else {
// error
// begin building our error message text
console.log( data.status + 'error' + '\n' );
console.log( data.message + '\n' + '——————————' );
}
},
'error' : function( jqXHR, textStatus, errorThrown ) {
// ajax didn't work
console.log('A jQuery Ajax error has occurred! See details below...');
console.log(textStatus);
console.log(errorThrown);
}
});
e.preventDefault();
// stop the form from submitting nornally
return false;
});
});
As I said above, I don't know why this work and, in case of input button, why ajax() can not sent the request URL to sending action. So, this is only a practical way.
If someone can explain, please do it.
Thank.

Related

Forbidden Error in ajax call with wordpress

I'm getting 403 error in my plugin develop when I try to use ajax calls. I had disabled all plugins and activated default theme, no works. I have no cache plugin, and I have no server cache.
I get:
403
Forbidden
Access to this resource on the server is denied!
PHP
add_action('wp_ajax_actualizar_jornada', 'actualizar_jornada' );
add_action('wp_ajax_nopriv_actualizar_jornada', 'actualizar_jornada');
function actualizar_jornada() {
$postdata = $_POST;
echo $postdata;
wp_die();
}
LOCALIZATION SCRIPT
wp_register_script('lmfront-js', plugin_dir_url( __FILE__ ) . '../includes/js/lmfront.js');
wp_localize_script('lmfront-js', 'strings', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'lstJugadoresParticipantesPlaceholder' => __('Find Players', 'leaguemanagement'),
'lstEquiposTeamsPlaceholder' => __('Find Teams', 'leaguemanagement'),
));
wp_enqueue_script('lmfront-js');
JS
$('.btn-update-jornada').on('click', function(){
var idjornada = parseInt($(this).data('idjornada'));
var data = {
'action': 'actualizar_jornada',
'idjornada': idjornada,
'marcador_local': parseInt($('#resultado-local-' + idjornada).val()),
'marcador_visitante': parseInt($('#resultado-visitante-' + idjornada).val()),
};
$.ajax({
type : "post",
url : strings.ajaxurl,
data : data,
error: function(response){
console.error(response);
},
failure: function(response){
console.error(response);
},
success: function(response) {
console.log(response);
}
});
});

Like Post Button in wordpress

I tried to make a Like button for Posts so i found this tutorial with a lot of searching
tutorial : https://www.atomicsmash.co.uk/blog/create-like-post-button-in-wordpress/
but not worked to me !
my code in functions.php
add_action( 'rest_api_init', function () {
register_rest_route( 'example/v2', '/likes/(?P<id>\d+)', array(
'methods' => array('GET','POST'),
'callback' => 'example__like',
) );
});
function example__like( WP_REST_Request $request ) {
// Custom field slug
$field_name = 'postlike';
// Get the current like number for the post
$current_likes = get_field($field_name, $request['id']);
// Add 1 to the existing number
$updated_likes = $current_likes + 1;
// Update the field with a new value on this post
$likes = update_field($field_name, $updated_likes, $request['id']);
return $likes;
}
in ajax
<script type="text/javascript">
$('.like__btn').on('click', function(){
// AJAX call goes to our endpoint url
$.ajax({
url: 'http://192.168.1.8/p-test/wp-json/example/v2/likes/7',
type: 'post',
success: function() {
console.log('works!');
},
error: function() {
console.log('failed!');
}
});
// Change the like number in the HTML to add 1
var updated_likes = parseInt($('.like__number').html()) + 1;
$('.like__number').html(updated_likes);
// Make the button disabled
$(this).attr('disabled', true);
});
</script>
in HTML
<button class="like__btn">
<span class="like__number"><?php the_field('postlike'); ?></span>
</button>
Which part of the tutorial did I make a mistake?
Thanks for any help

$_FILES not working with ajax submit in woocommerce checkout

I am try to upload file on woocommerce checkout page but I am not able to upload file. I have also try to get value using print_r($_FILES) in create_order function in class-wc-checkout.php file but it will return blank array
When I have remove class checkout from checkout form then it will working fine (without ajax submit)
I want to submit form without ajax but I need ajax remain on checkout page because I have add some extra price using ajax (update price without refresh)
My ajax call to add extra fee.
jQuery('#PageCount').change(function () {
var state = jQuery('#PageCount').val();
var current_price = jQuery('#carttot').val();
var data = {
action: 'woocommerce_apply_state',
security: wc_checkout_params.apply_state_nonce,
state: state,
current_price: current_price
};
jQuery.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: data,
success: function (code) {
console.log(code);
if (code === '0') {
jQuery('body').trigger('update_checkout');
}
},
dataType: 'html'
});
return false;
});
and php code or woocommerce hooks to add extra fee
add_action('wp_ajax_woocommerce_apply_state', 'calculate_per_page', 10);
add_action('wp_ajax_nopriv_woocommerce_apply_state', 'calculate_per_page', 10);
function calculate_per_page() {
if (isset($_POST['state'])) {
global $woocommerce;
$weight = WC()->cart->cart_contents_weight;
$state = $_POST['state'];
$current_price = $_POST['current_price'];
$val = $current_price * $state -$current_price;
session_start();
$_SESSION['val'] = $val;
}
}
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee');
function woo_add_cart_fee() {
session_start();
$extracost = $_SESSION['val'];
WC()->cart->add_fee('Per page charges:', $extracost);
}
And my function to upload file..
add_action('woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta');
function custom_checkout_field_update_order_meta( $order_id ) {
if ($_FILES['avatar']['name']) {
if ( ! function_exists( 'wp_handle_upload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
$upload_dir = wp_upload_dir();
$path = $upload_dir['path'];
$fileName = $_FILES["avatar"]["name"];
$fileTmpLoc = $_FILES["avatar"]["tmp_name"];
$pathAndName = $path."/".$fileName;
$moveResult = move_uploaded_file($fileTmpLoc, $pathAndName);
update_post_meta( $order_id, 'uploaded_file_to_translate', $_FILES['avatar']['name']);
if ($_POST['billing_output_to_send'])
update_post_meta( $order_id, 'How do you want your translation sent to you?', esc_attr(htmlspecialchars($_POST['billing_output_to_send'])));
if ($_POST['PageCount'])
update_post_meta( $order_id, 'How many pages are in your documents?', esc_attr(htmlspecialchars($_POST['PageCount'])));
}
}
How it will possible?
$_FILES you can not get it at woocommerce_checkout_update_order_meta hook because of woocommerce serialize the form and submit form throw ajax,
as we know that form serialize can not submit files requests. but I have two solutions for doing this may be it work for you.
You can use a plugin woocommerce upload file in the checkout. you can easily find it on google
But if you want to upload custom files then you can use this
when onchange file fire an ajax and push file array in session when user checkout, get the files from the session and upload to the directory, and then destroy your session.
$('.fileupload').change(function(e){
var action = 'update_session_files';
e.preventDefault();
var fd = new FormData();
fd.append('action', action);
var files = $('input[name="file"]')[0].files[0];
fd.append('billing_artist_headshot', files);
$.ajax({
url: my_ajax_object.ajax_url,
type: 'post',
data: fd,
contentType: false,
processData: false,
success: function(response){
},
});
});
and ajax action
add_action( 'wp_ajax_nopriv_update_session_files', 'update_session_function' );
add_action( 'wp_ajax_update_session_files', 'update_session_function' );
function update_session_function(){
session_start();
$_FILES['billing_artist_headshot'];
// upload your file here with Wordpress and get the id.
}

Wordpress Ajax returns 0 from PHP data but the ajax is working

Everytime I click Submit the popup alert only ever gives me a value of 0, also the console never logs what I echo from the php function. The String "Monkey" below does appear in the html, but the data variable doesnt work. (note: I've omitted the full ajax URL from public display)
In my WP plugin I've put this code:
function register_bio_script(){
wp_register_script('bio-script',plugins_url('js/bio-script.js',__FILE__), false, '1.0.0', 'all');
}
add_action('init','register_bio_script');
function enqueue_bio_script(){
wp_enqueue_script( 'bio-script', plugin_dir_url(__FILE__) . 'js/bio-script.js' );
}
add_action('wp_enqueue_scripts', 'enqueue_bio_script');
add_action( 'wp_ajax_nopriv_ MyAjaxFunction', 'MyAjaxFunction' );
add_action( 'wp_ajax_ MyAjaxFunction', 'MyAjaxFunction' );
function MyAjaxFunction(){
$GreetingAll = $_POST['GreetingAll'];
echo "peanut";
$results = "<h2>".$GreetingAll."</h2>";
die($results);}
and then i have the JS:
jQuery(document).ready(function() {
var GreetingAll = jQuery("#GreetingAll").val();
jQuery("#PleasePushMe").click(function(){
jQuery.ajax({
type: 'POST',
url: '.../wp-admin/admin-ajax.php',//the full url goes here
data: {
action: 'MyAjaxFunction',
GreetingAll: GreetingAll
},
success: function(data, textStatus, XMLHttpRequest){
jQuery("#test-div1").html('');
jQuery("#test-div1").append("Monkey");
alert(data);
},
error: function(MLHttpRequest, textStatus, errorThrown){
alert(errorThrown);
}
});
});
});
solved! i had to use wp_localize_script() for frontend ajax. wp ajax only works for backend users unless the script is localized.
the actual coding is complex but all the answers are
in this tutorial http://www.benmarshall.me/wordpress-ajax-frontend-backend/

Shortcode not working in Wordpress AJAX

I am trying to use a shortcode from Ultimate Facebook plugin to display a FB connect button in an AJAX popup and can't seem to get it work properly. I searched and used the solution given by djb in this question - Why might a plugin's 'do_shortcode' not work in an AJAX request?, but it worked only partially. Ideally, I want a user to be able to sign in using FB and then save the list to her account. I want to use the plugin instead of embedding direct code because creates a new user in wordpress too when someone uses FB connect.
Procedure to reproduce issue -
Go to http://www.ajaymreddy.com/stg/country/india/#
Click on Start
Select any of checboxes - take care to not click on the text against
the checkboxes
Click on Save button in the popup If you are not logged in, the fb
connect button should show up. However, only the shortcode text is
currently showing up.
Code in functions.php -
//From http://wordpress.stackexchange.com/questions/53309/why-might-a-plugins-do-shortcode-not-work-in-an-ajax-request
add_action( 'init', function() {
ps_register_shortcode_ajax( 'show_fblogin', 'show_fblogin' );
} );
function ps_register_shortcode_ajax( $callable, $action ) {
if ( empty( $_POST['action'] ) || $_POST['action'] != $action )
return;
call_user_func( $callable );
}
function show_fblogin(){
if (!is_user_logged_in())
echo do_shortcode('[wdfb_connect]');
die ();
}
add_action( 'wp_ajax_show_fblogin', 'show_fblogin' );
add_action( 'wp_ajax_nopriv_show_fblogin', 'show_fblogin' );
Code in ajax file -
$(document).on( 'click', '#saveBtn', function (){
if (myAjax.loggedin==1)
{
jQuery.ajax({
type: 'POST',
url: myAjax.ajaxurl,
data: {
action: 'save_whslist',
selected: selected.toString(),
whsNonce: myAjax.selectNonce,
},
success: function(data, textStatus, XMLHttpRequest){
selected = [];
modal.close();
$("input.whsites").prop('disabled', true);
$("input.whsites").prop('checked', false);
},
error: function(MLHttpRequest, textStatus, errorThrown){
alert(errorThrown+' fail');
}
});
}
else
{
jQuery.ajax({
type: 'POST',
url: myAjax.ajaxurl,
data: {
action: 'show_fblogin',
selected: selected.toString(),
whsNonce: myAjax.selectNonce,
},
success: function(data, textStatus, XMLHttpRequest){
modal.open({content: "<p>Please login to save your travel list<br /><span>No auto posts on your wall!</span></p>"+data});
},
error: function(MLHttpRequest, textStatus, errorThrown){
alert(errorThrown+' fail');
}
});
}
});
Adding the solution for posterity -
I solved it by adding FB.XFBML.parse(); once the AJAX call returned succesfully. Hope this helps.

Resources