I'm currently developing a plugin. In the plugin's main.php file, I have the following code to do an ajax post request:
main.php
<?php
add_action( 'admin_footer', 'first_ajax' );
function first_ajax() { ?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#mybutton').click(function(){
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action : 'second_ajax'
},
success: function(response) {
console.log("successful");
},
error: function(err) {
console.log(err);
}
});
});
});
</script>
<?php } ?>
But on the browser console, I see an error object.
Screenshot 1
Screenshot 2
I wrote this function taking as reference: https://codex.wordpress.org/AJAX_in_Plugins.
Any help is appreciated.
You're calling javascript from a php function tho your javascript is "raw" and not wrapped in a php variable. We're also missing a bunch of information in regard to the ajax action function (the php part which is supposed to answer to the request).
An ajax request need two things to be able to work properly.
The javascript call to action function and the backend php action function.
It a standard to use anonymous php functions as action functions.
Ajax action functions hooks are prepended with a wp_ajax_{$action} for public function (non-logged-in users) and wp_ajax_nopriv_{$action} for logged-in users. A logged-in user won't be able to use a public ajax function same goes for non-logged-in users.
The {$action} part is set in your javascript call to action function.
It is standard to pass a nonce as well as the ajax admin url through the localize_script() function. Localizing data only works if the script has already been registered.
An example of registering/enqueuing a script and localizing varaibles: functions.php
<?php
wp_enqueue_script( 'my-ajax-script', trailingslashit( get_template_directory_uri() ) . 'assets/js/my-ajax-script.js', array(), wp_get_theme()->version, true );
wp_localize_script( 'my-ajax-script', 'localize', array(
'_ajax_url' => admin_url( 'admin-ajax.php' ),
'_ajax_nonce' => wp_create_nonce( '_ajax_nonce' ),
) );
(The Object's name localize and variables _ajax_url and _ajax_nonce used in wp_localize_script() are just a personal preference).
A basic javascrip ajax call to action function looks like this: my-ajax-script.js
$( '#selector' ).click( function ( event ) {
$.ajax( {
type: 'POST',
url: localize._ajax_url,
context: this,
data: {
_ajax_nonce: localize._ajax_nonce,
action: '_wpso_73933867', //where this match {$action} from wp_ajax_{$action} in our php action function.
},
success: function ( response ) {
console.log( response );
//...
},
} );
} );
Where we use are localized variables: localize._ajax_url and localize._ajax_nonce (best practices).
A basic php ajax action function looks like this: functions.php
<?php
add_action( 'wp_ajax__wpso_73933867', function () {
if ( check_ajax_referer( '_ajax_nonce' ) ) {
//...
wp_send_json_success();
} else {
//...
wp_send_json_error();
};
wp_die();
} );
If the function is intended to be use by a non-logged-in user wp_ajax_nopriv should be prepended instead of wp_ajax_. Vice versa. If both case are supposed to be used, the function should be doubled.
Related
I'm writing a WordPress plugin (using the boilerplate recommended in the official documentation) and I need to incorporate an AJAX request to fill a DataList. I’m following the WP convention of sending my AJAX requests to “admin-ajax.php”.
My problem is that after doing everything “by the book” I can’t get it to work: the response from the server is always 0 (The default one). The server-side method to handle the request is not being triggered. I think it’s not being “hooked” at all. And I know the request enters the “admin-ajax” file.
The weird thing is that when I hook this method to “init” and process all AJAX requests in this function, it works perfectly. So, I’m pretty sure the problem is in the dynamic “wp_ajax_{$action}” and “wp_ajax_nopriv_{$action}” hooks. Any ideas?
Thanks in advance.
Here’s an extract of my code:
PHP
<?php
private function define_public_hooks() {
$plugin_public = new SR_Public($this->get_plugin_name(), $this->get_version());
$this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_scripts');
$this->loader->add_action('wp_ajax_sr_get_titles', $plugin_public, 'process_get_titles');
$this->loader->add_action('wp_ajax_nopriv_sr_get_titles', $plugin_public, 'process_get_titles');
}
public function enqueue_scripts() {
wp_enqueue_script(
$this->plugin_name,
PLUGIN_DIR_URL . 'public/js/sr-public.js',
array('jquery'),
$this->version
);
wp_localize_script(
$this->plugin_name,
'localizedData',
array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('sr_get_titles'),
)
);
}
public function process_get_titles() {
if ((!empty($_POST['action'])) && ($_POST['action'] === 'sr_get_titles')) {
check_ajax_referer('sr_get_titles');
// Load some data in $some_array...
wp_send_json($some_array);
}
}
JS
jQuery(document).ready(function($) {
"use strict";
var titleInput = $("#sr-title");
var titleDataList = $("#sr-requested-titles");
function ajaxRequest() {
var userInput = titleInput.val();
if (userInput.trim() !== "") {
$.ajax({
type: "POST",
dataType: "json",
url: localizedData.ajaxUrl,
data: {_ajax_nonce: localizedData.nonce, action: "sr_get_titles", user_input: userInput},
success: processSuccessResponse
});
}
}
function processSuccessResponse(data) {
if (data) {
titleDataList.empty();
data.forEach(function(item) {
titleDataList.append($("<option>").val(item));
});
}
}
titleInput.keyup(ajaxRequest);
});
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'm trying to implement basic ajax. I've been following this tutorial. My JS fires when I click the button but I get a 400 from the ajax url: POST http://localhost:8080/wp-admin/admin-ajax.php 400 (Bad Request)
As far as I can tell, I haven't strayed far from the tutorial code. Her is my JS:
jQuery(document).ready(function($){
$('#baa_form').submit(function(){
var data = {
action: 'baa_response'
}
$.post(ajaxurl, data, function(response){
alert('Hello');
});
return false;
});
});
PHP:
<?php
function baa_add_menu() {
global $baa_settings_page;
$baa_settings_page = add_menu_page( 'Basic Admin Ajax', 'Basic Admin Ajax', 'edit_pages', 'basic-admin-ajax', 'baa_render_settings_page', false, 62.1 );
}
function baa_load_scripts( $hook ) {
global $baa_settings_page;
if ( $hook !== $baa_settings_page ) {
return;
}
$path = plugin_dir_url( __FILE__ ) . 'js/basic-admin-ajax.js';
wp_enqueue_script( 'basic-admin-ajax', $path, array( 'jquery' ) );
}
add_action( 'admin_menu', 'baa_add_menu' );
add_action( 'admin_enqueue_scripts', 'baa_load_scripts' );
function baa_render_settings_page() {
?>
<form id="baa_form" method="POST">
<div>
<input type="submit" name="baa_submit_button" id="baa_submit_button" class="button-primary" value="go ajax">
</div>
</form>
<?php
}
function baa_response() {
die( 'I got died' );
}
I've had a look inside admin-ajax.php and the only reason for returning a 400 that I can see is if I've failed to set an action. data['action'] is certainly set, unless I'm crazy.
Am I doing anything that's obviously wrong? What could be causing the 400 response?
update
To clarify, the JS fires but the request to admin-ajax.php receives a 400. You can see where the tutorial make has implemented similar JS here. (I haven't added a nonce yet but the video maker had already demonstrated it working without implementing a nonce.)
edit
I've updated the PHP to show the plugin's entire PHP file.
update 2
I've stripped the JS back to the essentials and followed the top example from Wordpress. The response is still 400. Which leads me to believe that it might be something I've overlooked in the php. At the moment, I don't understand why or what it might be.
jQuery(document).ready(function($) {
var data = {
'action': 'baa_response'
};
$.post(ajaxurl, data, function(response) {
alert('Got this from the server: ' + response);
});
});
You missed action, which will fired on your Ajax request. WordPress can't guess which function related to your Ajax call, and that's why just blocking it( 400 Bad Request ).
In the php file add this line:
add_action('wp_ajax_baa_response', 'baa_response');
You may also want to look at the Ajax in Wordpress documentation.
Please try like this,
Add this to your functions.php,
$path = plugin_dir_url( __FILE__ ) . 'js/basic-admin-ajax.js';
wp_enqueue_script( 'basic-admin-ajax', $path, array('jquery'), '1.0', true );
wp_localize_script( 'basic-admin-ajax', 'action_linklist', array(
'ajax_url' => admin_url( 'admin-ajax.php' )
));
function baa_response() {
echo "something.....";
die();
}
in your JS file,
jQuery(document).ready(function($){
$('#baa_form').submit(function(){
jQuery.ajax({
url: action_linklist.ajax_url,
type: 'post',
data:{'action': 'baa_response'},
success: function (response) {
alert(response);
}
});
return false;
});
});
Hope this will helps you,
For more information, please visit.
Using AJAX with wordpress
AJAX in Plugins
I have searched for this a lot but still didn't found any solution for this . I want to call an ajax action after submission of post comment . How can I do this with WordPress ?
Without code, I cannot give you the following steps with code myself:
Track the event that triggers comment submission and on which DOM element it happens.
In the event handler, send an XMLHTTPRequest to server using jQuery.ajax.
Make sure you create the ajax call in the Wordpress way, and so by sending requests to wp-admin/admin-ajax.php and puting logic under functions.php. Add the die() function.
I would filter the comment with a WordPress filter. You may not need an AJAX request at all. But I'm not exactly sure why you need AJAX. To learn more about this filter.
function preprocess_comment_handler( $commentdata ) {
//some code
return $commentdata;
}
add_filter( 'preprocess_comment' , 'preprocess_comment_handler' );
If you do need AJAX, here's how to make it run in WordPress. You'll need to use wp_localize_script() to get your AJAX to admin-ajax.php.
//add wp_localize_script to your functions.php
//make sure to enqueue the js file you are writing to and it's dependencies
function acarter_enqueue_scripts() {
wp_enqueue_script( 'jquery' );
wp_enqueue_script('your-script', get_template_directory_uri() . '/js/theme.js');
wp_localize_script('your-script', 'your_script_vars', array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
)
);
}
add_action( 'wp_enqueue_scripts', 'acarter_enqueue_scripts' );
//do your AJAX call in the file you just enqueued
jQuery( document ).ready( function($) {
//Ajax Form Processing
var $form = $( '#button' )
$form.submit( function (e) {
e.preventDefault();
$.ajax({
type: '',
url: your_script_vars.ajaxurl,
data: {
action: 'function_name_of_the_callback',
//key : values of stuff you want in the php callback
},
dataType: 'json',
success: function (response) {
if ( true === response.success ) {
console.log( 'success!!' );
});
} else if ( false === response.success && response.data ) {
window.alert( 'doing it wrong' );
}
}
});
});
});
You maybe able to send the data to the aforementioned filter, thus using the filter as the callback, but, I've never tried this. At the least you'll know how to setup AJAX in WordPress.
I'm writing a Wordpress MU plugin, it includes a link with each post and I want to use ajax to call one of the plugin functions when the user clicks on this link, and then dynamically update the link-text with output from that function.
I'm stuck with the ajax query. I've got this complicated, clearly hack-ish, way to do it, but it is not quite working. What is the 'correct' or 'wordpress' way to include ajax functionality in a plugin?
(My current hack code is below. When I click the generate link I don't get the same output I get in the wp page as when I go directly to sample-ajax.php in my browser.)
I've got my code[1] set up as follows:
mu-plugins/sample.php:
<?php
/*
Plugin Name: Sample Plugin
*/
if (!class_exists("SamplePlugin")) {
class SamplePlugin {
function SamplePlugin() {}
function addHeaderCode() {
echo '<link type="text/css" rel="stylesheet" href="'.get_bloginfo('wpurl').
'/wp-content/mu-plugins/sample/sample.css" />\n';
wp_enqueue_script('sample-ajax', get_bloginfo('wpurl') .
'/wp-content/mu-plugins/sample/sample-ajax.js.php',
array('jquery'), '1.0');
}
// adds the link to post content.
function addLink($content = '') {
$content .= "<span class='foobar clicked'><a href='#'>click</a></span>";
return $content;
}
function doAjax() { //
echo "<a href='#'>AJAX!</a>";
}
}
}
if (class_exists("SamplePlugin")) {
$sample_plugin = new SamplePlugin();
}
if (isset($sample_plugin)) {
add_action('wp_head',array(&$sample_plugin,'addHeaderCode'),1);
add_filter('the_content', array(&$sample_plugin, 'addLink'));
}
mu-plugins/sample/sample-ajax.js.php:
<?php
if (!function_exists('add_action')) {
require_once("../../../wp-config.php");
}
?>
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
var aref = this;
jQuery(this).toggleClass('clicked');
jQuery.ajax({
url: "http://mysite/wp-content/mu-plugins/sample/sample-ajax.php",
success: function(value) {
jQuery(aref).html(value);
}
});
});
});
mu-plugins/sample/sample-ajax.php:
<?php
if (!function_exists('add_action')) {
require_once("../../../wp-config.php");
}
if (isset($sample_plugin)) {
$sample_plugin->doAjax();
} else {
echo "unset";
}
?>
[1] Note: The following tutorial got me this far, but I'm stumped at this point.
http://www.devlounge.net/articles/using-ajax-with-your-wordpress-plugin
TheDeadMedic is not quite right. WordPress has built in AJAX capabilities. Send your ajax request to /wp-admin/admin-ajax.php using POST with the argument 'action':
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
jQuery(this).toggleClass('clicked');
jQuery.ajax({
type:'POST',
data:{action:'my_unique_action'},
url: "http://mysite/wp-admin/admin-ajax.php",
success: function(value) {
jQuery(this).html(value);
}
});
});
});
Then hook it in the plugin like this if you only want it to work for logged in users:
add_action('wp_ajax_my_unique_action',array($sample_plugin,'doAjax'));
or hook it like this to work only for non-logged in users:
add_action('wp_ajax_nopriv_my_unique_action',array($sample_plugin,'doAjax'));
Use both if you want it to work for everybody.
admin-ajax.php uses some action names already, so make sure you look through the file and don't use the same action names, or else you'll accidentally try to do things like delete comments, etc.
EDIT
Sorry, I didn't quite understand the question. I thought you were asking how to do an ajax request. Anyway, two things I'd try:
First, have your function echo just the word AJAX without the a tag. Next, try changing your ajax call so it has both a success and a complete callback:
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
var val = '';
jQuery(this).toggleClass('clicked');
jQuery.ajax({
type:'POST',
data:{action:'my_unique_action'},
url: "http://mysite/wp-admin/admin-ajax.php",
success: function(value) {
val = value;
},
complete: function(){
jQuery(this).html(val);
}
});
});
});
WordPress environment
First of all, in order to achieve this task, it's recommended to register then enqueue a jQuery script that will push the request to the server. These operations will be hooked in wp_enqueue_scripts action hook. In the same hook you should put wp_localize_script that it's used to include arbitrary Javascript. By this way there will be a JS object available in front end. This object carries on the correct url to be used by the jQuery handle.
Please take a look to:
wp_register_script(); function
wp_enqueue_scripts hook
wp_enqueue_script(); function
wp_localize_script(); function
File: functions.php 1/2
add_action( 'wp_enqueue_scripts', 'so_enqueue_scripts' );
function so_enqueue_scripts(){
wp_register_script( 'ajaxHandle', get_template_directory() . 'PATH TO YOUR JS FILE', array(), false, true );
wp_enqueue_script( 'ajaxHandle' );
wp_localize_script( 'ajaxHandle', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
File: jquery.ajax.js
This file makes the ajax call.
jQuery(document).ready( function($){
//Some event will trigger the ajax call, you can push whatever data to the server, simply passing it to the "data" object in ajax call
$.ajax({
url: ajax_object.ajaxurl, // this is the object instantiated in wp_localize_script function
type: 'POST',
data:{
action: 'myaction', // this is the function in your functions.php that will be triggered
name: 'John',
age: '38'
},
success: function( data ){
//Do something with the result from server
console.log( data );
}
});
});
File: functions.php 2/2
Finally on your functions.php file there should be the function triggered by your ajax call.
Remember the suffixes:
wp_ajax ( allow the function only for registered users or admin panel operations )
wp_ajax_nopriv ( allow the function for no privilege users )
These suffixes plus the action compose the name of your action:
wp_ajax_myaction or wp_ajax_nopriv_myaction
add_action( 'wp_ajax_myaction', 'so_wp_ajax_function' );
add_action( 'wp_ajax_nopriv_myaction', 'so_wp_ajax_function' );
function so_wp_ajax_function(){
//DO whatever you want with data posted
//To send back a response you have to echo the result!
echo $_POST['name'];
echo $_POST['age'];
wp_die(); // ajax call must die to avoid trailing 0 in your response
}
Hope it helps!
Let me know if something is not clear.
Just to add an information.
If you want to receive an object from a php class method function :
js file
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
var data = {
'action': 'getAllOptionsByAjax',
'arg1': 'val1',
'arg2': $(this).val()
};
jQuery.post( ajaxurl, data, function(response) {
var jsonObj = JSON.parse( response );
});
});
php file
public static function getAllOptionsByAjax(){
global $wpdb;
// Start query string
$query_string = "SELECT * FROM wp_your_table WHERE col1='" . $_POST['arg1'] . "' AND col2 = '" . $_POST['arg2'] . "' ";
// Return results
$a_options = $wpdb->get_results( $query_string, ARRAY_A );
$f_options = array();
$f_options[null] = __( 'Please select an item', 'my_domain' );
foreach ($a_options as $option){
$f_options [$option['id']] = $option['name'];
}
$json = json_encode( $f_options );
echo $json;
wp_die();
}