Hi,
I'm looking for a method to write a form with a autocomplete field whom the autocomplete_path function have to get an argument changing with the value of a parent select field.
(i.e. the select field is a country field and the autocomplete field is a city field but only the cities of the selected country have to be loaded).

So i thought about something like that :

<?php
$form['country'] = array(
'#type' => 'select',
'#title' => t('country'),
'#options' => $country_all,
);

$form['city'] = array(
'#type' => 'textfield',
'#title' => t('city'),
'#autocomplete_path' => 'mymodule_autocomplete_city/'  .$country
);

// Here i need to put an ajax function to get the $form['country']['#value'].... and return $country
?>

Please i need help !

Thanks

Comments

timos’s picture

Hi again,
Well, I think i was on a wrong way, but the job is in progress.
I had a look on http://drupal.org/node/411074 and i used the same process to add an autocomplete fiedtext with a autocomplete list populated by the choice on a select field, for that i kept the same code but i introduce some changes (you can refer to this topic to see the original code).

Thanks to Predated to this topic who offered me a started solution !

first change, in the simple_ahah_select() function (this function define the new element we have to add to the form) :

<?php
function simple_ahah_select($form_state) {
if ($form_state['storage']['content']['simple_select_parent']) {
  $element = array(
    '#type' => 'textfield',
    '#size' => '60',
   // Define a autocomplete_path depend on the value selected on the parent select field
    '#autocomplete_path' => 'simple/autocomplete/' . $form_state['storage']['content']['simple_select_parent']
  );
  }
?>
}
  return $element;

So, we can see i define a textfield with an autocomplete_path attribute instead a select element populated from the value stored in the select field. The populated list who's going to populate the autocomplete field will be defined in the simple/autocomplete callback function.

Second step, we have to define a new menu item in our hook_menu() :

<?php
// Add this item in the simple_menu() function
$items['simple/autocomplete/%'] = array(
    'type' => MENU_CALBACK,
    'page callback' => 'simple_autocomplete_render',
    // the callback function take the wildcard define by the selected value from the parent select field as argument
    'page arguments' => array(2),
    'access callback' => TRUE,
 );
?>

Now we have to add the simple_auto_render function :

<?php
function simple_autocomplete_render($parent_value, $string = '') {
  $matches = array();
  if ($string) {
   // we just display the ten first items who match
    $result = db_query_range("SELECT name FROM {your_table} WHERE LOWER(name) LIKE LOWER('%s%%') AND id = %d", $string, $parent_value, 0, 10);
    while ($data = db_fetch_object($result)) {
      $matches[$data->title] = check_plain($data->title);
    }
  }

  drupal_json($matches);
}
?>

So, the major job is done, but staying a problem when i tested this code... the autocomplete field came on replacement of the select field... so if the user done a wrong choice he has to refresh the page to can change it... it's not a good thing !
To solve that, i became to add an 'after' method attribute in my ahah definition (in the my_simple_form function()) instead of the replace who come by default. But, if you do that, for each new choice the user do, he get a new textfield and so on....

My God ! Soluce was actually so simple and act on the method attribute was a wrong way. The wrapper attribute is the soluce !
So i just changed the form function (still refer to the topic cited above) like that :

<?php
function simple_form($form_state) { 
  $form['content'] = array(
    '#tree' => TRUE,
    '#prefix' => '<div id="simple-select-wrapper">',
    '#suffix' => '<div id="autocomplete-wrapper"></div></div>',
  );
  $form['content']['simple_select_parent'] = array(
    '#type' => 'select',
    '#default_value' => $form_state['storage']['category']['select_cat'],
    '#options' => simple_get_options(),  // Get some options for this select from the DB
    '#ahah' => array(
      'path' => 'simple/js',
      'wrapper' => 'autocomplete-wrapper',
    ),
  );
 // function continue....
}
?>

And, the job is done !

If you have any coment on that, thanks to do a feedback... i'm still a newbie, specially in ahah and ajax development in drupal.

Cheers

Tim Baret

marthinal’s picture

Thanks very much timos i was searching info about that :) Thanks for your time and write all detailed.

The only source of knowledge is experience. ~ Albert Einstein.

clashar’s picture

subscribe

drupalinside’s picture

subscribe