I created 2 dependent dropdowns in Drupal 7. In the first dropdown you need to choose the device, in order to see its attributes in the second dropdown.

When an option from the first list is selected, the Ajax throbber appears but it doesn't seem to be working and I don't get the appropriate options in the second dropdown.

I have read all examples and resources I could find online, but I haven't found how to fix this. Any help would be very much appreciated.

Below I attach the relevant code. Apologies in advance, I am new in Drupal.

function my_module_getdevicesfromrooms() {
  $dropdown1 = array();

  $tabdelimited = file_get_contents("http://.../tabdelimited");

  // some code
  return $dropdown1;

 * The device name is required in order to get the attributes using this function
function my_module_getattributesfromdevices($test) {
  $dropdown2 = array();
  $tabdelimited = file_get_contents("http://....");
  // some code

  return $dropdown2;

function my_module_form_ajax($form, &$form_state) {
  $form['#prefix'] = "<div id='latest-div'>";
  $form['#suffix'] = "</div>";   
  $options_first = my_module_getdevicesfromrooms();
  $value_dropdown_first = isset($form_state['values']['my_module_deviceurn']) ? $form_state['values']['my_module_deviceurn'] : $options_first;

  $state2 = my_module_getattributedfromdevices($value_dropdown_first); 

  $form['my_module_deviceurn'] = array(
    '#type' => 'select', 
    '#title' => 'Device', 
    '#options' => $options_first, 
    '#default_value' => $value_dropdown_first,

  $form['my_module_apply'] = array(
    '#type' => 'button',
    '#title' => t('Apply'),
    '#default_value' => t('apply'),
    '#ajax' => array(
      'callback' => 'my_module_ajax_callback',
      'wrapper' => 'nodes-div',
      'method' => 'replace',
      'effect' => 'fade',

  $form['my_module_attributes'] = array(
    '#type' => 'select',
    '#title' => t('Attributes'),
    '#options' => $state2,
    '#default_value' => variable_get('my_module_attributes', ''),
  return $form;

function my_module_ajax_callback($form, $form_state) {
  return $form;

On your callback function, you need to setup a callback help. Basically getting your form data. Now my code is for D6 so some functions might be slightly different but check this out. I left some of my tweaks in there. You'll just have to adjust accordingly. but the big thing is the callback helper function.

function MOD_js_callback() {

// use of ajax callback helper to set form variables again
$form = MOD_callback_helper();

// grab form['datacenter_devices'] data and drop into changed_elements
// simply to not confuse rebuilt form with 'global' form
$changed_elements = $form['datacenter_devices'];

// Prevent duplicate wrappers.
unset($changed_elements['#prefix'], $changed_elements['#suffix']);

// concat status_messages and call drupal_render to render elements array for output.
$output = theme('status_messages') . drupal_render($changed_elements);
    'status'   => TRUE,
    'data'     => $output,
function MOD_callback_helper() {

$form_state = array('storage' => NULL,'submitted' => FALSE);

$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form_state['post'] = $form['#post'] = $_POST;
// Enable the submit/validate handlers to determine whether AHAH-submittted.
$form_state['ahah_submission'] = TRUE;
$form['#programmed'] = $form['#redirect'] = FALSE;
drupal_process_form($form_id, $form, $form_state);

$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);

return $form;

A simpler way to achieve this is you could use Hierarchical select, https://drupal.org/project/hierarchical_select This will trigger the options in the dependency list whenever the source list is selected.


Try this code. This is not adapted to your code, but to your question. I have a working example which does exactly what you ask for. I don't find the throbber code in your example. Here we have 2 fields. Brand selection changes the property of ajax autocomplete of model field. The change is done in function mymodule_models_update

 $form['brand'] = array(
   '#type' => 'select',
   '#title' => t('Brand'),
   '#options' => $brands,
   '#default_value' => $brand,

'#ajax' => array(
    'callback' => 'mymodule_models_update',
    'wrapper' => 'models_wrapper',
    'progress' => array(
        'message' => '',
        'type' => 'throbber',


$form['model'] = array(
    '#type' => 'textfield',
    '#title' => t('Model'),
    '#description' => 'Please note available models change based on the brand.',
   '#required' => FALSE,

   '#autocomplete_path' => 'providers/autocomplete/' . $brand,
   '#attributes' => array("placeholder" => t('Model')),
   '#prefix' => '<div id="models_wrapper">',
   '#suffix' => '</div>',


 function mymodule_models_update($form, &$form_state) {
  unset($form_state['input']['model'], $form_state['values']['model']);
  $brand = $form_state['values']['brand'];
  $form['model']['#autocomplete_path'] = 'providers/autocomplete/' . $brand;
  return form_builder($form['#id'], $form['model'], $form_state);
} // function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.