3

I have a node form in Drupal 7, in order to simplify it for the user I want to break it up into sections using the vertical tabs feature.

Using hook_form_FORMID_alter() I can move the fields without difficulty. When the node is saved, it writes the values correctly, and they appear in the node view.

But when I re-edit the node any value for a moved field is not set so I effectively lose the data. I've tried various options including changing the array_parents value in form_state['fields'][field][langcode].

(I wondered whether it would be better to move the fields during pre_render instead.)

Any ideas?

apaderno
  • 28,547
  • 16
  • 75
  • 90
Adaddinsane
  • 535
  • 6
  • 11

2 Answers2

3

Field API fields by default are placed into a container field type. If you want to convert them to a fieldset in the vertical tabs, you can do the following:

$form['field_tags']['#type'] = 'fieldset';
$form['field_tags']['#title'] = 'Tags';
$form['field_tags']['#group'] = 'additional_settings';

A better solution would be to use the new Field Group module so you can make these modifications through the UI, rather than in code.

Dave Reid
  • 1,260
  • 7
  • 12
  • I didn't know that module existed. Wonderful. I have no desire to re-invent wheels :-) installed and in play. – Adaddinsane Feb 01 '11 at 17:14
  • 1
    I'm upvoting for the in-code solution, actually, as it's been more useful to me than Field Group in many circumstances where I need more fine-grained theming control over a form, or when building custom forms. – geerlingguy Jan 03 '12 at 01:44
  • One more note: To create custom vertical tabs groups in code, $form['group_name_here']['#type'] = 'vertical_tabs'; — then, substitute 'group_name_here' for 'additional_settings' in above code. – geerlingguy Jan 03 '12 at 01:46
2

Sometimes it works better to move field items around in the #after_build step of the form creation process.

in hook_form_alter, you set your after build function like so:

function mymodule_form_alter(&$form, &$form_state, $form_id)
{
    $form['#after_build'][] = 'mymodule_myform_after_build';
}

Then you define your after_build function like so:

function mymodule_myform_after_build($form)
{
   //do stuff to the form array
   return $form;
}

I think you can even define after_build on individual elements.

Anyway, it's a good way to alter the form after all the modules have done their thing.

thtas
  • 370
  • 1
  • 3
  • 10