Hello,
i want to provide possibility to edit another node in field widget. But how to submit node which form is included (by fubform element) in field widget and give back to widget the NID of saved node (for create relation to new node)?

Example of my code, which properly load subform but preview and save doesn't work:

/**
 * Implements of hook_field_widget_form().
 */
function relation_edit_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $widget = $instance['widget'];
  $settings = $widget['settings'];
  
  if(isset($items[$delta]))
    $related_node = node_load($items[$delta]);
  else {
    global $user;
    $related_node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $settings['bundle']);
  }
  
  $element['node_' . $delta] = array(
    '#type' => 'subform',
    '#subform_id' => 'node_form',
    '#subform_file' => array('module' => 'node', 'name' => 'node.pages'),
    '#subform_arguments' => array($related_node, $settings),
    '#subform_default_triggering_element' => array('actions' => 'submit'),
    '#required' => FALSE,
  );
  
  //dpm($element);
  return $element;
}

Comments

casey’s picture

Cool use case! Don't you have a git sandbox or something, so I can check it out/see how to fix it?

Honza Pobořil’s picture

It will be there in a few minutes: http://drupal.org/sandbox/bobik/1195712

casey’s picture

I am sorry but the whole relation dummy field doesn't seem to be usable to create/save relations. Relations aren't stored in the field data so you can't retrieve them and their target entities per field index.

So this is entirely incorrect (but there isn't really a correct way to do it):

    $related_node = node_load($items[$delta]); // $items[$delta] contains nothing

I think the dummy field is only created to display relations as a field so you can use different formatters.

Anyways, to get the subforms submitting while pressing the save button on the parent form you can:

  $element['node_' . $delta] = array(
    '#type' => 'subform',
    '#subform_id' => 'node_form',
    '#subform_file' => array('module' => 'node', 'name' => 'node.pages'),
    '#subform_arguments' => array($related_node, $settings),
    '#subform_default_triggering_element' => array('actions' => 'submit'),
    '#required' => FALSE,
  );

  // Add one submit handler to the form that handles all subforms.
  $form_state['complete form']['#submit'][] = 'subform_submit_all';
Honza Pobořil’s picture

I am using patched version of relation_dummy_field and there is loaded related NIDs, but it seems that is not propper way. I am going to update my module to work with master version of relation_dummy field.

Honza Pobořil’s picture

Try the newest version. Now it loads relations and multiple values is handled in one widget, so clear cache, please.

casey’s picture

Ow wait,

$form_state['complete form']['#submit'][] = 'subform_submit_all';

should be

$form_state['complete form']['#submit']['subform_submit_all'] = 'subform_submit_all';

Else it would add the submit handler multiple times if your form contains multiple subforms.

Honza Pobořil’s picture

or $form variable?

$form['complete form']['#submit']['subform_submit_all'] = 'subform_submit_all';
casey’s picture

$form argument in hook_widget_form() is not necessarily the actual $form element.

Honza Pobořil’s picture

I've updated this, but it still doesn't work. (checkout last commit)

casey’s picture

Oww of course, hook_widget form is called before form_builder() is run. There is no complete form yet.

Add this to relation_edit_field_widget_form():

  $widget = $instance['widget'];
  $settings = $widget['settings'];

  $element['#process'][] = 'relation_edit_field_widget_form_process';

And this extra function:

function relation_edit_field_widget_form_process($element, &$form_state, &$form) {
  // Add one submit handler to the form that handles all subforms.
  $form['#submit']['subform_submit_all'] = 'subform_submit_all';

  return $element;
}
Honza Pobořil’s picture

No, it still does not work (related nodes were not updated).

casey’s picture

Well thats because you hide all submit buttons on the subform. If you expose those, it works.

But I see why you need to be able to have subforms without submit buttons, so I'll work out a solution.

casey’s picture

Actually it is possible. You had '#subform_default_triggering_element' wrong

 '#subform_default_triggering_element' => array('actions' => 'submit'),

should be

 '#subform_default_triggering_element' => array('actions', 'submit'),
Honza Pobořil’s picture

Repaired, but still doesn't work. Btw, you have the same mistake in subform_example.module on the line 289.

casey’s picture

Have you updated to latest subform version?

Honza Pobořil’s picture

Yes, after update Subform it is working now. Thank you.

How do you recommend to implement creating new nodes? I have prepared creating new nodes, but I don't know how to get back NID of new node to create relation.

casey’s picture

To save you some troubles when debugging, note that sessions have a storage limit. if you dsm($form_state), and the form is submitted and redirected (which means that $_SESSION['messages'] is going to be stored), you'll likely don't see any status messages at all. $form_state is way too large to be stored in session storage.

I ran into this while getting this to work.

ejustice’s picture

Did you ever get this working? Would you be willing to share your code?

casey’s picture

Honza Pobořil’s picture

Thank you, casey. I recommend to use dev release. It has been rewrited for more clear code, but still missing some features what green release have.

ejustice’s picture

Thank you!