How to Use AJAX in a WordPress Shortcode? How to Use AJAX in a WordPress Shortcode? wordpress wordpress

How to Use AJAX in a WordPress Shortcode?


Nice question!

But, as your code starts with a bad practice - require_once('wp-load.php'); -, I decided to pick one of my working snippets and adapt it.

Observations:

  • Differently from your code, no external quotes.txt is being grabbed, here a Post Type is used as source (post), in the method get_random_post
  • There can only be one instance of the shortcode in a given page, as it is based on specific element ID's (#newpost-shortcode and #randomposts)
  • As usual, it's better to create a plugin for this. Follow the code comments.

/wp-content/plugins/so-ajax-shortcode/so-ajax-shortcode.php

<?php/** * Plugin Name: (SO) Ajax Shortcode * Description: Demonstration of WordPress Ajax working as a shortcode. * Plugin URI:  http://stackoverflow.com/a/13614297/1287812 * Version:     2013.10.25 * Author:      Rodolfo Buaiz * Author URI:  https://wordpress.stackexchange.com/users/12615/brasofilo * License:     GPLv3 */add_action(    'plugins_loaded',    array ( B5F_SO_13498959::get_instance(), 'plugin_setup' ));class B5F_SO_13498959{    private $cpt = 'post'; # Adjust the CPT    protected static $instance = NULL;    public $plugin_url = '';    public function __construct() {}    public static function get_instance()    {        NULL === self::$instance and self::$instance = new self;        return self::$instance;    }    /**     * Regular plugin work     */    public function plugin_setup()    {        $this->plugin_url = plugins_url( '/', __FILE__ );        add_shortcode( 'randomposts', array( $this, 'shortcode') );        add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );        add_action( 'wp_ajax_query_rand_post', array( $this, 'query_rand_post' ) );        add_action( 'wp_ajax_nopriv_query_rand_post', array( $this, 'query_rand_post' ) );    }    /**     * SHORTCODE output     */    public function shortcode( $atts )     {        # First post        if( ! $random_post = $this->get_random_post() )            $random_post = __( 'Could not retrieve a post.' );        # Prepare output        $output = sprintf(            '<div id="randomposts">%s</div>             <button id="newpost-shortcode" type="button" title="%s">%s</button>',            $random_post,            __( 'Gimme a new one!' ),            __( 'New random post' )        );        return $output;    }    /**     * ACTION Enqueue scripts     */    public function enqueue()     {        # jQuery will be loaded as a dependency        ## DO NOT use other version than the one bundled with WP        ### Things will BREAK if you do so        wp_enqueue_script(              'ajax-random-post',             "{$this->plugin_url}ajax.js",             array( 'jquery' )        );        # Here we send PHP values to JS        wp_localize_script(              'ajax-random-post',             'wp_ajax',             array(                  'ajaxurl'      => admin_url( 'admin-ajax.php' ),                 'ajaxnonce'   => wp_create_nonce( 'ajax_post_validation' ),                 'loading'    => 'http://i.stack.imgur.com/drgpu.gif'            )         );    }    /**     * AJAX query random post     *      * Check for security and send proper responses back     */    public function query_rand_post()    {        check_ajax_referer( 'ajax_post_validation', 'security' );        $random_post = $this->get_random_post();        if( !isset( $random_post ) )            wp_send_json_error( array( 'error' => __( 'Could not retrieve a post.' ) ) );        else            wp_send_json_success( $random_post );    }    /**     * AUX FUNCTION      * Search a random Post Type and return the post_content     */    public function get_random_post()    {        $array = get_posts(             array(                   'post_type' => $this->cpt,                  'numberposts' => -1             )         );        if( empty( $array ) )            return false;        # Select a random post index number from the current array        $r = rand( 0, count($array) - 1 );        return $array[$r]->post_content;    }}

/wp-content/plugins/so-ajax-shortcode/ajax.js

/*  * @plugin SO Ajax Shortcode */jQuery( document ).ready( function( $ ) {      var data = {         action: 'query_rand_post',         security: wp_ajax.ajaxnonce     };     var image = '<img src="' + wp_ajax.loading + '" alt="Loading ..." width="16" height="16" />';    $( '#newpost-shortcode' ).click( function(e)     {        e.preventDefault();        $( '#randomposts' ).html( image );        $.post(             wp_ajax.ajaxurl,             data,                               function( response )            {                // ERROR HANDLING                if( !response.success )                {                    // No data came back, maybe a security error                    if( !response.data )                        $( '#randomposts' ).html( 'AJAX ERROR: no response' );                    else                        $( '#randomposts' ).html( response.data.error );                }                else                    $( '#randomposts' ).html( response.data );            }        );     }); // end click});


Here sample plugin as answer to the question. Using ajaxurl at frontend.

so-random-quotes.php

<?php/*Plugin Name: SO Random QuotesPlugin URI: http://azzrael.ruDescription: Reference to http://stackoverflow.com/questions/13498959/how-to-use-ajax-in-a-wordpress-shortcodeVersion: 1.0.0Author: AzzraelAuthor URI: http://azzrael.ru*/new SoRandomQuotes();/** * Class SoRandomQuotes */class SoRandomQuotes{    const SHORTCODE_KEY = 'randomquotes'; // usage [randomquotes path='/path/to/file/another.quotes.csv']    const AJAX_ACTION = 'so_getnewquote'; // ajax action    const DOM_TARGET =  'randomquotes'; // dom element to put the quotes    /**     * SoRandomQuotes constructor.     * init actions     */    function __construct() {        // adding shortcode        add_shortcode('randomquotes', array($this, 'addShortcode'));        // adding ajax callbacks        add_action( 'wp_ajax_'.self::AJAX_ACTION, array($this, 'getQuoteAjax')); // admin        add_action( 'wp_ajax_nopriv_'.self::AJAX_ACTION, array($this, 'getQuoteAjax')); // front    }    /**     * Shortcode callback     * @param $atts     * @return string     */    public function addShortcode($atts){        // getting path value from shortcode atts        $got =shortcode_atts( array(            'path'    => plugin_dir_path( __FILE__ ).'quotes.txt',        ), $atts );        // shortcode replacement        $out = sprintf(                    '<div id="%s">%s</div><a id="newquote" class="button" href="#" title="Gimme a new one!">New Quote</a>',                    self::DOM_TARGET,                    $this->getQuote($got['path'])               );        // loading js        // jquery depends        wp_enqueue_script('sorandquo-js', plugin_dir_url( __FILE__ ).'quote-loader.js', array('jquery'));        // passing to js needed vars        wp_localize_script( 'sorandquo-js', 'ajaxParams',            array(                'path'      => $got['path'], // path to qoutes file                'targetDom' => '#'.self::DOM_TARGET, // dom path to put resulting qoute                'ajaxurl'   => admin_url( 'admin-ajax.php'), // for frontend ( not admin )                'action'    => self::AJAX_ACTION, //            )        );        // render shortcode replacement        return $out;    }    /**     * Ajax Callback     */    public function getQuoteAjax(){        echo $this->getQuote($_POST['path']);        die();    }    /**     * Getting random Qoute from the file     * @param $path     * @return mixed     */    public function getQuote($path){        $quotesFile = is_file($path) ? file_get_contents($path):"File {$path} not found";        $quotesArr = $quotesFile ? explode("\n", $quotesFile):['Quotes File is empty'];        return $quotesArr[array_rand($quotesArr)];    }}

quote-loader.js

jQuery.noConflict();jQuery(document).ready(function($) {    $(document).on('click', '#newquote', function (e) {        e.preventDefault();        $.post(ajaxParams.ajaxurl, {            'action':ajaxParams.action,            'path'  :ajaxParams.path        }, function (ret) {            $(ajaxParams.targetDom).html(ret);        }, 'html');    });});


Wordpress shortcode same like function where you give parameters,

for creating ajax request you can use jQuery.ajax or xmlhttp in your header or function file with add_action wp_head hook.

you should create ajax.php in your theme folder and on the top of file you should include wp-load.php. and place all your ajax functions in proper manner.