AJAX form post returns 0

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);