I'm trying to add AHAH functionality to a select list. The problem is that this select list is a CCK content type and injecting a "#ahah" array (during hook_form_alter) does not work. I don't know the reason.
1.

function test_ahah_form_alter(&$form, $form_state, $form_id) {
  // i created a test_ah node type to test this
  if($form_id == 'test_ah_node_form') {
    $form['field_select']['#ahah'] = array(
      'path' => 'test_ahah',
      'wrapper' => 'edit-field-select-value-wrapper',
      'method' => 'replace',
      'effect' => 'fade',
      'event' => 'click',
    );
  }
}
This is not working at all: the js setting #ahah callback is not even added into the header.

Another form of the code that i tried that works partially is this (more info here: http://www.lullabot.com/blog/ahah-js-in-core):
2.

function test_ahah_form_alter(&$form, $form_state, $form_id) {
    $ahah_binding = array(
      'url'   => url('test_ahah'),
      'event' => 'change',
      'wrapper' => 'edit-field-select-value-wrapper',
      'selector' => '#edit-field-select-value',
      'effect'   => 'slide',
      'method'   => 'replace',
      'progress' => array('type' => 'throbber'),
    );
   
    drupal_add_js('misc/jquery.form.js');
    drupal_add_js('misc/ahah.js');
    drupal_add_js(array('ahah' => array('edit-field-select-value-wrapper' => $ahah_binding)), 'setting');
  }
}
But this form is working only partially: in the callback of the 'test_ahah' path the form_get_cache($form_build_id, $form_state) return NULL for no obvious reason.

I managed to find a workaround:
3.

function test_ahah_form_alter(&$form, $form_state, $form_id) {
  //dpm($form_id);
  if($form_id == 'test_ah_node_form') {
    // without this here the ahah for #edit-field-select-value wont work (form_get_cache returns null from the ahah callback)
    $form['title']['#ahah'] = array(
      'path' => 'test_ahah',
      //'wrapper' => 'edit-field-select-value-wrapper',
      //'method' => 'replace',
      //'effect' => 'fade',
      'event' => 'click',
    );
   
    $ahah_binding = array(
      "button" => false,
      "keypress" => null,
      'url'   => url('test_ahah'),
      'event' => 'change',
      'wrapper' => 'edit-field-select-value-wrapper',
      'selector' => '#edit-field-select-value',
      'effect'   => 'slide',
      'method'   => 'replace',
      'progress' => array('type' => 'throbber'),
    );
   
    drupal_add_js('misc/jquery.form.js');
    drupal_add_js('misc/ahah.js');
    drupal_add_js(array('ahah' => array('edit-field-select-value-wrapper' => $ahah_binding)), 'setting');
  }
}

This is really really annoying... So if anyone knows why 1. not works (or why 3. works but 2. not) please have mercy and tell me :)

Comments

I have the same issue!!! We

