I've created a field collection with four elements.

2 x 'Text' field, with 'Text field' widget
2 X 'Integer' field, with 'Text field' widget

I am using this field collection as part of the signup process. I'm using the Profile2 module, with the profile2_regpath module, that provides a signup page for the various profiles created with the Profile2 module. I've attached the field collection to a Profile2 bundle. I'm also using the field_group module to create vertical tabs, of which the field collection is part of a tab.

So to clarify, the user goes to the signup page for a specific type of profile. The profile is fielded, and one of the fields is the field collection. This field is displayed in a tab created by the field_group module.

The problem: If I add a second instance of the collection using the 'add another item' button, then I click 'delete', the delete button doesn't work, and in firebug I get the error message:

uncaught exception: Syntax error, unrecognized expression: #

There is no line number associated with the error.

If I try to click around the tabs after this, everything collapses into a big drupal error and it has to be refreshed.

Comments

jaypan’s picture

I've just done some more checking, and the tabs seem to be irrelevant to the issue. I created a fresh profile bundle, and added a single field (a new instance of the field collection mentioned in the first post), with no tabs and/or other fields. The same error appears with this set up as well. I can add a field, but the delete button does not remove the field, and the error appears again.

This Drupal installation is quite vanilla, I've only added this module, a custom module, and the field_group module.

tcalin’s picture

I have the same problem. I localized the cause here:

function field_collection_remove_js() {
  // drupal_html_id() very helpfully ensures that all html IDS are unique
  // on a page. Unfortunately what it doesn't realize is that the IDs
  // we are generating are going to replace IDs that already exist, so
  // this actually works against us.
  if (isset($_POST['ajax_html_ids'])) {
    unset($_POST['ajax_html_ids']);
  }

  list($form, $form_state) = ajax_get_form();
  drupal_process_form($form['#form_id'], $form, $form_state);

  // Get the information on what we're removing.
  $button = $form_state['triggering_element'];
  // Go two levels up in the form, to the whole widget.
  $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -3));
  // Now send back the proper AJAX command to replace it.
  $return = array(
    '#type' => 'ajax',
    '#commands' => array(
      ajax_command_replace('#' . $element['#id'], drupal_render($element))
    ),
  );

  // Because we're doing this ourselves, messages aren't automatic. We have
  // to add them.
  $messages = theme('status_messages');
  if ($messages) {
    $return['#commands'][] = ajax_command_prepend('#' . $element['#id'], $messages);
  }

  return $return;
}

After drupal_process_form($form['#form_id'], $form, $form_state); all the parents of $button i.e. $button['#array_parents'] are disappearing from the form array. So drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -3)) returns no element. I will continue the investigations, maybe come up with a patch.

tcalin’s picture

I think we are posting to the wrong place.
This should be a profile2 or profile2_regpath problem.
In the original profile2 form everything works perfect.

tcalin’s picture

Not a field_collection bug.
I reported the problem here: http://drupal.org/node/1577650

gabrielu’s picture

I think it might be related to the wrapper id of Field collection.
I am just using field collection to edit a node (node/%/edit).

Gabriel

riseman’s picture

If you get form via ajax, there is another solution.
I get hint from somewhere but i can not remember exact issue number.
but key is this.
in field_collection_remove_js function,
required inc file is not included if the parent of field collection is node type.
So, If you get a form by using ajax, you have to add required resources after calling ajax_get_form

function field_collection_remove_js() {
  // drupal_html_id() very helpfully ensures that all html IDS are unique
  // on a page. Unfortunately what it doesn't realize is that the IDs
  // we are generating are going to replace IDs that already exist, so
  // this actually works against us.
  if (isset($_POST['ajax_html_ids'])) {
    unset($_POST['ajax_html_ids']);
  }

  list($form, $form_state) = ajax_get_form();
  // Include required files to process form actions
  if ($form['#entity_type'] == 'node') {
    module_load_include('inc', 'node', 'node.pages');
  }
  
  drupal_process_form($form['#form_id'], $form, $form_state);

  // Get the information on what we're removing.
  $button = $form_state['triggering_element'];
  // Go two levels up in the form, to the whole widget.
  $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -3));
  // Now send back the proper AJAX command to replace it.
  $return = array(
    '#type' => 'ajax',
    '#commands' => array(
      ajax_command_replace('#' . $element['#id'], drupal_render($element))
    ),
  );

  // Because we're doing this ourselves, messages aren't automatic. We have
  // to add them.
  $messages = theme('status_messages');
  if ($messages) {
    $return['#commands'][] = ajax_command_prepend('#' . $element['#id'], $messages);
  }

  return $return;
}
jmuzz’s picture

Issue summary: View changes
Status: Active » Closed (duplicate)

Closing based on #4.