I am trying to implement '#autocomplete_path' on a text field in my module.

$form['foo'] = array(
'#type' => 'textfield',
'#title' => t('First Name'),
'#size' => 12,
'#autocomplete_path' => 'hello/auto',
);

I then have a modified function from user/autocomplete in the user module.

function hello_world_autocomplete($string) {
$matches = array();

if ($string) {
$result = db_query_range("SELECT firstname FROM {usernames} WHERE LOWER(firstname) LIKE LOWER('%s%%')", $string, 0, 10);
while ($user = db_fetch_object($result)) {
$matches[$user->firstname] = check_plain($user->firstname);
}
}
print drupal_to_js($matches);
exit();
}

When I type a name from the database in the text field, nothing happens. Nothing at all. If I go to the page "hello/auto/justin" it returns "{ "Justin": "Justin" }"

Any thoughts on why nothing happens at all?

Comments

kingandy’s picture

A couple of months late, I know, but I'm working with autocompletes at the moment and it seems to me you may have missed a vital step in the progression autocomplete_path fires a menu callback, which then directs Drupal to your custom function - without defining the callback, nothing will happen.

Try adding something like the following to your module:

 function hello_world_menu() {
$items = array();
  $items[] = array('path' => 'hello/auto',
                                'title' => t('Hello World autocomplete callback'),
                                'callback' => 'hello_world_autocomplete',
                                'type' => MENU_CALLBACK);						  
  return $items;
}

The 'path' of the menu item matches the #autocomplete_path of your form item, and the 'callback' points to your function. The 'type' => MENU_CALLBACK tells drupal not to display the menu item in any actual menus - it's just a path/function mapping.

Hope that works - because that's the principle I'm currently developing under and if it doesn't I'll be very disappointed :)

++Andy

kingandy’s picture

I am very disappointed, it's not working for me either.

Also, from my own investigations, I realise that if visiting the callback URL directly worked for you, you must have had the menu callback set up already.

So basically I've been no help at all. :(

++Andy

roedelius’s picture

Actually, you've been a big help :)

here's the function that worked for me, needed $may_cache and 'access' => array('access_content'), otherwise I was just getting a 403 error.


function MODULE_NAME_menu($may_cache) {

	$items = array();

	if ($may_cache) {
		$items[] = array (
			'path' => 'yourpath', // e.g. 'whatever/autocomplete'
			'title' => t('Autocomplete'),
			'access' => array('access content'),
			'callback' => 'MODULE_NAME_autocomplete',
			'type' => MENU_CALLBACK,
		);                         
	}

	return $items;

}

kingandy’s picture

Alright, I got this sorted out in my site.

Apparently the inline file upload javascript file (misc/upload.js) interferes with other JS functionality on the site - specifically collapsible fieldsets and autocomplete fields. Removing or renaming the upload.js file removes this conflict.

I don't know if this is the same problem as you had (my upload.js is v 1.11, if that means anything) but I figure it's worth reporting just in case.

++Andy

robl@wearevi.com’s picture

How close am I to get this working?!

[code]


/*
Query database for the string

*/
function advance_autocomplete_company_render_page() {
    $output = drupal_get_form('advance_autocomplete_company_form');
    return $output;
}

/**
* Retrieve a pipe delimited string of autocomplete suggestions for existing users
*/
function user_autocomplete2($string) {
  $matches = array();
  $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10);
  while ($user = db_fetch_object($result)) {
    $matches[$user->name] = check_plain($user->name);
  }
  print drupal_to_js($matches);
  return;
}




/**
 * Implementation of hook_menu()
 */

function advance_autocomplete_company_menu($may_cache) {

    $items = array();

    if ($may_cache) {
        $items[] = array (
            'path' => 'hello/auto', // e.g. 'whatever/autocomplete'
            'title' => t('Autocomplete'),
            'access' => array('access content'),
            'callback' => 'user_autocomplete2',
            'type' => MENU_CALLBACK,
        );                        
    }

    return $items;

}








function advance_autocomplete_company_form() {
  $form = array();


  // ...code...
  $form['profile_companyajax'] = array(
  
    '#type' => 'textfield',
    '#default_value' => $typed_string,
    '#maxlength' => 100,
    '#autocomplete_path' => 'hello/auto',
    '#title' => $vocabulary->name,
    '#description' => t('A comma-separated list of terms describing this content (Example: funny, bungie jumping, "Company, Inc.").')  

  );
  // ...code...
  
	return $form;
}

[/code]

robl@wearevi.com’s picture

any suggestions guys... am I defining the callback menu correctly? Am I to link the #autocomplete_path to the path of my menu? How can I see if drupal is calling the javascript well on this?

robl@wearevi.com’s picture

how come its not working guys?

hammyliem’s picture

Hi guys,

I tried to make an autocomplete_textfield, searching for name in users table inside the overlay. I have made the autocomplete work smoothly for the page itself (which is under inbox/new_message). However, when I grabbed that form and put it inside the overlay, it does not work for some reason. Here is my code:

url: inbox/new_message will contain =>

$form['new_message'] = array(
'#type' => 'fieldset',
'#title' => 'New Message',
'#id' => 'new_message_fieldset',
'#prefix' => '

',
'#suffix' => '

',
);
$form['new_message']['to'] = array (
'#type' => 'textfield',
'#title' => 'To',
'#id' => 'new-message-to',
'#autocomplete_path' => 'inbox/new_message/user-name-autocomplete',
);
$form['new_message']['subject'] = array (
'#type' => 'textfield',
'#title' => 'Subject',
'#id' => 'new-message-subject',
);
$form['new_message']['message'] = array (
'#type' => 'textarea',
'#title' => 'Message',
'#id' => 'new-message-message',
'#resizable' => false,
);
and then, {url: inbox}, there is an html code that says->

print $base_url."/inbox/new_message";" class="uiButton uiButtonNewMessage" rel="#overlay" >
+ New Message

and then, i am using jquery.tools.min.js, and I add an js file that contain this following code: (this partial code will show overlay)

$(function() {
$("a[rel]").overlay({

mask: 'darkred',
effect: 'apple',

onBeforeLoad: function() {

// grab wrapper element inside content
var wrap = this.getOverlay().find(".contentWrap");

// grap contents from external page
var content = this.getTrigger().attr("href");
//var content = content.find("#haloworld").html();
//alert(content);
// load the page specified in the trigger
wrap.load(this.getTrigger().attr("href")+" #new_message");
}

});
});

so, when + new message is clicked, wrap.load(this.getTrigger().attr("href")+" #new_message"); will take id #new_message from inbox/new_message and then show it inside overlay. Once again, my question is that once it shows on the overlay, why #autocomplete_path on "to" title do not work? any idea on how to make it work guys?? thank you.

Best regards,

hammyliem