0

Dear fellow Wordpress plugin developers,

I'm currently developing a WordPress custom booking plugin. In this plugin, I have added a calendar shortcode, which embeds an Html month calendar on the page. I also added some Jquery which should get the calendar of the previous or next month when the user clicks on the corresponding button. The jquery sends a post-request to admin-ajax.php, which should trigger an added ajax action. The problem only is that admin-ajax.php returns a 400, which means it can't find the action. I know the constructor of the Wp_Lbs_Calendar is triggered (which means the action has to be added), because the show function successfully returns a calendar to the page.

So I hope you guys can help me further.

My code:

Calendar class:

class Wp_Lbs_Calendar {  

/**
 * The ID of this plugin.
 *
 * @since    1.0.0
 * @access   private
 * @var      string    $plugin_name    The ID of this plugin.
 */
private $plugin_name;

/**
 * The version of this plugin.
 *
 * @since    1.0.0
 * @access   private
 * @var      string    $version    The current version of this plugin.
 */
private $version;


/**
 * Constructor
 */
public function __construct( $plugin_name, $version ) {
    $this->plugin_name = $plugin_name;
    $this->version = $version;  

    $this->naviHref = htmlentities($_SERVER['PHP_SELF']);

    add_action('wp_ajax_nopriv_get_next_calendar_ajax_action', array(get_called_class(), 'get_next_calendar_ajax_action') );
    add_action('wp_ajax_get_next_calendar_ajax_action', array(get_called_class(), 'get_next_calendar_ajax_action') );

    wp_enqueue_style( $this->plugin_name.'_calendar');
    wp_enqueue_script( $this->plugin_name.'_calendar');
    wp_localize_script( $this->plugin_name.'_calendar', 'my_ajaxurl', admin_url( 'admin-ajax.php' ) );
}

private function _createScript(){
    $nextMonth = $this->currentMonth==12?1:intval($this->currentMonth)+1;

    $nextYear = $this->currentMonth==12?intval($this->currentYear)+1:$this->currentYear;

    $preMonth = $this->currentMonth==1?12:intval($this->currentMonth)-1;

    $preYear = $this->currentMonth==1?intval($this->currentYear)-1:$this->currentYear;

    return '<script>function prev(){getNextCalendar(\''.$this->version.'\','.$preMonth.','.$preYear.');}
    function next(){getNextCalendar(\''.$this->version.'\','.$nextMonth.','.$nextYear.');}</script>';
}

...

public function show(){
    ...
}

public static function get_next_calendar_ajax_action(){
    if(isset($_POST['plugin_name']) && isset($_POST['version'])  && isset($_POST['year']) && isset($_POST['month']) ){           
        $plugin_name = htmlentities($_POST['plugin_name']);
        $version = htmlentities($_POST['version']);
        $year = htmlentities($_POST['year']);
        $month = htmlentities($_POST['month']);

        $Calendar = new Wp_Lbs_Calendar($plugin_name, $version);
        echo $Calendar->ShowByDate($month, $year);
    }
    wp_die();
}
}

My shortcode class:

class Wp_Lbs_Shortcodes {

    /**
     * The ID of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string    $plugin_name    The ID of this plugin.
     */
    private $plugin_name;

    /**
     * The version of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string    $version    The current version of this plugin.
     */
    private $version;

    /**
     * Initialize the class and set its properties.
     *
     * @since    1.0.0
     * @param      string    $plugin_name       The name of the plugin.
     * @param      string    $version    The version of this plugin.
     */
    public function __construct( $plugin_name, $version ) {

        $this->plugin_name = $plugin_name;
        $this->version = $version;

    }

    public function calendar($atts = [], $content = null){
        include_once('partials/wp-lbs-calendar.php');
        $Calendar = new Wp_Lbs_Calendar($this->plugin_name, $this->version);
        return $Calendar->show();
    }
}

The style is loaded in an other file as follows:

public function enqueue_scripts() {

    wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/wp-lbs-public.js', array( 'jquery' ), $this->version, false );
    wp_register_script( $this->plugin_name.'_calendar', plugin_dir_url( __FILE__ ) . 'js/wp-lbs-get-calendar.js', array( 'jquery' ), $this->version, false );

}

The javascript file:

function getNextCalendar(plugin_version, year, month){
    jQuery.ajax({
        url: my_ajaxurl,
        type: "POST",
        data:{
            action: 'get_next_calendar_ajax_action',
            plugin_name: 'wp_lbs',
            version: plugin_version,
            year: year,
            month: month
        },
        success: function(result){
            $('#calendar').parent().html(result);
        }
    });
}

1 Answer 1

0

You can't hook an AJAX action from within a shortcode, and the constructor for Wp_Lbs_Calendar is only running inside your shortcode.

This means that the actions are only hooked to wp_ajax_ when your shortcode is used on the page. But the AJAX request is a separate request to admin-ajax.php, and your shortcode is not running on on that page, so the actions are not hooked and will not run.

Your add_action()s for AJAX need to be hooked in a place that lets them run on every page load, so that the handler is available on admin-ajax.php.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.