Last updated March 21, 2009. Created by fago on April 4, 2007.
Edited by quicksketch, LeeHunter. Log in to edit this page.

This module just provides a new form element, that can be used by other modules.
It is an API module and this page is intended for developers!

This module provides a new form element, that can be used by other modules. This form element allows you to reuse existing forms inside your form!
So you can build forms that reuse existing forms while you extend them with further form items. Note that form reusing means not only reusing the visual representation, but also the validation and submit logic.

One important source for developers is the API documentation!

But let's show an example. We combine two forms into one - one node creation form for stories and one for books. All we need are two simple subforms, one for each node creation form. We set the correct form_id for each subform and pass the $node argument to it, which will be passed to node_form().

So here's the code:

<?php
/*
* Implementation of hook_menu()
*/
function subform_example_menu($may_cache) {
  if (
$may_cache) {
   
$items[] = array(
   
'path' => 'example',
   
'title' => t('Subform Example'),
   
'callback' => 'drupal_get_form',
   
'callback arguments' => array('subform_example_add_nodes'),
   
'access' => TRUE,
   
'type' => MENU_NORMAL_ITEM,
    );
    return
$items;
  }
}
function
subform_example_add_nodes() {
  global
$user;
 
$form = array();
  foreach (array(
'story', 'book') as $type) {
    if (
node_access('create', $type)) {
     
// Initialize new node:
     
$node = array('uid' => $user->uid, 'name' => $user->name, 'type' => $type);
     
//create the subform element
     
$form[$type.'_form'] = array(
     
'#type' => 'subform',
     
'#id' => $type .'_node_form',
     
'#arguments' => array($node),
     
'#data_separation' => TRUE,
      );
    }
  }
 
//this sets the subform submit handler, which submits the subforms for you
 
$form['#submit']['subform_element_submit'] = array();
  return
$form;
}
?>

That's it!
If you want to run and try these code, put it into subform_example.module and also create a subform_example.info file containing this two lines:

name = Subform Element Example
dependencies = subform_element

Then you can activate the example module. But note that this code requires at least version 1.1 of the subform_element module.
The example will present you both fully working node creation forms. You need to fill all required fields of both forms, only then the form validation succeeds. So the whole form will be submitted and your nodes are created!

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

If your subform uses FileUpload, you need to edit your "container" FORM to use "enctype=multipart/form-data". Without that your form will not upload attached files. So add this line before render or return your form:

  $form['#attributes'] = array('enctype' => 'multipart/form-data');

If your subform uses ImageField module or FileField you also need to set (to the Subform element) the #data_separation to FALSE to let them work.

form['mysubform'] = array(
  '#type' => 'subform',
  '#id' => $type .'_node_form',
  '#arguments' => array($node),
  '#data_separation' => FALSE,
),

Notes: I added this comment after reading this issue: #208864: File uploads don't work on subform_element Hope my comment help someone :)

-thePanz-

-thePanz-

files are excluded from the data_separation anyway, but the ajax callbacks of modules like imagefield or upload have problems with data separation. So if you use them, turn data separation off.

Will this work for Drupal 6?

I've tested it and it does not seem so....

Hi

Can you update this post for drupal version 6?

Thanks

subscribe

Steve

If there's no such thing as a stupid question, what do you call this?
if (isset($stupid_question)) { return 'a stupid question'; }