Took me the better part of the morning to figure this one out:

This code will not work:

function my_module_form(&$form_state) {
  ctools_include('dependent');
  
  $form = array();
    
  $form['payment_method'] = array(
    '#type' => 'select',
    '#title' => t('Type'),
    '#options' => array('Cash', 'Credit'),
    '#default_value' => NULL,
  );
  
  $form['cash_payment'] = array(
    '#type' => 'select',
    '#title' => t('Currency'),
    '#options' => array('UK Pounds', 'Dollars', 'Euro'),
    '#process' => array('ctools_dependent_process'),
    '#dependency' => array('edit-payment-method' => array('Cash')),
  );

  $form['credit_payment'] = array(
    '#type' => 'select',
    '#title' => t('Type of creditcard'),
    '#options' => array('Visa', 'Mastercard', 'American express'),
    '#process' => array('ctools_dependent_process'),
    '#dependency' => array('edit-type' => array('Credit')),
  );
}

The problem is that the #options array of $form['payment_method'] has to be a keyed array.

So: this will work:

function my_module_form(&$form_state) {
  ctools_include('dependent');
  
  $form = array();
    
  $form['payment_method'] = array(
    '#type' => 'select',
    '#title' => t('Type'),
    '#options' => array('cash' => 'Cash', 'credit' => 'Credit'),
    '#default_value' => NULL,
  );
  
  $form['cash_payment'] = array(
    '#type' => 'select',
    '#title' => t('Currency'),
    '#options' => array('UK Pounds', 'Dollars', 'Euro'),
    '#process' => array('ctools_dependent_process'),
    '#dependency' => array('edit-payment-method' => array('cash')),
  );

  $form['credit_payment'] = array(
    '#type' => 'select',
    '#title' => t('Type of creditcard'),
    '#options' => array('Visa', 'Mastercard', 'American express'),
    '#process' => array('ctools_dependent_process'),
    '#dependency' => array('edit-type' => array('credit')),
  );
}

The problem is that #options accepts keyed and non-keyed arrays and parses them fine. If your array is non-keyed, then the Form API will approach it as a numerical keyed array: array(0 => 'Cash', 1 => 'Credit'); So, apart from explicitly providing an associative array to the form item, we could change the #dependency property to this: '#dependency' => array('edit-type' => array(0)), with 0 being the numerical key.

I didn't find this particularity back in the documentation. I erroneously assumed that I had made a mistake with the ID targetting the wrong element and that JS wasn't working as it should.

Comments

merlinofchaos’s picture

'#options' => array('Cash', 'Credit'),

Technically this is a keyed array. If you don't provide keys, PHP gives them to you like this:

'#options' => array(0 => 'Cash', 1 => 'Credit'),

Then you define your dependency like this:

'#dependency' => array('edit-payment-method' => array(0)),

Since this is an intrinsic part of PHP, it never occurred to me to document it explicitly. I'm not entirely sure I should.

lslinnet’s picture

I had the same issue when I first started using Dependent, some better documentation on this wouldn't hurt.

merlinofchaos’s picture

I always feel uncomfortable documenting basic language constructs that people should know, though.

netsensei’s picture

True.

Then again, it's not a formal API documentation where one would describe a function signature and what happens when you pass an associative or numerical array (much like your standard PHP doc for any given function). The Dependent docs describe how the arrays are build, not how they get parsed.

The same goes for much of the Drupal documentation though i.e. #options:

http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/6#options

japerry’s picture

Status: Active » Closed (outdated)

Closing this issue as outdated as Drupal 6 ctools is not supported. If this issue is relevant for Drupal 7, feel free to re-open and mark for Drupal 7 (or 8)