I have the same issue!!! We added a CCK Select field and now we need to develop custom feature which will populate one CCK Select based on the choice of another CCK Select. (I know about Hierarchical select - it won't work in my case). We added all #ahah stuff for CCK select on form_alter but this didn't work.

This only works if we change its type to SELECT instead of OPTIONWIDGETS_SELECT but in this case saving doesn't work.

This is very frustrating. We spent the whole day fighting with this in D6... We did this easily for D5.

Same Problem

I have been looking for the exact same thing. My ideal solution would be to fix Hierarchical select. But in the mean time I am trying to do this. Main reason be a country ->province/state selection. I found out some information in case someone else is working on this.

Form alter cant be used for cck fields because the fields have not been created yet.
http://drupal.org/node/357328

If anyone gets the solution to this, please please please share.

I fought with this for a few

I fought with this for a few days. It turned out that I had to adjust the module weight so my custom module was evaluated after the CCK processing to create the form.

Install the utility module and then enable module weights and make sure your custom module weight is greater than the CCK weights.

Pete

It's a can of worms

For a number of reasons, hook_form_alter-based AHAH manipulation + CCK fields = big mess. For an informative walk through the problems, I recommend Roger Saner's thread here:
http://drupal.org/node/331941#comment-1503260

Even without the AHAH wrinkle, hook_form_alterations are tricky with CCK, per the explanation cited above and here:
http://drupal.org/node/339730

In a nutshell: CCK fields have meta types (which don't take #ahah bindings) that are only populated with standard FAPI fields after hook_form_alter gets its turn. I think the solution is a second alteration step using #pre_render, like this:

function hook_form_alter(&$form, &$form_state, $form_id) {
  ...
  $form['field_my_cck_field']['#pre_render'][] = 'my_cck_field_pre_render';
}

function my_cck_field_pre_render($element) {
  // now the real form elements are in here as children
  $element['cck-generated-fapi-element']['#ahah'] = array(
    ...
  );

  // this part may be naughty
  form_expand_ahah($element['cck-generated-fapi-element']);

  // $element doesn't pass by reference, so don't forget to return it
  return $element;
}

A second problem is that ahah bindings won't be processed for #ahah parameters added at the #pre_render stage, therefore our new #ahah parameters need to be processed manually. My possibly-naughty solution above (calling form_expland_ahah() directly) seems to work, but a FAPI expert should tell us whether that could have unintended consequences.

This still seems doesn't work

This still seems doesn't work for me... can anyone has another solution... No way to bind ahah property to a cck field.
heeeeeeeelp

=========================================================
Andrea Vivaldi
.it Registry (ccTLD.it)
Institute for Informatics and Telematics (IIT)
Italian National Research Council (CNR)
Via G. Moruzzi, 1 - 56124 Pisa, Italy

CCK optionwidget.module feature request

Hi,
I've just requested this feature here http://drupal.org/node/844808

Drupal in the Amazon Jungle

I know this definitely isn't the correct way to be doing this but in case anyone else needs it to work.

First get the dependent dropdown working out of the AHAH example module then you can populate your dropdowns with whatever you like out of the DB and the fun part is to get Drupal to save the value of the second dropdown in it's node-ref DB field simply change the #name to the name of the node-ref field had Drupal rendered that field on the form.
So sneaky.

AHAH Double Dropdown CCK node reference field on create node form.

edit: this works for regular cck fields as well

web Kreator

Use drupal_add_js

One way to do this is to directly inject the javascript into the page using drupal_add_js. This is how the #ahah binding tells ahah.js which elements to link to which path. Here is a snippet of code that shows how to do this for a radio cck field:

      // since you can't attach ahah behaviors to cck through the FAPI, manually create the js
      $selectors = array('edit-field-activity-type-value-eat', 'edit-field-activity-type-value-play', 'edit-field-activity-type-value-care');
      $ahah = array();
     
      foreach ($selectors as $selector){
        $ahah[$selector] = array(
          'button' => false,
          'effect' => 'fade',
          'event' => 'change',
          'keypress' => NULL,
          'method' => 'replace',
          'progress' => array('type' => 'throbber'),
          'selector' => '#' . $selector,
          'url' => "/switchback/load-activity-choices",
          'wrapper' => 'edit-field-log-activity-nid-nid-wrapper',
        );
      }

      drupal_add_js(array('ahah' => $ahah), 'setting');

The foreach loop is extraneous to the example but it shows a good way to add a few similar ahah settings objects without repeating yourself.

- Dan

Correction

Sorry for being redundant, somehow I didn't realize that I just duplicated the partial solution that andreiashu posted. However I did come up with a further solution that prevents needing to add the proxy ahah element.

I got this to work by setting $form['#cached'] = TRUE in the form alter. The clue was in content.node-form.inc from the CCK module, on lines 216 and 217.

Also, people trying to do this might run into another problem when using drupal_add_js in the form_alter - there are instances where the form gets loaded and hook_form_alter doesn't run, for example if the form fails validation. In these cases the form is being loaded from the cache I believe. To circumvent this, I put my drupal_add_js inside hook_init and used a url argument conditional to load it only on the right page.

The holy grail for this problem though would be a way to actually use the FAPI to add the #ahah binding to the CCK element without having to manually inject the Javascript. Any ideas?

- Dan

How about using the

How about using the #after_build property of the forms. This property is executed every time a form gets displayed to the end user.

function hook_form_alter(&$form, $form_state) {
  $form['#after_build'][] = 'myfunction_add_ahah';
}

function myfunction_add_ahah($form, $form_state) {

   $selectors = array('edit-field-activity-type-value-eat', 'edit-field-activity-type-value-play', 'edit-field-activity-type-value-care');
   $ahah = array();
    
   foreach ($selectors as $selector){
     $ahah[$selector] = array(
       'button' => false,
       'effect' => 'fade',
       'event' => 'change',
       'keypress' => NULL,
       'method' => 'replace',
       'progress' => array('type' => 'throbber'),
       'selector' => '#' . $selector,
       'url' => "/switchback/load-activity-choices",
       'wrapper' => 'edit-field-log-activity-nid-nid-wrapper',
     );
   }

   drupal_add_js(array('ahah' => $ahah), 'setting'); 


   return $form;
}

Thanks for the snippet code :). Hope this helps.

nobody click here