I originally posted this concern in http://drupal.org/node/522558#comment-4825090, thinking it was something wrong with multigroups, but having traced the code (thank goodness for NetBeans and xdebug!), I think I found the issue in function date_element_empty in the date_elements.inc file.

With the patch in the above-noted issues, multigroups makes sure that every element in a multigroup has a '_weight' and a '_remove' element set, and the '_weight' element is particularly important for maintaining deltas across all row elements of a multigroup.

Now, if a date element is empty in a particular row, during form validation, and in particular in the function date_combo_validate, when the element is found to be empty, the function calls date_element_empty, which creates a new $item array and then completely overwrites what was in $form_state (through function form_set_value) as follows:

  $item = array();
  $item['value'] = NULL;
  $item['value2']   = NULL;
  $item['timezone']   = NULL;
  $item['offset'] = NULL;
  $item['offset2'] = NULL;
  $item['rrule'] = NULL;
  form_set_value($element, $item, $form_state);
  return $item;

This of course means that the '_weight' attribute is gone from $form_state, and then later on when the field goes through a sort to deal with table-drag stuff, without those '_weight' attributes for each empty date field, the order of the resulting array (which is really the reassignment of deltas) is out-of-whack.

To solve this, I made a slight change in function date_element_empty as follows:

function date_element_empty($element, &$form_state) {
//  PATCH:  Multigroups needs _weight and _remove attributes to maintain deltas properly.
//          Alter the definition of $item here to preserve that.
//  $item = array();
  $item = isset($form_state['values'][$element['#field_name']]['rrule'])
                  ? $form_state['values'][$element['#field_name']]
                  : $form_state['values'][$element['#field_name']][$element['#delta']];
  $item['value'] = NULL;
  $item['value2']   = NULL;
  $item['timezone']   = NULL;
  $item['offset'] = NULL;
  $item['offset2'] = NULL;
  $item['rrule'] = NULL;
  form_set_value($element, $item, $form_state);
  return $item;
}

This seems to be working now for me, preserving the proper deltas, and still only storing non-empty date values in the database.

Would love some feedback on this. I've attached a patch.

Shawn

CommentFileSizeAuthor
multigroup patch for empty dates.patch969 bytessdsheridan
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bkat’s picture

I was having a similar issue - I was trying to remove a date element from a multigroup and even though there was 1 less element in the database, it would never be removed from the user interface.

I installed your patch and its working great now.

imclean’s picture

Title: Empty date fields in a multigroup cause deltas to be shuffled » Empty date fields causes missing deltas
Version: 6.x-2.9 » 6.x-2.x-dev
Status: Active » Needs work

Thanks sdsheridan, this has been a big problem for us for a while.

The issue is independent of multigroup. We're just using a multiple value (unlimited) date field. If any of them are blank or removed, the deltas don't get reassigned.

I applied your changes by hand and that solved the problem nicely! Are you able to create it against the version in git?

There's probably no need for the word "PATCH" in the comments in the patch.

imclean’s picture

DamienMcKenna’s picture

Status: Needs work » Closed (won't fix)

Unfortunately the D6 version of this module is no longer supported, but we appreciate the time you put into this. If this problem is relevant for D7 too, please reopen the issue. Thanks.