How to add Autocomplete to a Views Custom Textfield Filter I have created my own custom views filter handler which works perfectly with a simple textfield for the value form. However, I am unable to add autocomplete to that textfield (ie: the blue circle denoting autocomplete doesn't show up in the textfield and in the page source, autocomplete is not mentioned for that element).

What am I missing? Does Views re-write my value form somewhere as implied in Making text fields autocomplete in views exposed filters and if so, how do I plug into the after build within a custom filter handler class? (The question linked to involved altering an existing exposed form as opposed to creating a custom filter which I am.)

NOTE: I am using Drupal 7 and Views 3.

My Code

Here is my custom filter class:


/**
 * The Germplasm Genotyped views filter handler class (autocomplete textfield).
 */
class views_handler_filter_germplasm_genotyped_name extends views_handler_filter_string {

  /**
   * So that the value form is not inherited.
   */
  function value_form (&$form, &$form_state) {

        $form['value'] = array(
            '#type' => 'textfield',
            '#default_value' => $this->value,
            '#autocomplete' => 'tripal_ajax/nd_genotypes/genotyped_germplasm/name_to_id/Phaseolus/only'
        );

  }
}


I've defined my autocomplete in hook_menu():


  // Name autocomplete (display only the preferred organism -in path).
  $items['tripal_ajax/nd_genotypes/genotyped_germplasm/name_to_id/%/only'] = array(
    'page callback' => 'nd_genotypes_germplasm_name_to_id_callback',
    'page arguments' => array(4, FALSE),
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK
  );


And created my callback:


function nd_genotypes_germplasm_name_to_id_callback($organism_genus, $all_organisms, $string) {
  $matches = array();

  // custom table select
  $query = db_select('nd_genotype_germplasm', 'g')
    ->fields('g', array('name', 'genus'))
    ->condition('g.name', '%' . db_like($string) . '%', 'LIKE')
    ->condition('g.genus', $organism_genus, '=')
    ->orderBy('char_length(g.name)','ASC')
    ->orderBy('g.genus','ASC');
  $result = $query->execute();
  foreach ($result as $row) {
      $key = $row->name;
      if (!$all_organisms) {
        $matches[$key] = $row->name;
      }
      else {
        $matches[$key] = format_string(
          '@genus: @name',
          array(
            '@genus' => check_plain($row->genus),
            '@name' => check_plain($row->name),
          )
        );
      }
  }
  drupal_json_output($matches);
}


Testing I've done

I have tested the autocomplete callback directly by entering the path in my browser (ie: tripal_ajax/nd_genotypes/genotyped_germplasm/name_to_id/Cicer/only/CDC where "CDC" is the $string) and it works perfectly. By that I means it returns a json array outside my drupal theme with the elements I expect:


{
"CDC Xena 454 DNA Extraction": "CDC Xena 454 DNA Extraction",
"CDC Frontier 454 DNA Extraction": "CDC Frontier 454 DNA Extraction"
}


But as I said, my exposed fitler textfield in my view doesn't have autocomplete functionality. I know my value form is being executed because I can dpm() from within the handler and see it in my view, #autocomplete and all. However, when I look at the page source I see a plain textfield input with no autocomplete mentioned.

Note: Working autocomplete fields seem to have the class "form-autocomplete" on the input tag and an addition hidden input with the callback path and class "autocomplete autocomplete-processed".
So it turns out that I just had a small typo :( Anyway, I'm keeping this question up in case others are having troubles since it outlines completely how to do this and I was personally unable to find any tutorials. 

In the above code it needs to be #autocomplete_path instead of #autocomplete.

Furthermore, if you are trying to create your own custom autocomplete filter, remember that you have to indicate the file containing your handler class in your .info file (ie: files[] = views/handlers/name_of_my_handler.inc) and that you need to assign your handler to a field using hook_views_data() or hook_views_data_alter().