I'm currently working on a project related to employee goals. The idea here, is that each individual interacting with my project site has a particular area of expertise and different job requirements. To that end, when they write goals for their yearly personal development, they will be slightly different for each individual. I'm working on a custom content type (and a resulting custom "goal category" field) to support this.
I've had good luck with the hook_form_alter() function and have followed the example developer module to make a field that I can override with a list of custom values, save to the database, and retrieve from the database in both my node view, and my node/edit view. So far so good!
The problem is, that as soon as I start wrapping the field inside of a Field Collection, things go downhill rapidly. The field values will still propagate, but I cannot for the life of me get the user selections in the list field to persist. Even worse, the node_presave, node_udpate, and node_insert hooks don't see the selection (that is a round about way of saying that the field collection entity located in the resulting $node variable in each of these functions doesn't contain a selection when looked up with field_collection_item_load() ).
I think my problem is related to the "multi-add" field collection. My code, is perhaps not the cleanest, and I would love some feedback on how I might work around the problems I'm having. I have had great luck finding documentation on how to accomplish this OUTSIDE of a field collection, but zero luck finding anything about doing this inside a field collection. I think my problem is that I'm iterating through the field collections to figure out which number I need to modify, but I guess I don't know how else to select the field collections in question otherwise.
<?php
$i=0;
//Foreach field collection that we have...
foreach ($form['field_goal']['und'] as $key=>$value) {
//if it's one of the actual collections and not another part of the array
if (is_numeric($key)) {
//add a custom field into the form based on the key
$form['field_goal']['und'][$key]['field_goal_category2'] = array(
'#type' => 'select',
'#title' => t('Goal Category'),
'#options' => $values,
//'#default_value' => isset($category) ? $category : '',
'#description' => $description,
'#required' => TRUE,
'#weight' => 0,
);
}
$i++;
}
?>The only issue I've found that is similar to this http://drupal.org/node/1822092 has gone answered by the folks over on the FC module board. Hoping someone on the regular forums has a suggestion, I'm running low on ideas.
Thanks!
Comments
A few questions: 1) You said
A few questions:
1) You said you are adding a field. Do you mean an HTML field, or a field created using the drupal Field API (with instances, widgets and formatters)?
2) Can you please be more specific about the problem? What is the workflow to recreate the problem. What is your expected behavior?
3) You gave a chunk of code, but with no context as to where it exists. What function does it reside in?
Jaypan We build websites
1. I didn't use the Field
1. I didn't use the Field API, I basically used the example out of the drupal developer example download to create a list field in the hook_form_alter() function in a custom module.
2. When you go to the node/add page for the content type, I see the field collection in place. Within that collection, I can see my field that the module is creating, with the custom values showing up in it. When I select a value, and click the save button to trigger the submission of the node, I have some debugging code in the node_update() function and cannot find the selection that I just made. (Yes, I am looking up the entity id of the field collection, and I can see other fields in the field collection just fine, just not my custom field)
3. The code I gave resides in hook_form_alter(). It takes the $form variable that is passed into that function, modifies it and adds the field above, and then returns the $form variable.
The process of node creation
The process of node creation in Drupal goes like this:
1) The user accesses the node/add/___ page
2) An empty node (no Node ID) is generated with some default values. (Note: when a user goes to the node edit page, in this step, the node being edited is loaded, rather than creating a new node.)
3) The node is passed to the Form API
4) The form is generated, using the default values provided in the node created in step 2
5) The user enters data into the form, and submits it
6) The node created in step 2 is loaded, and the user submitted values are merged with the node
So at this point, the system has a $node object in memory, but it hasn't been saved to the database yet. The next part is where it gets relevant to your situation:
7) The $node object is passed to the NodeController class
8) The NodeController class saves the new node to the system. (Note: when editing a node, it overwrites the node data in the system.)
8B) The NodeController class invokes the various Field API hooks in order to save the Field data. A Field Collection is a type of field, so all of the Field API hooks that are implemented by the Field Collection module are invoked.
8C) The NodeController class invokes hook_node_insert() (Note: hook_node_update() when editing), passing it the newly saved $node object. This means that any modules implementing this hook have their hook functions fired. Your module is implementing hook_node_update(), and you are receiving the newly created node.
As you can see from steps 8B and 8C, hook_node_update() does not ever receive the field data. That data is processed separately in the field api hooks. This is why you are not seeing the data in your hook implementation.
You can probably find one of the hook_field_ series of hooks in which you can get access to this data, but it's generally not really the Drupally way to do it. The Drupally way would be to either use a pre-existing field type, or to create your own custom Field type, beinning with implement hook_field_info(), hook_field_widget_info(), and hook_field_formatter_info(). Doing so will integrate your field with the system, and do things for example like integrating your data with Views.
Jaypan We build websites
I'll experiment with the
I'll experiment with the Field API next then. Thanks for your thorough responses!