Changing Drupal's autocomplete path with JavaScript

Posted on July 18, 2012

Ever had an interface that needed an autocomplete field? Happens all the time - and Drupal makes that task trivial. But what if you need to change the autocomplete URL without reloading the page? Use these steps, and you'll find out how to do so with JavaScript.

For the purposes of this tutorial, we'll assume you don't care too much about the initial URL. So let's make it obvious that it's a placeholder. Let's start by declaring our menu entries.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php      
function our_autocompleted_field_menu() {                                     
  $items = array();                                                           
  $items['our_autocompleted_field_form'] = array(                             
    'type' => MENU_CALLBACK,                                                  
    'access callback' => TRUE,                                                
    'page callback' => 'drupal_get_form',                                     
    'page arguments' => array('our_autocompleted_field_form'),                
  );                                                                          
  $items['our_autocompleted_field/autocomplete/%'] = array(                   
    'type' => MENU_CALLBACK,                                                  
    'access callback' => TRUE,                                                
    'page callback' => 'our_autocompleted_field_autocomplete',                
    'page arguments' => array(2),                                             
  );                                                                          
  return $items;                                                              
}

Now let's declare the form with our field. Like any other autocomplete field, we declare it by using the #autocomplete property on our form definition.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php                                                                               
function our_autocompleted_field_form() {                                     
  $form = array();                                                            
  $form['our_autocompleted_field_toggle'] = array(                                   
    // This is just a sample link to demonstrate the dynamic autocomplete URL.
    '#type' => 'markup',                                                      
    '#value' => '<a id="our-autocompleted-field-toggle" href="#">Toggle</a>', 
  );                                                                          
  $form['our_autocompleted_field'] = array(                                   
    '#type' => 'textfield',                                                   
    '#id' => 'our-autocompleted-field',                                       
    // Drupal needs a valid autocomplete path, otherwise it will not add the  
    // behavior. So we add the placeholder argument and replace that on the   
    // JS frontend.                                                           
    '#autocomplete_path' => 'our_autocompleted_field/autocomplete/PLACEHOLDER',
  );                                                                          
  return $form;                                                               
}

Now, let's define our autocomplete function. To demonstrate the dynamic capabilities, let's use the first argument - which comes along with the path - as a way to tell us whether to return results in lowercase or uppercase. Of course, you can use the dynamically-changed URL to vary your results however you want.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php      
function our_autocompleted_field_autocomplete($letter_case, $input) {         
  if ($letter_case == 'uppercase') {                                          
    $function = 'strtoupper';                                                 
  }                                                                           
  else {                                                                      
    $function = 'strtolower';                                                 
  }

  $matches = array(                                                           
    'Suggestion 1',                                                           
    'Suggestion 2',                                                           
  );                                                                          
  $matches = array_map($function, $matches);

  print json_encode($matches);                                                
  exit();                                                                     
}

Finally, we use a little bit of magic on the frontend to change the autocomplete path. The trick is to reload the autocomplete object that Drupal generates, otherwise, the change won't take effect. You also need to get rid of the old behavior - that way you avoid confusing duplicate calls. Find or create your module's JavaScript file. Then add the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$(document).ready(function() {                                                
  // ID format is {OUR-FIELD-ID}-autocomplete.                                  
  var autocompletePath = $('#our-autocompleted-field-autocomplete')           
                         .val().replace('/PLACEHOLDER', '');

  // Keep track of the case we're in.                                         
  var isUpperCase = false;

  $('#our-autocompleted-field-toggle').click(function() {                     
    if (isUpperCase) {                                                        
      var newURL = autocompletePath + '/lowercase';                           
      isUpperCase = false;                                                    
    }                                                                         
    else {                                                                    
      var newURL = autocompletePath + '/uppercase';                           
      isUpperCase = true;                                                     
    }                                                                         
    // Trick Drupal into rebinding the autocomplete behavior.                 
    $('#our-autocompleted-field-autocomplete').val(newURL)                    
    .removeClass('autocomplete-processed');

    $('#our-autocompleted-field').unbind().val('');                           
    Drupal.behaviors.autocomplete(document);

    return false;                                                             
  });

  // Simulate a click when initializing so that we have a valid autocomplete  
  // path.                                                                    
  $('#our-autocompleted-field-toggle').click();                               
});

And that's it. This code will toggle your autocomplete results between uppercase and lowercase. It's a contrived example, of course. But think of the possibilities!

Learning Drupal? Subscribe to my Drupal articles, tips and tutorials.

Comments

Erich SchulzMarch 11, 2013, 2:08 p.m.

Thanks for this. Are your two form elements supposed to have the same index?

Reply
silviogutierrezDec. 10, 2013, 5:45 p.m.

Fixed this. Thanks.

Reply
Omar FloresDec. 8, 2015, 4:06 p.m.

thanks very much for this, I'm running D7 and this excellent explanation you posted still works.

Reply
hillaryFeb. 22, 2019, 10:38 a.m.

Incredible post. Articles that have significant and savvy remarks are more agreeable, at any rate to me. It’s fascinating to peruse what other i need a dissertation individuals thought and how it identifies with them or their customers, as their point of view could help you later on.

Reply
RoweApril 14, 2019, 9:01 p.m.

There is nothing that I can do anything for assignment writers in uk. I guess that we will not be working on it as they are suggesting and we will be asked to do more things here for sure.

Reply
dsdsdMay 6, 2019, 5:53 a.m.

Bien qu’il n’y ait pas de schéma aléatoire aléatoire, cela peut vous aider à résoudre subtilement et à éviter les facteurs défavorables face aux situations d’urgence, et à saisir les facteurs favorables, afin que le personnel de vente des iwc montres ne puisse pas affecter l’activité en raison d’événements imprévus. Il peut même compter sur des situations imprévues pour inverser les inconvénients et faciliter les transactions. Pour exercer efficacement leur propre résilience, le personnel de vente ne peut pas agir conformément aux règles du processus de vente, jaeger lecoultre montres mais doit apprendre à découvrir de nouvelles situations, de nouveaux problèmes et à résumer les nouvelles expériences tirées du processus de vente.

Reply
CherisseMay 15, 2019, 9:22 p.m.

Well, I don’t have much to say about www.imfaceplate.com/gluecksspielmaster/rubbellose-sind-wieder-populr. But it was a good article and I liked reading it. Would like to see more from them.

Reply
fggfggfMay 18, 2019, 2:28 p.m.

Dans le processus de vente, il n’est pas difficile pour le vendeur d’obtenir la confiance du client: il suffit de laisser le client penser que vous le servez sincèrement et que votre produit ou votre service est vraiment ce dont il a besoin. Il suffit de lui laisser une attente sincère pour vous. Tant que vous pouvez atteindre un consensus avec le client est suffisant. replique montre de luxe Les clients ont les yeux vifs et leurs sentiments sont aussi très vifs. Vos mots, un regard, un geste, ils sont tous dans le cœur. Un bon vendeur. Il faut toujours faire passer les intérêts des clients en premier. Avec ce genre d’attitude au travail, je pense que même les clients les plus difficiles seront conquis.

Reply

Post New Comment