How to create live autofill search?

I am currently trying to create a wordpress search function that shows live results underneath the search bar. There is an example on the World Bank website (screens below). I’m not looking for an autofill like you would find on Google.com which completes words you type, rather I want it to find actual posts on the site.

I tried doing a scrub through WordPress Answers and other similar resources but have only run into implementing a Google type search which is not what I am looking for. Any help or points in the right direction would be greatly appreciated.

Read More

search-before

search after

Related posts

Leave a Reply

3 comments

  1. The following uses jQuery UI Autocomplete, which has been included in WordPress since 3.3. (I’ve borrowed the format from @Rarst :D).

    It’s still not precisely what you’re after, but gives you a good starting point. The following uses a the basic jQuery UI styling, but you can use the one that’s currently worked out on trac and call that from your plug-in folder.

    class AutoComplete {
    
        static $action = 'my_autocomplete';//Name of the action - should be unique to your plugin.
    
        static function load() {
            add_action( 'init', array( __CLASS__, 'init'));
        }
    
        static function init() {
            //Register style - you can create your own jQuery UI theme and store it in the plug-in folder
            wp_register_style('my-jquery-ui','http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css');    
            add_action( 'get_search_form', array( __CLASS__, 'get_search_form' ) );
            add_action( 'wp_print_footer_scripts', array( __CLASS__, 'print_footer_scripts' ), 11 );
            add_action( 'wp_ajax_'.self::$action, array( __CLASS__, 'autocomplete_suggestions' ) );
            add_action( 'wp_ajax_nopriv_'.self::$action, array( __CLASS__, 'autocomplete_suggestions' ) );
        }
    
        static function get_search_form( $form ) {
            wp_enqueue_script( 'jquery-ui-autocomplete' );
            wp_enqueue_style('my-jquery-ui');
            return $form;
        }
    
        static function print_footer_scripts() {
            ?>
        <script type="text/javascript">
        jQuery(document).ready(function ($){
            var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
            var ajaxaction = '<?php echo self::$action ?>';
            $("#secondary #searchform #s").autocomplete({
                delay: 0,
                minLength: 0,
                source: function(req, response){  
                    $.getJSON(ajaxurl+'?callback=?&action='+ajaxaction, req, response);  
                },
                select: function(event, ui) {
                    window.location.href=ui.item.link;
                },
            });
        });
        </script><?php
        }
    
        static function autocomplete_suggestions() {
            $posts = get_posts( array(
                's' => trim( esc_attr( strip_tags( $_REQUEST['term'] ) ) ),
            ) );
            $suggestions=array();
    
            global $post;
            foreach ($posts as $post): 
                        setup_postdata($post);
                $suggestion = array();
                $suggestion['label'] = esc_html($post->post_title);
                $suggestion['link'] = get_permalink();
    
                $suggestions[]= $suggestion;
            endforeach;
    
            $response = $_GET["callback"] . "(" . json_encode($suggestions) . ")";  
            echo $response;  
            exit;
        }
    }
    AutoComplete::load();
    
  2. Ok, this would be very basic example code that uses native suggest.js, WP core for Ajax and binds to default search form (from unmodified get_search_form() call). It’s not precisely what you asked for, but incremental search is huge pain to get perfect. 🙂

    class Incremental_Suggest {
    
        static function on_load() {
    
            add_action( 'init', array( __CLASS__, 'init' ) );
        }
    
        static function init() {
    
            add_action( 'wp_print_scripts', array( __CLASS__, 'wp_print_scripts' ) );
            add_action( 'get_search_form', array( __CLASS__, 'get_search_form' ) );
            add_action( 'wp_print_footer_scripts', array( __CLASS__, 'wp_print_footer_scripts' ), 11 );
            add_action( 'wp_ajax_incremental_suggest', array( __CLASS__, 'wp_ajax_incremental_suggest' ) );
            add_action( 'wp_ajax_nopriv_incremental_suggest', array( __CLASS__, 'wp_ajax_incremental_suggest' ) );
        }
    
        static function wp_print_scripts() {
    
            ?>
        <style type="text/css">
            .ac_results {
                padding: 0;
                margin: 0;
                list-style: none;
                position: absolute;
                z-index: 10000;
                display: none;
                border-width: 1px;
                border-style: solid;
            }
    
            .ac_results li {
                padding: 2px 5px;
                white-space: nowrap;
                text-align: left;
            }
    
            .ac_over {
                cursor: pointer;
            }
    
            .ac_match {
                text-decoration: underline;
            }
        </style>
        <?php
        }
    
        static function get_search_form( $form ) {
    
            wp_enqueue_script( 'suggest' );
    
            return $form;
        }
    
        static function wp_print_footer_scripts() {
    
            ?>
        <script type="text/javascript">
            jQuery(document).ready(function ($) {
                $('#s').suggest('<?php echo admin_url( 'admin-ajax.php' ); ?>' + '?action=incremental_suggest');
            });
        </script><?php
        }
    
        static function wp_ajax_incremental_suggest() {
    
            $posts = get_posts( array(
                's' => $_REQUEST['q'],
            ) );
    
            $titles = wp_list_pluck( $posts, 'post_title' );
            $titles = array_map( 'esc_html', $titles );
            echo implode( "n", $titles );
    
            die;
        }
    }
    
    Incremental_Suggest::on_load();
    
  3. You must do it using Ajax of course, but here there is a problem. Since WordPress uses MySQL, you might over stress your server with searching if you try to fill the search with the real Database queries trough Ajax, but what you might do is develop a system where all the posts are saved in to one big “wp_options” field and then when a search is done you query from that instead of doing a real search. But remember you need to update this chunk of text/serialized variable every time you create or edit a post.

    If you are not willing to spend some time to develop this solution, I wouldn’t recommend you doing this sort of “live search”.