Thursday, September 23, 2010

Converting Texfield into autocomplete using Drupal's Form API

Inside Drupal APIs we can find separate set of APIs that deals with Forms, their elements and properties. Forms API reference guide has all the elements, properties and complete reference to the forms control structure where you can find easily a what properties all forms element carry. For more details please see Forms API Quick Start Guide.

Back to adding autocomplete feature to any textfield in Drupal, this textfield can be CCK or any core/contrib module generated textfield.
Autocomplete involves the program predicting a word or phrase that the user wants to type in without the user actually typing it in completely. This feature is effective when it is easy to predict the word being typed based on those already typed >>> (Wikipedia)
We will be creating a module which will implement hook_form_alter to alter form elements so that we can easily attach autocomplete property to form's textfield. Lets name this module "my_autocomplete", In my_autocomplete.module file add following code:
function my_autocomplete_form_alter(&$form, $form_state, $form_id) {

  if ($form_id == 'any_node_form') {

    //$form['field_cck_textfield'][0]['value']['#autocomplete_path'] = 'my/autocomplete';

    $form['#after_build'] = array('_my_autocomplete_form_afterbuild');

   

  }

}
function _dealrant_coupons_form_afterbuild($form, &$form_state) {

  $form['field_cck_textfield'][0]['value']['#autocomplete_path'] = 'my/autocomplete';

   return $form;

}
function my_autocomplete_menu() {

  $items = array();

  $items['my/autocomplete'] = array(

      'title' => '',

      'page callback' => '_my_autocomplete_terms',

      'access arguments' => array('access content'),

      'type' => MENU_CALLBACK,

    );

  return $items;

}
function _my_autocomplete_terms($string = '') {

  $matches = array();

  if ($string) {

    $result = db_query_range("SELECT name FROM {term_data} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 5);

    while ($data = db_fetch_object($result)) {

      $matches[$data->title] = check_plain($data->title);

    }

  }

  print drupal_to_js($matches);

  exit;

}
Things to remember: Use form's #after_build property in hook_form_alter only if you want to manipulate forms elements after all modules processing on that particular form is done... thats why its called after_build. This is usually used when we are going to alter some CCK textfield.

Reference: http://qandeelaslam.com/blogs/cck/converting-texfield-autocomplete-using-drupals-form-api

No comments: