Answer the question
In order to leave comments, you need to log in
How to programmatically prepopulate a multiple field in drupal7 with several Items of the FieldColelction type when creating a new material?
I spent a lot of time to find a solution to the following problem
There is a material type: $node->type == 'product_template'
screenshot:
Each item (Item) in the Field Сollection (field_properties) consists of - screenshot:
Task: programmatically make that when adding a new the nodes of this type of material
in the add form were as in the screenshot:
I dug up this material from Google
: drupal.cocomore.com/blog/field-collections-exposed
form_state
An example of my code that alters the form for adding material and adds as in the template node nid==22.
/**
* Implements hook_form_alter().
*/
function nxte_database_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'product_template_node_form'){
if(!isset($form['nid']['#value'])){
dsm('is_new');
dsm($form);
dsm($form_state);
//unset($form['#node']);
//unset($form['#entity']);
//var_dump($form);
//exit;
$original_node = node_load(22);
// Get the fields defined for this node type;
$node_fields = field_info_instances('node', $node_type);
// Re-create the fields for the original node, like when editing it
$tmpform = array();
$tmpform['#node'] = $original_node;
$tmpform['type']['#value'] = $node_type;
$tmpform_state = array( 'build_info' => array('form_id' => $form['#form_id']) );
field_attach_form('node', $original_node, $tmpform, $tmpform_state, entity_language('node', $original_node));
// Here we have on $tmpform the form structure we need and with the default values.
// We can choose what fields to clone, but in this example we will loop over all the node fields and clone all of them
foreach($node_fields as $field_name => $field_settings) {
// Copy the form structure
$form[$field_name] = $tmpform[$field_name];
// Copy state information about this field
$form_state['field'][$field_name] = $tmpform_state['field'][$field_name];
// When copying the field_collection structure, reset the id of the entities and
// they will be created again with a new id.
$langcode = field_language('node', $original_node, $field_name);
if ($form_state['field'][$field_name][$langcode]['field']['type'] == 'field_collection') {
$field_childs = &$form_state['field'][$field_name][$langcode]['entity'];
foreach(element_children($field_childs) as $idx => $fc_entity) {
$field_childs[$idx]->item_id = NULL;
$field_childs[$idx]->revision_id = NULL;
}
}
}
}
}
}
Answer the question
In order to leave comments, you need to log in
I found the solution myself - maybe it will be useful to someone.
1) create a new node that will serve as a blank with a preset set of elements in
$node_template->field_properties['und'][0..2] I have three properties for the default product
$node_template->nid==22
2) We hardcode the same structure to the object of the created node (without its nid yet) in the hook:
/**
* Implements hook_node_prepare().
*/
function nxte_database_node_prepare($node) {
//Изменяем объект ноды перед тем как друпал построит для него форму добавления материала
if($node->type == 'product' && !isset($node->nid)){
$node_array_hardcoded =array(
'body' => array(
'und' => array(
0 => array(
'value' => 'Description of product',
'format' => 'full_html',
'safe_value' => 'Description of product',
),
),
),
'field_properties' => array(
'und' => array(
0 => array(
'value' => 46, //это значение будет изменено после сохранения новой ноды (сейчас это existing_filed_collection_item_ID)
'revision_id' => 46,
),
1 => array(
'value' => 47, //это значение будет изменено после сохранения новой ноды (сейчас это existing_filed_collection_item_ID)
'revision_id' => 47,
),
2 => array(
'value' => 48, //это значение будет изменено после сохранения новой ноды (сейчас это existing_filed_collection_item_ID)
'revision_id' => 48,
),
),
),
);
foreach ($node_array_hardcoded as $key => $value){
$node->$key = $value;
}
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question