What is the correct way to attach an arbitrary field from a different content type to an existing form? I have a content type with a title and item id fields. The item ID field is a simple decimal and has unlimited entries. It acts as a reference to another field on a different content type.

In hook_form_alter(), I attach an AJAX callback to each existing item ID element. When the AJAX callback is called, I add the values that already exist from the other content type (image, a couple taxonomy terms), and two input elements to the results div. The two inputs are fields that exist on the other content type.

The way I do this is by loading the node whose item ID value correlates and adding it to the form (using a custom view type that only displays the fields I want). As for the inputs, I use drupal_get_form() to get the other content type's node form and copy the input element arrays into the form that I'm modifying. (This is the part that feels like cheating.)

On the page, everything displays fine. The problem is the form submission. When the new input elements try to validate, it fails. I've dug into the source code and discovered that the field does not exist in the $form_state array. That is to say, the corresponding $form_state['field'][$field_name] is missing.

My suspicion is that, upon splicing the form elements into the new form, the '#parent' and '#array_parent' arrays are not being updated correctly, despite being sure to add $form_state['rebuild'] = TRUE to hook_form_alter().

Is there a more correct way to add an arbitrary field from a different bundle to my form?

I considered using field_attach_form(), but I can't wrap my head around what the $entity argument should contain.

PS. I plan to handle the additional fields in a hook_node_prepare(), as I doubt shoving them into this content type would work!
I considered using field_attach_form(), but I can't wrap my head around what the $entity argument should contain.


It's the entity for which you want to show the form elements to edit its fields. For example, if you want have a reference to a node in $node, and you want to add the form elements to edit its fields, you add the following line to the code.

field_attach_form('node', $node, $form, $form_state, entity_language('node', $node));


The validation handler for the form should then call either one of these functions.


entity_form_field_validate()
field_attach_form_validate()


The first function builds the entity object from its $form_state parameter; the second function requires the entity object as second parameter.

Keep in mind that, despite the fact the UI allows you to add fields to a content type (e.g. add a Portrait image field to a Biography content type, but not to a Blog content type), for Drupal the entity to which the fields are attached is a node, which means you need a node object. passing as entity a string containing the machine name of the content type doesn't produce the expected result.