6

I got a set of meta boxes on a custom post type. Two of them are simple input/text-type fields, that should have autocompleted input:

  • A) Another Custom Post Type
  • B) Users

Now I have the problem that I need to somehow trigger the autocomplete event. So far I have this pretty simple definition:

jQuery( document ).ready( function ($)
        {
            $( '#some_id' ).autocomplete(
            {
                 minLength: 2
                ,source:    "<?php print 'SOME_STRING'; ?>"
            } );
        } );

which gives me the following answer in the console, when I enter "zz":

GET http:// localhost/wordpress/wp-admin/SOME_STRING?term=zz 404 (Not Found)

Point is that I need to run a query (as you can see above) and need to root the request for the source option/argument from autocomplete somehow to a php callback.

I hope someone can explain me how I'd get around this. Thanks (and merry christmas in case you read this :) !

2
  • Shouldn't OXO be a URL? This might be relevant. code.google.com/p/jquery-autocomplete/wiki/Options Merry Christmas to you too :) Dec 23, 2011 at 20:28
  • @BrianFegter Thanks and yes, it is an URL. As you can see above, it gets appended to the admin URL with term as query key and the field input as query arg. So I don't have a clue how to route this to my php ajax callback function (and exactly this is my Q). :) Oh, and I use the native jQuery UI autocomplete Widget/Plugin.
    – kaiser
    Dec 25, 2011 at 9:01

2 Answers 2

9

Use jQuerys getJSON in the autocompletes source method and use WordPress' admin-ajax.php to handle the request, to avoid having to find wp-load.php (which may have been moved) and would load WordPress on every request.

First of all: get the ajax url of your WordPress blog:

This is simple:

admin_url( 'admin-ajax.php' )

But, we want this accessible in your javascript file, so use wp_localize_script

wp_enqueue_script( 'myajax_jsfile_handle', get_stylesheet_directory."/rest/of/path/to/file.js", array( 'jquery', 'jquery-form', 'json2' ), false, true ); );
wp_localize_script( 
    'myajax_jsfile_handle', 
    'MyAjax_object', 
    array( 
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
        'myajax_nonce' => wp_create_nonce( 'myajax_nonce_val' ),
        'action' => 'myajax-submit'
    )
);

Where myajax_jsfile_handle is the handle of your registered javascript file. Call the above when you queue your javascript file.

The autocomplete source method

For your source in the JQuery UI autocomplete option...

source: function( request, response ) {  
    jQuery.getJSON( MyAjax_object.ajaxurl + "?callback=?&action=myajax-submit", request, function( data ) {  
        response( jQuery.map( data, function( item ) {
            jQuery.each( item, function( i, val ) {
                val.label = val.whatever; // build result for autocomplete from suggestion array data
            } );
            return item;
        } ) );
  } );  
},
  • request is whatever is typed.
  • The action is what Wordpress interprets (see below). These are added the url that autcomplete uses to return the suggestions.

What the above does is takes each item (the returned JSONrd rows) and gives them a label, which the autocomplete uses to display the suggestions. (In the example above the label is the content of the column 'column')

Tell WordPress how to do deal with the request

So the above sends to WordPress an ajax request with action 'myajax-submit'.

When WordPress recieves this it triggers the actions wp_ajax_myajax-submit (if the user is logged in) or wp_ajax_nopriv_myajax-submit if they are not. You can hook your function onto one or both of these hooks, depending on whom you intend to allow this AJAX request for. Our function will perform any necessary querys and JSON the result (the suggestions) and echo them.        

        // Callback
        function get_my_suggestions() {
            // This function should query the database and get results as an array of rows:
            // GET the recieved data: 'term' (what has been typed by the user)
            $term = $_GET['term']
            $suggestions_array = array();

            // echo JSON to page  and exit.
            $response = $_GET["callback"]."(". json_encode($suggestions_array) .")";  
            echo $response;  
            exit;
        }
    add_action( 'wp_ajax_myajax-submit', 'get_my_suggestions' );
//For non-logged in users add_action( 'wp_ajax_nopriv_myajax-submit', 'get_my_suggestions' );

Disclaimer: The example returns an empty array in any case.

2
  • For some reason it didn't work in one of my vanilla test setups - I consider it an edge case. The rest works like a charm. The source function was what I was searching for. Thanks mate! You made my day :)
    – kaiser
    Dec 28, 2011 at 9:27
  • Btw: I hope you don't mind the edit. Just wanted to make sure, the reference is complete.
    – kaiser
    Dec 28, 2011 at 9:37
1

In your autocomplete source file (you can put a autocomplete.php file in your theme) put include_once($_SERVER['DOCUMENT_ROOT'].'/wp-load.php' ); at the top of your script. Then you can use the $wpdb to query what you want.

It doesn't use WordPress AJAX API, but it works. Hope this helps.

4
  • 1
    Loading Wordpress on every key stroke isn't what I want to do. It works, but would add a significant overhead if there're a lot of requests. Anyway, thanks for your answer. :)
    – kaiser
    Dec 28, 2011 at 9:26
  • I have to correct myself. As admin-ajax.php includes wp-load.php on top, there is no difference between your solution and core. Late, but anyway. +1.
    – kaiser
    Feb 4, 2012 at 3:17
  • So does this also mean only including wp-load.php is a bit leaner? Or maybe unsafer? Anyway, next time I will do it the right way :-) Feb 4, 2012 at 13:48
  • No, there's really no difference. Just take a look at the top of the core file. And no, it's not unsafe that way.
    – kaiser
    Feb 4, 2012 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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