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');
Related
I've been working with WooCommerce recently and I was wondering if it was possible to get cart items via JavaScript or JQuery
I know you can use PHP functions to retrieve the contents of the cart but currently I do not have access to the backend of the site.
I've found a similar question here: WooCommerce cookies and sessions - Get the current products in cart
In the session there is a wc_fragment that contains the HTML of the cart.
{"div.widget_shopping_cart_content":"<div class=\"widget_shopping_cart_content\">\n\n\t<ul class=\"woocommerce-mini-cart cart_list product_list_widget \">\n\t\t\t\t\t\t<li class=\"woocommerce-mini-cart-item mini_cart_item\">\n\t\t\t\t\t×\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t<img width=\"800\" height=\"450\" src=\"https://cdn2.co.uk/app/uploads/Overlapped-800x450.jpg\" class=\"attachment-woocommerce_thumbnail size-woocommerce_thumbnail\" alt=\"\" />Raspberry Drinking Yogurt - 1 drink\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"quantity\">1 × <span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">£</span>1.50</span></span>\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\n\t<p class=\"woocommerce-mini-cart__total total\">\n\t\t<strong>Subtotal:</strong> <span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">£</span>1.50</span>\t</p>\n\n\t\n\t<p class=\"woocommerce-mini-cart__buttons buttons\">View basketCheckout</p>\n\n\t\n\n</div>"}
Would it be possible to extract the elements from this?
I've found a solution for you. Maybe there is a better one but's how I would do it.
First create a custom JS file and register it. Also add a custom ajaxurl (in case you don't did this already):
add_action( 'wp_enqueue_scripts', 'wp_enqueue_scripts_action' );
function wp_enqueue_scripts_action() {
wp_register_script( 'child-theme', get_stylesheet_directory_uri() . '/assets/child.js', [ 'jquery' ] );
wp_enqueue_script( 'child-theme' );
wp_localize_script( 'child-theme', 'child_theme', [
'ajaxurl' => admin_url( 'admin-ajax.php' )
]
);
}
Now add an AJAX endpoint:
add_action( 'wp_ajax_get_cart_items', 'wp_ajax_get_cart_items_action' );
add_action( 'wp_ajax_nopriv_get_cart_items', 'wp_ajax_get_cart_items_action' );
function wp_ajax_get_cart_items_action() {
$cart = WC()->cart;
if ( $cart ) {
wp_send_json_success( $cart->get_cart_contents() );
/** #noinspection ForgottenDebugOutputInspection */
wp_die();
}
}
This will return the content of the cart in case a cart is available. Now call it inside your JS function. In my case for testing directly in the document.ready method:
(function ( $ ) {
$( document ).ready( function () {
let data = {
action: 'get_cart_items'
};
$.post( child_theme.ajaxurl, data, function () {
} ).done( function ( response ) {
console.log( response );
} ).fail( function ( response ) {
console.log( 'Fail' );
} );
} );
})( jQuery );
This will return for example:
077e29b11be80ab57e1a2ecabb7da330: {key:
"077e29b11be80ab57e1a2ecabb7da330", product_id: 249, variation_id: 0,
variation: Array(0), quantity: 1, …}
I think you need to add some null checks but all in all its a working solution.
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);
}
I have used Wordpress Admin Ajax and the console shows that 400 (Bad Request)
jQuery('#submitid').click(function(e){
e.preventDefault();
//var newCustomerForm = jQuery(this).serialize();
jQuery.ajax({
type: "POST",
url: "wp-admin/admin-ajax.php",
data: {status: 'status', name: 'name'},
success:function(data){
jQuery("#result").html(data);
}
});
});
The Wordpress AJAX process has some basic points that should be followed if you want it to work correctly:
1.In functions.php add the action you'd like to call from the frontend:
function logged_in_action_name() {
// your action if user is logged in
}
function not_logged_in_action_name() {
// your action if user is NOT logged in
}
add_action( 'wp_ajax_logged_in_action_name', 'logged_in_action_name' );
add_action( 'wp_ajax_nopriv_not_logged_in_action_name', 'not_logged_in_action_name' );
2.Register the localization object in functions.php
// Register the script
wp_register_script( 'some_handle', 'path/to/myscript.js' );
// Localize the script with new data
$some_object = array(
'ajax_url' => admin_url( 'admin-ajax.php' )
);
wp_localize_script( 'some_handle', 'ajax_object', $some_object );
// Enqueued script with localized data.
wp_enqueue_script( 'some_handle' );
3.Create the AJAX request on the frontend
// source: https://codex.wordpress.org/AJAX_in_Plugins
var data = {
'action': 'not_logged_in_action_name',
'whatever': 1234
};
jQuery.post( ajax_object.ajax_url, data, function( response ) {
console.log( response );
}
All Wordpress Ajax call must have action param which points to hook wp_ajax_{action_param} or wp_ajax_nopriv_{action_param} and from there you jump to function from that hooks.
From Codex:
add_action( 'wp_ajax_my_action', 'my_action' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action' );
function my_action() {
$status = $_POST['status'];
}
first you shouldn't write the url by yourself. You could use the localize function to add the url to your javascript file:
wp_enqueue_script('myHandle','pathToJS');
wp_localize_script(
'myHandle',
'ajax_obj',
array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) )
);
After this you can use ajax_obj.ajax_url within your script to receive the url.
Second, did you implement the correct hook?
// Only accessible by logged in users
add_action( 'wp_ajax_my_action', 'my_action_callback' );
// Accessible by all visitors
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
Best Regards
I am developing a WordPress plugin and I am trying to pass a variable from ajax to a php file. Both files are inside my plugin folder. The js file is running but when I fire the ajax function, it seems that is not sending a post.
Plugin structure:
-plugin folder
--ajax.js
--folder/example.php
This is my ajax.js
// using jQuery ajax
// send the text with PHP
$.ajax({
type: "POST",
url: "/absoluteurlpluginfolder/folder/example.php",
data: {
'action': 'my_action',
'whatever': 1234
},
// dataType: "text",
success: function(data){
console.log('Connection success.');
// console.log(data);
}
});
And this is my example.php
add_action( 'wp_ajax_my_action', 'my_action' );
function my_action() {
global $wpdb; // this is how you get access to the database
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
alert($whatever);
wp_die(); // this is required to terminate immediately and return a proper response
}
I have two problems:
I cannot see that example.php is receiving anything
How could I use a relative URL to connect with my PHP file? When I try such as 'url: "folder/example.php",' it seems that it starts with "http://localhost/my-wp-project/wp-admin/" and not in my plugin folder, and fails.
I think that the main problem was that I need to add "wp_enqueue_script" and "wp_localize_script". However, I am working in the development of a TinyMCE plugin inside WordPress.
That means that although the JS file is already include, it is not working when I add "wp_enqueue_script" and "wp_localize_script". Why? I do not know but the strange thing is that I made it working with another line.
wp_register_script( 'linked-plugin-script', null);
I have tried with different versions, and the minimum necessary to work is this one above. I can put the URL, version, jquery dependency and false or true. All of them work.
So at the end this is my code and is working.
This is the plugin.php
// Include the JS for TinyMCE
function linked_tinymce_plugin( $plugin_array ) {
$plugin_array['linked'] = plugins_url( '/public/js/tinymce/plugins/linked/plugin.js',__FILE__ );
return $plugin_array;
}
// Add the button key for address via JS
function linked_tinymce_button( $buttons ) {
array_push( $buttons, 'linked_button_key' );
return $buttons;
}
// Enqueue the plugin to manage data via AJAX
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue() {
wp_register_script( 'linked-plugin-script', null);
wp_enqueue_script( 'linked-plugin-script');
// in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value
wp_localize_script( 'linked-plugin-script', 'ajax_object', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'whatever' => '' )
);
}
// Same handler function...
add_action( 'wp_ajax_my_action', 'my_action' );
function my_action() {
global $wpdb;
$whatever = strtoupper($_POST['whatever']);
echo $whatever;
wp_die();
}
And this is the plugin of TinyMCE in JavaScript
// JavaScript file for TinyMCE Linked Plugin
//
//
//
( function() {
tinymce.PluginManager.add( 'linked', function( editor, url ) {
// Add a button that opens a window
editor.addButton( 'linked_button_key', {
// Button name and icon
text: 'Semantic Notation',
icon: false,
// Button fnctionality
onclick: function() {
// get raw text to variable content
var content = tinymce.activeEditor.getContent({format: 'text'});
// using jQuery ajax
// send the text to textrazor API with PHP
$.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: { 'action': 'my_action',
'whatever': ajax_object.whatever = content
},
beforeSend: function() {
console.log('before send..');
},
success: function(response){
console.log('Success the result is '+response);
}
});
} // onclick function
} ); // TinyMCE button
} ); // tinymce.PluginManager
} )(); // function
Have you seen this page? This is the best tutorial. But you have missed a few things:
You should set global js variable with wp_localize_script() function. Like
wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'we_value' => 1234 ) );
Replace your url in JS to ajax_object.ajax_url.
IF you wanna work ajax with wp_ajax hooks - you should send all your requests do wp-admin/admin-ajax.php. You can get this url by admin_url('admin-ajax.php');.
I am attempting to add auto complete search function in Wordpress, I have the code but auto complete does not trigger when i start typing in the search field, anybody can guide me in the right direction?
//php
add_action( 'init', 'casino_autocomplete_init' );
function casino_autocomplete_init() {
// Register our jQuery UI style and our custom javascript file
wp_enqueue_style('mycasino-jquery-ui','http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css');
wp_enqueue_script( 'my_acsearch', get_template_directory_uri() . '/js/myacsearch.js', array('jquery','jquery-ui-autocomplete'),null,true);
wp_localize_script( 'my_acsearch', 'MyAcSearch', array('url' => admin_url( 'admin-ajax.php' )));
// Function to fire whenever search form is displayed
add_action( 'get_search_form', 'mycasino_autocomplete_search_form' );
// Functions to deal with the AJAX request - one for logged in users, the other for non-logged in users.
add_action( 'wp_ajax_casino_autocompletesearch', 'mycasino_autocomplete_suggestions' );
add_action( 'wp_ajax_nopriv_casino_autocompletesearch', 'mycasino_autocomplete_suggestions' );
}
function mycasino_autocomplete_search_form(){
wp_enqueue_script( 'my_acsearch' );
wp_enqueue_style( 'mycasino-jquery-ui' );
}
function mycasino_autocomplete_suggestions(){
// custom post type
function filter_search($query) {
if ($query->is_search) {
$query->set('post_type', array('custom_post', 'events'));
};
return $query;
};
add_filter('pre_get_posts', 'filter_search');
// Query for suggestions
$posts = get_posts( array(
's' =>$_REQUEST['term'],
) );
// Initialise suggestions array
$suggestions=array();
global $post;
foreach ($posts as $post): setup_postdata($post);
// Initialise suggestion array
$suggestion = array();
$suggestion['label'] = esc_html($post->post_title);
$suggestion['link'] = get_permalink();
// Add suggestion to suggestions array
$suggestions[]= $suggestion;
endforeach;
// JSON encode and echo
$response = $_GET["callback"] . "(" . json_encode($suggestions) . ")";
echo $response;
// Don't forget to exit!
exit;
}
// jquery
jQuery(document).ready(function ($){
var acs_action = "casino_autocompletesearch";
$("#s").autocomplete({
source: function(req, response){
$.getJSON(MyAcSearch.url+"?callback=?&action="+acs_action, req, response);
},
select: function(event, ui) {
window.location.href=ui.item.link;
},
minLength: 3,
});
});
Please make sure you're using get_search_form() for calls and not get_search_query() you can check this inside the themes php file where the search field has been created. The above code can only be used by themes that uses get_search_form()