AJAX calls in CTools Content Type Plugin? I'm building a CTools Panels Content Type (i.e., that thing you insert into panels when adding content, not a type of node) and I am trying to use a form item's #ajax attribute to set some default values. See code below. 

This is all inside of the content type's my_module_content_type_edit_form($form, &amp;$form_state) call, by the way.

  $form['link_type'] = array(
    '#type' =&gt; 'radios',
    '#title' =&gt; t('Link Type'),
    '#ajax' =&gt; array(
      'callback' =&gt; 'my_module_set_target'
    ),
    '#default_value' =&gt; empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' =&gt; array('none'=&gt;t('No Link'), 'internal'=&gt;t('Internal Link'), 'external'=&gt;t('External Link'), 'document'=&gt;t('Document Link')),
  );


My callback is the following.

function my_module_set_target($form, $form_state) {
  watchdog("Test", "Testing callback", array(), WATCHDOG_ALERT);
  $form['link_target']['#default_value'] = '_parent';

  return $form['link_target']['#default_value'];
}


Regardless of whether the return I'm suggesting would actually work, watchdog() doesn't even work.

I know CTools does some weird stuff with AJAX, but it can't be that weird. Do you have any idea on how I'd do what I'm wanting to do?

Thanks!

Alternatively: How do I set a default value based on the value of a previous form option? 

I figured out how to do this, but it's a bit hacky -- you create new form fields for each dependency fork. You can then merge the values together in hook_content_type_edit_form_submit(), using whichever one corresponds to the value chosen for the component that initially forked everything.

I'm leaving the question open because I (and, frankly, every programmer I'm working with) is really wanting a good way to use AJAX inside these Panel content type edit forms.

Update: It appears you can't do stuff with #attached, either.

$form['link'][$i] = array(
  '#type' =&gt; 'fieldset',
  '#title' =&gt; t('Link #@num', array('@num' =&gt; $i)),
  '#collapsible' =&gt; TRUE,
  '#collapsed' =&gt; TRUE,
  '#attached' =&gt; array(
    'js' =&gt; array(
      'alert("Yay.");', 'inline'
    ),
  )
);
Short answer: you should use #ajax['path'].

Long answer:

Having a ajax callback does not help as ctools creates it's forms differently afaik. The callback done by system/ajax cannot find the complete form definition thus cannot find an element to process the ajax request for. Using #ajax[path] just triggers a menu item.

You can check for yourself by dumping the form when using #ajax[callback]

function ajax_form_callback() {
  list($form, $form_state) = ajax_get_form();
  drupal_process_form($form['#form_id'], $form, $form_state);


I've modified the simplecontext_content_type_edit_form by adding the user autocomplete widget and your field which both work :)

function simplecontext_content_type_edit_form($form, &amp;$form_state) {
  $conf = $form_state['conf'];

  $form['owner_name'] = array(
    '#type' =&gt; 'textfield',
    '#title' =&gt; t('Username'),
    '#default_value' =&gt; 'admin',
    '#autocomplete_path' =&gt; 'user/autocomplete',
    '#size' =&gt; '6',
    '#maxlength' =&gt; '60',
    '#description' =&gt; '$description',
  );

  $form['link_type'] = array(
    '#type' =&gt; 'radios',
    '#title' =&gt; t('Link Type'),
    '#ajax' =&gt; array(
      'path' =&gt; 'my_module_set_target'
    ),
    '#default_value' =&gt; empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' =&gt; array('none' =&gt; t('No Link'), 'internal' =&gt; t('Internal Link'), 'external' =&gt; t('External Link'), 'document' =&gt; t('Document Link')),
  );
...


As you now use #ajax path you need to add a menu item as I did like

&lt;?php

function my_module_menu() {
  $items = array(
    'my_module_set_target' =&gt; array(
      'title' =&gt; 'AJAX Example',
      'page callback' =&gt; 'my_module_set_target',
      'access callback' =&gt; TRUE,
      'expanded' =&gt; TRUE,
    )
  );
  return $items;
}

function my_module_set_target() {
  drupal_json_output( array('data' =&gt; "ABC"));
}


A nittpick about #attached[js]: the inline js should be key => value like:

'#attached' =&gt; array(
  'js' =&gt; array(
    'alert("Yay.");' =&gt; 'inline',
  ),
),


I've used Firebug to check for the resulting value not the resulted effect. So I hope this helps to fix your problem.