Search code examples
javascriptphpajaxwordpress

Wordpress ajax function runs on front end when not called


I have a page that displays an archive of a custom post type and there is a real time search field. The page should load with a default set of results, then on keyup in the search field will filter out results based on the post title, and if the field is cleared just show all like when the page initially loads.

That's all working as expected, however when the page loads, after about 4-5 seconds it loads the results again without any interaction with the page.

Also, if a post is clicked and it's an external link it reloads the results. It won't happen if the post links to an internal page.

I also tried using the search field and then clicking on a result and it retains the search results, but again reloads them.

I am only calling the function in one place, on the input field using onkeyup="fetch()", so I have no idea why it would just be running on its own. It only does it once and I'm not sure where the 4-5 second delay is coming from either.

Here's what I have in the functions.php file:

add_action('wp_ajax_data_fetch', 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch', 'data_fetch');
function data_fetch(){

    remove_all_filters('posts_orderby');
    
    $the_query = new WP_Query( 
        array( 
            'post_type' => 'games',
            'post_title_like' => esc_attr( $_POST['keyword'] ),
            'orderby' => 'post_title',
            'post_status' => 'publish',
            'order' => 'ASC'
        )
    );

    $the_query_empty = new WP_Query( 
        array(
            'posts_per_page' => -1,
            'post_type' => 'games',
            'order' => 'ASC',
            'post_status' => 'publish',
            'orderby' => 'menu_order'
        )
    );

    // if the user has typed, filter posts
    if( $_POST['keyword'] != '' && $the_query->have_posts() ) :
        while( $the_query->have_posts() ): $the_query->the_post();

            $website = get_field('website');
            if($website){
                $url = $website;
            }else{
                $url = get_the_permalink();
            }
            ?>
            <a href="<?php echo $url; ?>" title="<?php the_title(); ?>" class="fadein"<?php if($website){echo ' target="_blank"';} ?>><?php the_post_thumbnail(); ?></a>

        <?php endwhile;
        wp_reset_postdata();
    endif;


    // if search terms have been deleted, show all
    if( $_POST['keyword'] == '' && $the_query_empty->have_posts() ) :
        while( $the_query_empty->have_posts() ): $the_query_empty->the_post();

            $website = get_field('website');
            if($website){
                $url = $website;
            }else{
                $url = get_the_permalink();
            }
            ?>
            <a href="<?php echo $url; ?>" title="<?php the_title(); ?>" class="fadein"<?php if($website){echo ' target="_blank"';} ?>><?php the_post_thumbnail(); ?></a>

        <?php endwhile;
        wp_reset_postdata();
    endif;

    die();
}

The archive file:

<input type="text" name="keyword" id="keyword" class="game-search-field" onkeyup="fetch()" value="" placeholder="Search..." />

<script>
    function fetch(){
        jQuery.ajax({
            url: '<?php echo admin_url('admin-ajax.php'); ?>',
            type: 'post',
            data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
            success: function(data) {
                jQuery('.game-list').html( data );
            }
        });
    }
</script>

After that, it's just a standard posts loop wrapped in the .game-list div. Can anybody give insight into what's going on? Not trying to self promote, but here's the url so you can see it in action: https://maximument.com/games/


Solution

  • The issue is the name of your fetch function and how your code is written. Your fetch function is being defined globally, therefore any other code that uses the native Fetch API will instead use your function, which on your site is being called multiple times by Google Tag Manager.

    There are several ways to fix this, one of them is to change the name of your function:

    <input 
        type="text" 
        name="keyword" 
        id="keyword" 
        class="game-search-field" 
        onkeyup="max_entertainment_game_fetch()" 
        value="" 
        placeholder="Search..." 
    />
    
    <script>
        function max_entertainment_game_fetch() {
            jQuery.ajax({
                url: '<?php echo admin_url('admin-ajax.php'); ?>',
                type: 'post',
                data: { 
                    action: 'data_fetch', 
                    keyword: jQuery('#keyword').val() 
                },
                success: function(data) {
                    jQuery('.game-list').html( data );
                }
            });
        }
    </script>