Modifying CCK fieldgroups with hook_form_alter()

I was writing a module to conditionally hide a fieldset on a CCK node editing form based on whether the user is logged in or not, and for a while I was very puzzled as to why my custom module's implementation of hook_form_alter wasn't seeing any of the fieldsets defined by the CCK fieldgroup module.

I searched Google for the terms 'cck fieldset hook_form_alter', which led me to a helpful tip from Benjamin Melançon:

http://agaricdesign.com/note/not-seeing-cck-fieldsets-when-you-form-alter-your-form

The problem is that the CCK fieldgroup module is stored in the Drupal 5 'system' table with a weight of 9. My custom module had a weight of 0. When Drupal runs, it loads modules in order of their weight, so the fieldgroup module wasn't making its changes to the node form until after my module's form_alter() function.

I created an update to bump my custom module's weight to 10 (by implementing hook_update_N()), and after running update.php I immediately gained access to the CCK fieldgroup I had been trying to hide in the first place:

/**
* Fix module weight to be heavier than CCK field group module,
* so hook_form_alter() has access to field groups
*/
function my_module_update_1() {
$items = array();
$items[] = update_sql("UPDATE {system} SET weight = 10 WHERE `name` = 'my_module';");
drupal_set_message('Updated custom module weight.');
return $items;
}

(See "How to update a module's weight" on Drupal.org for more information & discussion.)

In Drupal 6, the Utility module provides an interface for adjusting module weights. There is a Module Weight module for Drupal 5, but at the time of this post it has no stable releases.

As for the original subject of this post, modifying a CCK fieldgroup with hook form alter, here's what I did to hide a fieldgroup from non-anonymous users (an admittedly curious use case, but this logic could easily be inverted to hide a fieldgroup from anonymous users instead):

/**
* Implementation of hook_form_alter().
*/
function my_module_form_alter($form_id, &$form) {
switch ($form_id) {
case 'my_content_type_node_form':
if ($GLOBALS['user']->uid) {
    $form['group_my_group_name']['#access'] = FALSE;
}
break;
}
}

Alternative to unset

Good post, I've been caught by module weight myself, and not just on form alters.

You might be interested in the #access attribute:
http://api.drupal.org/api/file/developer/topics/forms_api_reference.html...

(Instead of unset, you'd use: $form['group_my_group_name']['#access'] = false)

Thanks Dale

I know I encountered the #access attribute at some point in the past, but I had quite forgotten about it. Definitely the more "Drupalish" way to go about it! Example code updated accordingly.

unset is handy, too

Although in most cases setting #access false is probably the way to go, there are times where unset is what you need. It's good to have both in the toolbox!

Brett

I always use #access

thanks

Good info. Thanks for the source code of this hook too.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd><p><div> <br><img>
  • Lines and paragraphs break automatically.

More information about formatting options

Verification
This question is for testing whether you are a human visitor and to prevent automated spam submissions.