13

I want to have an auto-complete or auto-suggest function on a (search) form:

When a user begins to type, it suggests post titles that have matching text.

I'd also like it to display some meta-data (a number) that I have stored related to each custom post. Example:

If I type "A", it suggest "Apples (13), Aardvarks(51), Astronauts (21)", etc.

3
  • What's the name of the meta field? Please add the code that shows exactly how you added the meta field. Thanks.
    – kaiser
    Commented Jul 15, 2012 at 17:08
  • I've made the assumption the meta field is a specifically added post meta field (by meta box addition), or a custom post var, which can be accessed with get_post_meta (iirc) Commented Jul 15, 2012 at 17:15
  • I actually haven't added the meta field yet.
    – marctain
    Commented Jul 15, 2012 at 17:15

1 Answer 1

19

Yes this is possible.

You can use jQuery Auto Suggest which is included with WordPress http://codex.wordpress.org/Function_Reference/wp_enqueue_script

With this you can write a form that does a Ajax lookup to the the Ajax URL handler. Which you can add_action onto. http://codex.wordpress.org/AJAX_in_Plugins

So you can ajax lookup and then on the action side you can just perform a get_posts to match titles, or a raw sql Query. And return what is needed.

That should help, if I get time shortly I might write a full code solution. But the bulk of it is a whole plugin to help power the lookup.

Edit: Here we go, something like this should do it, haven't tested it just wrote it off the top of my head. Update: Escape the Entered text, narrow by custom post type and to published posts only

2012-11-21 Edit: updated typo in code sample.

add_action('wp_enqueue_scripts', 'se_wp_enqueue_scripts');
function se_wp_enqueue_scripts() {
    wp_enqueue_script('suggest');
}

add_action('wp_head', 'se_wp_head');
function se_wp_head() {
?>
<script type="text/javascript">
    var se_ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';

    jQuery(document).ready(function() {
        jQuery('#se_search_element_id').suggest(se_ajax_url + '?action=se_lookup');
    });
</script>
<?php
}

add_action('wp_ajax_se_lookup', 'se_lookup');
add_action('wp_ajax_nopriv_se_lookup', 'se_lookup');

function se_lookup() {
    global $wpdb;

    $search = like_escape($_REQUEST['q']);

    $query = 'SELECT ID,post_title FROM ' . $wpdb->posts . '
        WHERE post_title LIKE \'' . $search . '%\'
        AND post_type = \'post_type_name\'
        AND post_status = \'publish\'
        ORDER BY post_title ASC';
    foreach ($wpdb->get_results($query) as $row) {
        $post_title = $row->post_title;
        $id = $row->ID;

        $meta = get_post_meta($id, 'YOUR_METANAME', TRUE);

        echo $post_title . ' (' . $meta . ')' . "\n";
    }
    die();
}
10
  • Wow, thanks Barry! I'll give it a whirl, this goes into functions.php, yes? I'll modify the necessary parts and see what it gives
    – marctain
    Commented Jul 15, 2012 at 16:58
  • 2
    In theory yes, into functions.php. I'd stick it in a plugin so its out of the way. If it goes straight into functions.php then some optimization can be done, so some of this code can be applied to functions that already exist in functions.php (theme dependant of course) Commented Jul 15, 2012 at 16:59
  • It works.. almost! I should've specified that I wanted it to be from a custom-post-type, I'll edit my question
    – marctain
    Commented Jul 15, 2012 at 17:07
  • Updated to include the like_escape. I'm not using a % at the start, as he wants to search where the post titles start with the first letter entered. Not a global match. My working code is with a $_REQUEST['q'] with no options applied to jQuery suggest. Q emulates what search engines use. Commented Jul 15, 2012 at 17:07
  • @BarryCarlyon Please don't edit every minor thing. If you reach 10 edits it will automatically be transformed to a "community wiki" and you'll loose all rep points. And we need more users, that add good answers and got a min.-nr. of reputation to do tasks like editing, adding wikis, etc. Oh, and exit; is always faster than die(); :)
    – kaiser
    Commented Jul 15, 2012 at 17:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.