FAPI form_alter missing fields

There are many occasions in which you would like to alter a form behavior, and it's normally very easy to do -- just implement hook_form_alter and you're done. There are cases though, where fields will be missing, and in those cases, you need a workaround.

It's not a big thing, really; you only need to register a function callback on hook_form_alter, instructing FAPI to call it after the form's been completely built.



This is done like so:

function mymodule_form_alter($form, &$form_state, $form_id) {
  // [... logic to see if we're interested here ... ]
  $form['#after_build'][] = 'my_handling_function';

function my_handling_function($form,&$form_state) {
  // Do what you want here, you can change $form as you wish
  return $form; // If you don't return you'll get a WSOD!!!

There. In the my_handling_function, the complete form array has been build, along with elements that are added after module alter code (such as other modules with greater weight than yours). It is quite simple, however it tooks me a couple of hours trying to figure out how to get to a custom module field!

Though mentioned inline in the code, I wanted to stress this out: if you don't return $form in your code, Drupal will return a white screen with no errors. This is what you get for going under the hood though!

Since this is a fully built form array, some elements might not be where you expect them. Try playing around by printing out your "normal" of injected elements if what you're attempting to do doesn't work out of the box. As an example, disabling a field is not via $form['item']['#disabled'] = true;, rather via $form['item']['#attributes']['disabled'] = 'disabled';

Image from DrupalCon Munich blog page