Template issues getting ajax search results

I’m trying to put search results into a div with ajax. The issue is I’m getting errors saying undefined function have_posts() when the the search template is accessed. It also took issue with get_header() which was in the search-results.php but I took it out. Here’s how I have it setup.

  <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 id="results"></div>
  <script type="text/javascript">
    $(document).ready(function(){
    $("#searchsubmit").click(function(e){
     e.preventDefault();
     var search_val=$("#s").val(); 
     $.post('http://mysite.com/wp-content/themes/beta/search-results.php',{search_string:search_val},function(data){
        if(data.length>0){
            $("#results").html(data);
        }
     });
    });   
   });
  </script>

And here is the search-results.php template. I’m wondering if maybe I’m not passing the search results to the template.

<ul>
 <?php if (have_posts()) : while (have_posts()) : the_post();  ?>
  <li><a title="Permalink to this post" href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a></li>

 <?php endwhile; endif; ?>
 <?php if (!have_posts()) { echo('<li>No results to show.</li>'); } ?>
</ul>

Related posts

Leave a Reply

1 comment

  1. When you load a template file directly that way, you’re not loading the WordPress environment, so no WordPress functions are available.

    Your two options are to either load the search page on the front end and filter the result, like:

    $('#results').load('http://mysite.com/?s=searchterm ul#target');
    

    Or build a search function using WordPress provided AJAX functionality, see AJAX in Plugins.

    EDIT

    Here’s an example of how I load additional posts via AJAX which you could adapt to create a search function if you wish.

    First, in functions.php, I enqueue my javascript and localize the script to pass the AJAX URL that will process my requests. WordPress AJAX uses admin-ajax.php to process all AJAX requests, front or back end:

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

    In scripts.js, my javascript that calls my AJAX action, and passes a postoffset var so I can pass that to the query. Note also the use of WPaAjax.ajaxurl to pass the URL that will process this request:

    jQuery(document).ready(function($){
    
        $('#blog-more').click(function(e){ // <- added
            e.preventDefault(); // <- added to prevent normal form submission
            var postoffset = $('.post').length;
            $.post(
                WPaAjax.ajaxurl,
                {
                    action : 'wpa56343_more',
                    postoffset : postoffset
                },
                function( response ) {
                    $('#container').append( response );
                }
            );
        });
    
    });
    

    In functions.php, the function that processes my AJAX request mapped to the action I passed in the javascript above. A stripped down version of WordPress is bootstrapped, so I can access most WordPress functions:

    add_action('wp_ajax_wpa56343_more', 'wpa56343_more');
    add_action('wp_ajax_nopriv_wpa56343_more', 'wpa56343_more');
    
    function wpa56343_more(){
        global $wp_query;
    
        $offset = $_POST['postoffset'];
        $args = array(
            'offset' => $offset,
            'posts_per_page' => 10
        );
        $wp_query = new WP_Query( $args );
    
        get_template_part( 'post-template' );
    
        exit;
    }