I am using a metabox in the Post creator to store extra content as described in this post
Now, I would like to execute the shortcode [extra] on the click of a button similar to this post, but I can't get it to work.
Here's my code so far:
jQuery
jQuery(document).ready(function($) {
$('#extra').on('click',function() {
$.ajax({
type: "POST",
url: my_ajaxurl,
data: {
action : 'process_shortcode_on_click_action'
},
success:function(data) {
console.log("Success");
},
error: function(errorThrown){
console.log("Error");
}
});
})
})
functions.php
add_action( 'wp_enqueue_scripts', 'add_my_script' );
function add_my_script() {
wp_enqueue_script(
'extra-script', // name your script so that you can attach other scripts and de-register, etc.
get_template_directory_uri() . '/js/script.js', // this is the location of your script file
array('jquery') // this array lists the scripts upon which your script depends
);
wp_localize_script( 'extra-script', 'my_ajaxurl', admin_url( 'admin-ajax.php' ) );
}
add_shortcode( 'extra', 't5_extra_content' );
add_action( 'add_meta_boxes_post', 't5_register_extra_metabox' );
add_action( 'save_post', 't5_save_shortcode_box', 10, 2);
add_action( 'wp_ajax_process_shortcode_on_click_action', 'process_shortcode_on_click_ajax');
add_action( 'wp_ajax_nopriv_process_shortcode_on_click_action', 'process_shortcode_on_click_ajax');
function process_shortcode_on_click_ajax() {
echo do_shortcode('[extra]');
die;
}
function t5_extra_content( $attributes, $content = '' )
{
$args = shortcode_atts( array ( 'cap' => 'edit_posts' ), $attributes );
if ( current_user_can( $args['cap'] ) )
return wpautop(
get_post_meta( get_the_ID(), '_t5_extra_box', TRUE )
. $content
);
}
function t5_register_extra_metabox()
{
add_meta_box(
't5_extra',
'My Point of View',
't5_extra_metabox_callback',
NULL, // screen
'normal',
'default'
);
}
function t5_extra_metabox_callback( $post )
{
$nonce = wp_create_nonce( __FILE__ );
echo "<input type='hidden' name='t5_extra_box_nonce' value='$nonce' />";
$content = get_post_meta($post->ID, '_t5_extra_box', TRUE );
wp_editor(
$content,
'_t5_extra_box',
array (
'textarea_rows' => 10,
'media_buttons' => FALSE,
'teeny' => TRUE,
'tinymce' => TRUE
)
);
}
function t5_save_shortcode_box( $post_id )
{
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE
or ! isset ( $_POST['post_type'] )
or 'post' !== $_POST['post_type']
or ! current_user_can( 'edit_post', $post_id )
or ! wp_verify_nonce( $_POST[ 't5_extra_box_nonce' ], __FILE__ )
)
{
return;
}
if ( isset ( $_POST['_t5_extra_box'] ) )
update_post_meta( $post_id, '_t5_extra_box', $_POST['_t5_extra_box'] );
else
delete_post_meta( $post_id, '_t5_extra_box' );
}
I am seeing "Success" in the console, so I know that the jQuery is getting called correctly. I can't figure out how to get the do_shortcode('[extra]') to fire however. Any help is greatly appreciated.
Your ajax call does not have coxtent of the global $post from the page the ajax request is coming from and thus get_the_ID() should be false and get_post_meta( get_the_ID(), '_t5_extra_box', TRUE ) will also be false. Furthermore, you're calling do_shortcode('[extra]') (no content) so $content inside your callback will be an empty string. So return wpautop(get_post_meta( get_the_ID(), '_t5_extra_box', TRUE).$content); becomes return wpautop(''); which is just an empty string. Based on your code I would expect your data response to always be an empty string.
To fix this I would add an extra ajax post data item along with the action that tells the callback what $post_id should be. That's the most primitive way. You may want to add a nonce or some other measure for security (but that may not be relevant for your original question).
UPDATE
I haven't tested this, and you may want to do it differently, but here is one option. Ultimately you just need a way to get the $post_id from the original request and pass it along to the ajax call. Since you're already passing the ajax url via wp_localize_script, I would just add another JavaScript variable there.
jQuery
jQuery(document).ready(function ($) {
$('#extra').on('click', function () {
$.ajax({
type: "POST",
url: my_ajaxurl,
data: {
action: 'process_shortcode_on_click_action',
post_id: my_postid,
},
success: function (data) {
console.log("Success");
},
error: function (errorThrown) {
console.log("Error");
}
});
})
})
functions.php
add_action('wp_enqueue_scripts', 'add_my_script');
function add_my_script () {
wp_enqueue_script(
'extra-script', // name your script so that you can attach other scripts and de-register, etc.
get_template_directory_uri() . '/js/script.js', // this is the location of your script file
array('jquery') // this array lists the scripts upon which your script depends
);
wp_localize_script('extra-script', 'my_ajaxurl', admin_url('admin-ajax.php'));
wp_localize_script('extra-script', 'my_postid', get_the_ID());
}
add_action('wp_ajax_process_shortcode_on_click_action', 'process_shortcode_on_click_ajax');
add_action('wp_ajax_nopriv_process_shortcode_on_click_action', 'process_shortcode_on_click_ajax');
function process_shortcode_on_click_ajax ()
{
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
if (empty($post_id = $_POST['post_id']) || !is_numeric($post_id)) {
wp_die('Post ID is Invalid', 400);
}
echo do_shortcode("[extra post_id='{$post_id}']");
wp_die();
}
add_shortcode('extra', 't5_extra_content');
function t5_extra_content ($attributes, $content = '')
{
$defaults = [
'post_id' => get_the_ID(),
'cap' => 'edit_posts'
];
$args = shortcode_atts($defaults, $attributes);
if (!current_user_can($args['cap']) || empty($args['post_id'])) {
return ''; // or some message on fail
}
return wpautop(get_post_meta($args['post_id'], '_t5_extra_box', TRUE) . $content);
}
Related
My ajax call on click redirects me to /undefined, /wp-admin/admin-ajax.php has value 0
I'm using Divi theme, custom ajax script which is localized:
function my_enqueue() {
wp_enqueue_script( 'increment_counter', get_stylesheet_directory_uri() . '/js/slug-ajax.min.js', array('jquery') );
wp_localize_script( 'increment_counter', 'my_ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue' );
Counter function:
add_action('wp_ajax_increment_counter', 'my_increment_counter');
add_action('wp_ajax_nopriv_increment_counter', 'my_increment_counter');
function my_increment_counter(){
// Name of the option
$option_name = 'my_click_counter';
// Check if the option is set already
if ( get_option( $option_name ) !== false ) {
$new_value = intval(get_option($option_name)) + 1;
// The option already exists, so update it.
update_option( $option_name, $new_value );
} else {
// The option hasn't been created yet, so add it with $autoload set to 'no'.
$deprecated = null;
$autoload = 'no';
add_option( $option_name, 1 , $deprecated, $autoload );
}
}
Ajax file has this jQuery code for increment counter:
jQuery(document).ready(function($){
$('.activate-popup-animation').click(function(e){
e.preventDefault();
$.ajax({
url: my_ajax_object.ajaxurl,
data: {
action: 'increment_counter',
},
type: 'POST',
})
.done(function(){
// go to the link they clicked
window.location = $(this).attr('href');
})
.fail(function(xhr){
console.log(xhr);
})
});
});
Now, plan is to create custom widget in dashboard and call this function:
get_option('my_click_counter')
Where I'm making mistake, is that url problem with call action?
Your ajax function should call some action, in this case "my_increment_counter", but instead you wrote "increment_counter", same with wordpress hooks. It should be:
add_action('wp_ajax_my_increment_counter', 'my_increment_counter');
add_action('wp_ajax_nopriv_my_increment_counter', 'my_increment_counter');
I added a button to Checkout form :
<input type="submit" id="ajax-order-btn" class="button" value="Place Order via AJAX" />
and added a AJAX snippet in functions.php file:
add_action('wp_head', 'ajax_call_place_order');
function ajax_call_place_order() {
?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
$(document).on("click", "#ajax-order-btn" ,function(e) {
e.preventDefault();
var data = {
action: 'ajax_order',
};
$.post('<?php echo esc_url( home_url() ); ?>/wp-admin/admin-ajax.php', data);
});
});
</script>
<?php
}
And this is AJAX callback with which create a order programmatically:
add_action('wp_ajax_ajax_order', 'ajax_order_callback_wp');
add_action( 'wp_ajax_nopriv_ajax_order', 'ajax_order_callback_wp' );
function ajax_order_callback_wp() {
$address = array(
'first_name' => 'John',
'last_name' => 'Doe',
'company' => 'Speed Society',
'email' => 'joe#testing.com',
'phone' => '760-555-1212',
'address_1' => '123 Main st.',
'address_2' => '104',
'city' => 'San Diego',
'state' => 'Ca',
'postcode' => '92121',
'country' => 'US'
);
$order = wc_create_order();
$order->add_product( get_product('275962'), 1); // This is an existing SIMPLE product
$order->set_address( $address, 'billing' );
$order->calculate_totals();
$order->update_status("Completed", 'Imported order', TRUE);
}
The problem is that I can't find a way to get current order data, and to use that data when creating order programmatically instead of current hardcoded data. I need to place exact same order as the current one on Checkout page.
I was trying with WC_Checkout, and methods create_order() and get_checkout_fields(), but no success.
For PHP order creation I use a custom clone from WC_Checkout create_order() method that works perfectly. All submitted data is automatically set in the order.
For custom order meta data and custom order item meta data, you can use all woocommerce default hooks as:
woocommerce_checkout_create_order
woocommerce_checkout_update_order_meta
woocommerce_checkout_create_order_line_item
and so on …
I have also made some necessary changes in the jQuery code to make it work nicely, sending the necessary formatted data to PHP via Ajax*(which is now in the footer)*.
The complete code that create an order via Ajax:
add_action('wp_footer', 'checkout_billing_email_js_ajax' );
function checkout_billing_email_js_ajax() {
// Only on Checkout
if( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script type="text/javascript">
jQuery(function($){
if (typeof wc_checkout_params === 'undefined')
return false;
$(document.body).on("click", "#ajax-order-btn" ,function(evt) {
evt.preventDefault();
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
enctype: 'multipart/form-data',
data: {
'action': 'ajax_order',
'fields': $('form.checkout').serializeArray(),
'user_id': <?php echo get_current_user_id(); ?>,
},
success: function (result) {
console.log(result); // For testing (to be removed)
},
error: function(error) {
console.log(error); // For testing (to be removed)
}
});
});
});
</script>
<?php
endif;
}
add_action('wp_ajax_ajax_order', 'submited_ajax_order_data');
add_action( 'wp_ajax_nopriv_ajax_order', 'submited_ajax_order_data' );
function submited_ajax_order_data() {
if( isset($_POST['fields']) && ! empty($_POST['fields']) ) {
$order = new WC_Order();
$cart = WC()->cart;
$checkout = WC()->checkout;
$data = [];
// Loop through posted data array transmitted via jQuery
foreach( $_POST['fields'] as $values ){
// Set each key / value pairs in an array
$data[$values['name']] = $values['value'];
}
$cart_hash = md5( json_encode( wc_clean( $cart->get_cart_for_session() ) ) . $cart->total );
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
// Loop through the data array
foreach ( $data as $key => $value ) {
// Use WC_Order setter methods if they exist
if ( is_callable( array( $order, "set_{$key}" ) ) ) {
$order->{"set_{$key}"}( $value );
// Store custom fields prefixed with wither shipping_ or billing_
} elseif ( ( 0 === stripos( $key, 'billing_' ) || 0 === stripos( $key, 'shipping_' ) )
&& ! in_array( $key, array( 'shipping_method', 'shipping_total', 'shipping_tax' ) ) ) {
$order->update_meta_data( '_' . $key, $value );
}
}
$order->set_created_via( 'checkout' );
$order->set_cart_hash( $cart_hash );
$order->set_customer_id( apply_filters( 'woocommerce_checkout_customer_id', isset($_POST['user_id']) ? $_POST['user_id'] : '' ) );
$order->set_currency( get_woocommerce_currency() );
$order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
$order->set_customer_ip_address( WC_Geolocation::get_ip_address() );
$order->set_customer_user_agent( wc_get_user_agent() );
$order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );
$order->set_payment_method( isset( $available_gateways[ $data['payment_method'] ] ) ? $available_gateways[ $data['payment_method'] ] : $data['payment_method'] );
$order->set_shipping_total( $cart->get_shipping_total() );
$order->set_discount_total( $cart->get_discount_total() );
$order->set_discount_tax( $cart->get_discount_tax() );
$order->set_cart_tax( $cart->get_cart_contents_tax() + $cart->get_fee_tax() );
$order->set_shipping_tax( $cart->get_shipping_tax() );
$order->set_total( $cart->get_total( 'edit' ) );
$checkout->create_order_line_items( $order, $cart );
$checkout->create_order_fee_lines( $order, $cart );
$checkout->create_order_shipping_lines( $order, WC()->session->get( 'chosen_shipping_methods' ), WC()->shipping->get_packages() );
$checkout->create_order_tax_lines( $order, $cart );
$checkout->create_order_coupon_lines( $order, $cart );
/**
* Action hook to adjust order before save.
* #since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order', $order, $data );
// Save the order.
$order_id = $order->save();
do_action( 'woocommerce_checkout_update_order_meta', $order_id, $data );
echo 'New order created with order ID: #'.$order_id.'.' ;
}
die();
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Make your JS function to post the checkout field data as well and capture the data from $_POST
jQuery(document).ready(function($) {
$(document).on("click", "#ajax-order-btn" ,function(e) {
e.preventDefault();
var post_data: $( 'form.checkout' ).serialize()
var data = {
action: 'ajax_order',
post_data : post_data
};
$.post('<?php echo esc_url( home_url() ); ?>/wp-admin/admin-ajax.php', data);
});
});
This question already has answers here:
Wordpress admin-ajax.php 400 bad request
(8 answers)
Closed 4 years ago.
I'm working on a search plugin for the front-end of a Wordpress site. At the moment I keep getting a 400 Bad Request Error and I can't understand why. I've reviewed many questions on SO and the WordpressStackExchange but cannot see where I'm going wrong, nothing appears to be out of place. Please give me guidance:
plugin.php:
function my_admin_scripts() {
$localize = array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
);
wp_register_script('veh-app-search', plugin_dir_url( __FILE__ ) . '/ajax.js', '', '', true);
wp_localize_script( 'veh-app-search', 'veh_app_script', $localize);
wp_enqueue_script( 'veh-app-search', plugin_dir_url( __FILE__ ) . '/ajax.js', array( 'jquery' ) );
}
add_action( 'wp_enqueue_scripts', 'my_admin_scripts' );
add_action( 'wp_ajax_the_ajax_hook', 'handle_request' );
add_action( 'wp_ajax_nopriv_the_ajax_hook', 'handle_request' );
//takes care of the $_POST data
function handle_request(){
echo "hello";
}
ajax.js
var data = {
action: 'handle_request',
RequestType: 'category',
Category: jQuery('#Category option:selected').val()
};
jQuery.post(
veh_app_script.ajaxurl,
data,
function(categories){
console.log(categories);
}
);
One would expect to see "Hello" in the console but I only see the error in the console:
jquery.js?ver=1.12.4:4 POST http://localhost/wp-admin/admin-ajax.php 400 (Bad Request)
Please replace code and check
plugin.php
function my_admin_scripts() {
$localize = array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
);
wp_enqueue_script( 'veh-app-search', plugin_dir_url( __FILE__ ) . '/ajax.js', array( 'jquery' ) );
wp_localize_script( 'veh-app-search', 'veh_app_script', $localize);
}
add_action( 'wp_enqueue_scripts', 'my_admin_scripts' );
add_action( 'wp_ajax_handle_request', 'handle_request' );
add_action( 'wp_ajax_nopriv_handle_request', 'handle_request' );
//takes care of the $_POST data
function handle_request(){
echo "hello";
}
ajax.js
var data = {
action: 'handle_request',
RequestType: 'category',
Category: jQuery('#Category option:selected').val()
};
jQuery.post(
veh_app_script.ajaxurl,
data,
function(categories){
console.log(categories);
}
);
Use JSON instead:
function handle_request(){
echo json_encode( array( "message" => "hello" ) );
exit;
}
Parse the JSON in your ajax.js response handler:
function( response ) {
var returndata = JSON.parse( response );
console.log( returndata.message );
}
Don't forget to add json2 as a dependency to your script.
wp_enqueue_script( 'veh-app-search', plugin_dir_url( __FILE__ ) . '/ajax.js', array( 'jquery', 'json2' ) );
I am trying to minus a product or remove a product from cart.Suppose i have 3 same item in cart and i want to minus one but the ajax i used not works.I returns zero on console log.I thing this zero is from wp die().But it is expected to return some data.
Below is my codes in functions.php
add_action( 'wp_enqueue_scripts', 'the_foody_enqueue_cartajax_scripts' );
if ( ! function_exists( 'the_foody_enqueue_cartajax_scripts' ) )
{
function the_foody_enqueue_cartajax_scripts() {
wp_enqueue_script( 'ajax-script', get_template_directory_uri().'/js/ajax-cart.js', array('jquery'), '1.0', true );
wp_localize_script( 'ajax-script', 'cart_ajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
}
function the_foody_removefrom_cart_process(){
if( !wp_verify_nonce( $_POST['nonce'], 'foody_reservation_nonce' ) ){
die();
}
if( !isset($_POST['hash']) || !isset($_POST['quantity']) ){
exit;
}
$cart_item_key = $_POST['hash'];
if( !isset( WC()->cart->get_cart()[ $cart_item_key ] ) ){
exit;
}
$values = WC()->cart->get_cart()[ $cart_item_key ];
$_product = $values['data'];
// Sanitize
$quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT)) ), $cart_item_key );
if ( '' === $quantity || $quantity == $values['quantity'] )
exit;
// Update cart validation
$passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $values, $quantity );
if ( $passed_validation ) {
WC()->cart->set_quantity( $cart_item_key, $quantity, false );
}
// Recalc our totals
WC()->cart->calculate_totals();
return woocommerce_cart_totals();
}
add_action( 'wp_ajax_foody_removefrom_cart', 'the_foody_removefrom_cart_process' ); // If called from admin panel
add_action( 'wp_ajax_nopriv_foody_removefrom_cart', 'the_foody_removefrom_cart_process' );
And JS codes
function removefromCart( hash, nonce, qty ){
$.ajax({
action : 'foody_removefrom_cart',
type : 'POST',
url : cart_ajax.ajaxurl,
data : {
'hash' : hash,
'nonce' : nonce,
'quantity' : qty,
},
beforeSend : function(){
// codes to execute
},
success : function(response){
console.log(response);
}
})
}
But it returns only zero in console.
In js passed variable hash,nonce,qty are okay.
Got php codes from here
You should use like code below:
function removefromCart( hash, nonce, qty ){
$.ajax({
type : 'POST',
url : cart_ajax.ajaxurl,
data : {
'hash' : hash,
'nonce' : nonce,
'quantity' : qty,
action : 'the_foody_removefrom_cart_process',
},
beforeSend : function(){
// codes to execute
},
success : function(response){
console.log(response);
}
})
}
add_action( 'wp_ajax_the_foody_removefrom_cart_process', 'the_foody_removefrom_cart_process' ); // If called from admin panel
add_action( 'wp_ajax_nopriv_the_foody_removefrom_cart_process', 'the_foody_removefrom_cart_process' );
instead of
add_action( 'wp_ajax_foody_removefrom_cart', 'the_foody_removefrom_cart_process' ); // If called from admin panel
add_action( 'wp_ajax_nopriv_foody_removefrom_cart', 'the_foody_removefrom_cart_process' );
updated
type : 'POST',
url : cart_ajax.ajaxurl,
data : {
'hash' : hash,
'nonce' : nonce,
'quantity' : qty,
action : 'the_foody_removefrom_cart_process',
},
jQuery(document).ready(function(e) {
jQuery('#m').click(function()
{
//jQuery(this).fadeOut();
var d='<?php echo $plugins;?>';
jQuery.ajax({url:d,data:{q:10},type:GET,success: function(msg)
{
alert(msg);
}
}
)
});
I have to develop my own plugin, basically Wordpress has an admin-ajax file which handles this type of request, so how can I make it request using its own file to handle an Ajax request?
for that you need to do it like this:
jQuery(document).ready(function($) {
var data = {
action: 'my_action',
whatever: ajax_object.we_value // We pass php values differently!
};
// We can also pass the url value separately from ajaxurl for front end AJAX implementations
jQuery.post(ajax_object.ajax_url, data, function(response) {
alert('Got this from the server: ' + response);
});
});
and in your handler file :
add_action('wp_ajax_my_action', 'my_action_callback');
function my_action_callback() {
global $wpdb; // this is how you get access to the database
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
echo $whatever;
die(); // this is required to return a proper result
}
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue($hook) {
if( 'index.php' != $hook ) return; // Only applies to dashboard panel
wp_enqueue_script( 'ajax-script', plugins_url( '/js/my_query.js', __FILE__ ), array('jquery'));
// in javascript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value
wp_localize_script( 'ajax-script', 'ajax_object',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'we_value' => $email_nonce ) );
}
And Do not forget to enqueue your script :
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue($hook) {
if( 'index.php' != $hook ) return; // Only applies to dashboard panel
wp_enqueue_script( 'ajax-script', plugins_url( '/js/my_query.js', __FILE__ ), array('jquery'));
// in javascript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value
wp_localize_script( 'ajax-script', 'ajax_object',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'we_value' => $email_nonce ) );
}