AJAX form post returns 0

I am working on a simple plugin that shows an HTML form where the user can input a keyword which is used to query an external API. I currently have the form and the related jQuery set up, but when passed to the plugin’s PHP file, I get a response of simply 0. At this point I’m only just trying to get any response but 0 (see the echo "Whyyyy" part). I’ve been scouring the internet and feel like I have tried everything that’s been suggested, leading me to think I’m making a mistake somewhere.

Any help would be greatly appreciated. 🙏

This is the plugin’s PHP:

defined('ABSPATH') or die('Ah ah ah. You didn\'t say the magic word.');

class News_search {

    // Load scripts upon class initiation
    public function __construct() {
        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
        add_action('wp_ajax_get_news_callback', 'get_news_callback');
        add_action('wp_ajax_nopriv_get_news_callback', 'get_news_callback');
        add_shortcode('wp_news_search', array($this, 'wp_news_search_form'));
    }

    function enqueue_scripts() {
        // Enqueue CSS
        wp_enqueue_style('wp-news-search', plugins_url('/css/wp-news-search.css', __FILE__));
        // Enqueue and localize JS
        wp_enqueue_script('ajax-script', plugins_url('/js/wp-news-search_query.js', __FILE__), array('jquery'), null, true);
        wp_localize_script('ajax-script', 'ajax_object',
            array('ajax_url' => admin_url('admin-ajax.php'),
                'security' => wp_create_nonce('my-string-shh'),
            ));
    }

    // Handle AJAX request
    function get_news_callback() {
        check_ajax_referer('my-special-string', 'security');
        $keyword = isset($_POST['news-keyword']) ? $_POST['news-keyword'] : null;
        echo "Whyyyy";
        die();

    }

    public function wp_news_search_form() {
        $content .= '<form id="wp-news-search__form">
                        <label>
                            <input type="text" name="news-keyword" placeholder="' . __('Enter keywords') . '" id="news-keyword" required>
                        </label>
                        <button id="wp-news-search__submit">' .
                         __('Search for news', 'wp-news-search') .
                       '</button>
                    </form>';
        return $content;
    }

}

new News_search();

And this is the JS file:

(function ($) {

    $(document).ready(function () {
        $('#wp-news-search__form').submit(function (event) {
            event.preventDefault();

            // const keyword = $('#query-input').val();
            const values = $(this).serialize();


            if (values) {
                // send stuff to php
                console.log(values);
                const data = {
                    action: 'get_news_callback',
                    status: 'enabled',
                    security: ajax_object.security,
                    form_data: values
                }

                $.post(ajax_object.ajax_url, data, function(response) {
                    if (response) {
                        console.log(`Response is: ${response}`);
                    }
                })
                    .fail(() => { console.error('error'); })
                    .always(() => { console.log('form submitted') });
            }

        });


    });

})(jQuery);

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

your ajax post callable function action "get_news_callback" not working in your Class __construct() becuase You Can use simple WordPress action in the class.

Use Action In The Class :

add_action(‘wp_ajax_get_news_callback’, array($this,
‘get_news_callback’));
add_action(‘wp_ajax_nopriv_get_news_callback’, array($this, ‘get_news_callback’));

your Script also change So you Can Use below script to get your ajax response .

defined('ABSPATH') or die('Ah ah ah. You didn\'t say the magic word.');

class News_search {

// Load scripts upon class initiation
public function __construct() {
    add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
    add_action('wp_ajax_get_news_callback', array($this, 'get_news_callback'));
    add_action('wp_ajax_nopriv_get_news_callback', array($this, 'get_news_callback'));
    add_shortcode('wp_news_search', array($this, 'wp_news_search_form'));
}

function enqueue_scripts() {
    // Enqueue CSS
    wp_enqueue_style('wp-news-search', plugins_url('/css/wp-news-search.css', __FILE__));
    // Enqueue and localize JS
    wp_enqueue_script('ajax-script', plugins_url('/js/wp-news-search_query.js', __FILE__), array('jquery'), null, true);
    wp_localize_script('ajax-script', 'ajax_object',
        array('ajax_url' => admin_url('admin-ajax.php'),
            'security' => wp_create_nonce('my-string-shh'),
        ));
}

// Handle AJAX request
public function get_news_callback() {
    
    check_ajax_referer('my-string-shh', 'security');

    $keyword = isset($_POST['form_data']) ? $_POST['form_data'] : null;
    
    echo $keyword;
    
    die();

}



public function wp_news_search_form() {
    $content .= '<form id="wp-news-search__form">
                    <label>
                        <input type="text" name="news-keyword" placeholder="' . __('Enter keywords') . '" id="news-keyword" required>
                    </label>
                    <button id="wp-news-search__submit">' .
                     __('Search for news', 'wp-news-search') .
                   '</button>
                </form>';
     return $content;
   }

 }

 new News_search();

Your Js

(function ($) {

$(document).ready(function () {
    $('#wp-news-search__form').submit(function (event) {
        event.preventDefault();

        // const keyword = $('#query-input').val();
        const values = $(this).serialize();


        if (values) {
            // send stuff to php
            console.log(values);
            const data = {
                action: 'get_news_callback',
                status: 'enabled',
                type: "POST",
                security: ajax_object.security,
                form_data: values 
            }

            $.post(ajax_object.ajax_url, data, function(response) {
                if (response) {
                    console.log(`Response is: ${response}`);
                }
            })
                .fail(() => { console.error('error'); })
                .always(() => { console.log('form submitted') });
        }

    });


   });

})(jQuery);

Solution 2

The check_ajax_referer() function will die() if the check fails, which is why you won’t see anything after it, and the reason it’s failing is that the action names given to wp_create_nonce() and check_ajax_referer() do not match.

Here you’re using one string, 'my-string-shh':

'security' => wp_create_nonce('my-string-shh'),

But here you’re using another, 'my-special-string':

check_ajax_referer('my-special-string', 'security');

These need to match.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply