AJAX search on post pages by custom post type

I’m having an issue creating an ajax search on my single post pages. I need to limit the search results to the custom post types “fod_videos” and “post” and category 12. My issue is the search is returning all the posts under those filters and not taking the search value. I’m guessing I’m missing something obvious but I can’ figure it out. Here’s my setup.

<div class="panel">
  <h2>Search Videos</h2>
  <div id="my-search">
   <form role="search" method="get" id="searchform" action="http://myurl.com/" >
    <input type="text" value="" name="s" id="s" />
    <input type="submit" id="searchsubmit" value="Search" />
   </form>
  </div>
</div>

add_action('wp_ajax_wpa5000_search', 'wpa5000_search');
add_action('wp_ajax_nopriv_wpa5000_search', 'wpa5000_search');
function wpa5000_search(){
  global $wp_query;
  $search = $_POST['search_val'];
  $args = array(
    's' => $search,
    'posts_per_page' => 10,
    'cat' => 12, 
    'post_type' => array( 'post','fod_videos'  )
  );
  $wp_query = new WP_Query( $args );

  get_template_part( 'video-search-results' );

  exit;
}

add_action( 'wp_enqueue_scripts', 'wpa56343_scripts', 100 );
function wpa56343_scripts() {
 wp_enqueue_script(
    'wpa56343_script',
    get_template_directory_uri() . '/libs/search.js?ver=1.0',
    array( 'jquery' ),
    null,
    false
 );
 wp_localize_script(
    'wpa56343_script',
    'WPaAjax',
    array(
        'ajaxurl' => admin_url( 'admin-ajax.php' )
    )
 );
}

// search.php

Read More
$(document).ready(function($){
 $('#searchsubmit').click(function(e){
    var $panel = $(this).closest(".panel");
    $panel.empty();
    e.preventDefault();
    var search_val=$("#s").val();
    $.post(
        WPaAjax.ajaxurl,
        {
            action : 'wpa5000_search',
            search_val : search_val
        },
        function( response ) {
            $panel.append( response );
        }
    );
 });
});

//video-search-results.php

<?php
 while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
   //STUFF
<?php endwhile; ?>

Related posts

Leave a Reply

2 comments

  1. Instead of 'cat' => 12 and $wp_query use 'category_name' => slug and get_posts().

    Here is a basic example how it works:

    PHP

    add_action( 'wp_loaded', array ( 'T5_Ajax_Search', 'init' ) );
    
    /**
     * Ajaxify the search form.
     */
    class T5_Ajax_Search
    {
        /**
         * The main instance. You can create further instances for unit tests.
         * @type object
         */
        protected static $instance = NULL;
    
        /**
         * Action name used by AJAX callback handlers
         * @type string
         */
        protected $action = 't5_ajax_search';
    
        /**
         * Handler for initial load.
         *
         * @wp-hook wp_loaded
         * @return void
         */
        public static function init()
        {
            NULL === self::$instance and self::$instance = new self;
            return self::$instance;
        }
    
        /**
         * Constructor. Registers the actions.
         *
         *  @wp-hook wp_loaded
         *  @return object
         */
        public function __construct()
        {
            $callback = array ( $this, 'search' );
            add_action( 'wp_ajax_'        . $this->action,        $callback );
            add_action( 'wp_ajax_nopriv_' . $this->action, $callback );
            add_action( 'wp_enqueue_scripts', array ( $this, 'register_script' ) );
        }
    
        /**
         * Callback for AJAX search.
         *
         * @wp-hook wp_ajax_t5_ajax_search
         * @wp-hook wp_ajax_nopriv_t5_ajax_search
         * @return void
         */
        public function search()
        {
            $args  = array ( 's' => $_POST['search_term'] );
            $args  = apply_filters( 't5_ajax_search_args', $args );
            $posts = get_posts( $args );
            if ( $posts )
            {
                $this->render_search_results( $posts );
            }
            else
            {
                print '<b>nothing found</b>';
            }
            exit;
        }
    
        /**
         * Create markup from $posts
         *
         * @param array $posts Array of post objects
         * @return void
         */
        protected function render_search_results( $posts )
        {
            print '<ul class="t5-ajax-search-results">';
    
            foreach ( $posts as $post )
            {
                printf(
                    '<li><a href="%1$s">%2$s</a></li>',
                    get_permalink( $post->ID ),
                    esc_html( $post->post_title )
                );
            }
            print '</ul>';
        }
    
        /**
         * Register script and local variables.
         *
         * @wp-hook wp_enqueue_scripts
         * @return void
         */
        public function register_script()
        {
            wp_enqueue_script(
                't5-ajax',
                #plugins_url( __FILE__ ) . '/search.js',
                plugins_url( 'search.js', __FILE__ ),
                array ( 'jquery' ),
                NULL,
                TRUE
            );
    
            wp_localize_script(
                't5-ajax',
                'T5Ajax',
                array(
                    'ajaxurl' => admin_url( 'admin-ajax.php' ),
                    'action'  => $this->action
                )
            );
        }
    }
    

    JavaScript search.js

    jQuery( function( $ ) {
        // search filed
        var $s = $( '#s' );
        // the search form
        var $sForm = $s.closest( 'form' );
        console.log( $sForm );
        $sForm.on( 'submit', function( event) {
            event.preventDefault();
            $.post(
                T5Ajax.ajaxurl,
                {
                    action:     T5Ajax.action,
                    search_term: $s.val()
                },
                function( response ) {
                    // just append the result to the search form.
                    $sForm.append( response );
                }
            );
        });
    });
    

    Restricting the search

    add_filter( 't5_ajax_search_args', 'restrict_t5_search' );
    
    function restrict_t5_search( $args )
    {
        $args['post_type'] = array ( 'post', 'fod_videos' );
        $args['category_name']       = 'category-slug';
        return $args;
    }
    

    Instead of my $this->render_search_results( $posts ); you can also load a template from your theme and use the $posts array in a more sophisticated result. 🙂

  2. I got the original code working, but with the custom post type (without the categories). Add a hidden input in your form with your post type like this:

    <input type="hidden" name="post_type" value="fod_videos" />