You are here

function date_field_widget_form in Date 7

Same name and namespace in other branches
  1. 7.3 date_elements.inc \date_field_widget_form()
  2. 7.2 date_elements.inc \date_field_widget_form()

Private implementation of hook_widget().

The widget builds out a complex date element in the following way:

  • A field is pulled out of the database which is comprised of one or more collections of from/to dates.
  • The dates in this field are all converted from the UTC values stored in the database back to the local time before passing their values to FAPI.
  • If values are empty, the field settings rules are used to determine if the default_values should be empty, now, the same, or use strtotime.
  • Each from/to combination is created using the date_combo element type defined by the date module. If the timezone is date-specific, a timezone selector is added to the first combo element.
  • If repeating dates are defined, a form to create a repeat rule is added to the field element.
  • The date combo element creates two individual date elements, one each for the from and to field, using the appropriate individual Date API date elements, like selects, textfields, or popups.
  • In the individual element validation, the data supplied by the user is used to update the individual date values.
  • In the combo date validation, the timezone is updated, if necessary, then the user input date values are used with that timezone to create date objects, which are used update combo date timezone and offset values.
  • In the field's submission processing, the new date values, which are in the local timezone, are converted back to their UTC values and stored.

File

./date_elements.inc, line 47
Date forms and form themes and validation.

Code

function date_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $base) {
  $element = $base;
  module_load_include('inc', 'date_api', 'date_api_elements');
  $timezone = date_get_timezone($field['settings']['tz_handling'], isset($items[0]['timezone']) ? $items[0]['timezone'] : date_default_timezone());

  // TODO see if there's a way to keep the timezone element from ever being
  // nested as array('timezone' => 'timezone' => value)). After struggling
  // with this a while, I can find no way to get it displayed in the form
  // correctly and get it to use the timezone element without ending up
  // with nesting.
  if (is_array($timezone)) {
    $timezone = $timezone['timezone'];
  }

  // Convert UTC dates to their local values in DATETIME format,
  // and adjust the default values as specified in the field settings.
  // It would seem to make sense to do this conversion when the data
  // is loaded instead of when the form is created, but the loaded
  // field data is cached and we can't cache dates that have been converted
  // to the timezone of an individual user, so we cache the UTC values
  // instead and do our conversion to local dates in the form and
  // in the formatters.
  $process = date_process_values($field, $instance);
  foreach ($process as $processed) {
    if (!isset($items[$delta][$processed])) {
      $items[$delta][$processed] = '';
    }
    $date = date_local_date($form, $form_state, $delta, $items[$delta], $timezone, $field, $instance, $processed);
    $items[$delta][$processed] = is_object($date) ? date_format($date, DATE_FORMAT_DATETIME) : '';
  }
  $element += array(
    '#type' => 'date_combo',
    '#theme_wrappers' => array(
      'date_combo',
    ),
    '#weight' => $delta,
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
    '#date_timezone' => $timezone,
    '#element_validate' => array(
      'date_combo_validate',
      'date_widget_validate',
    ),
  );
  if ($field['settings']['tz_handling'] == 'date') {
    $element['timezone'] = array(
      '#type' => 'date_timezone',
      '#delta' => $delta,
      '#default_value' => $timezone,
      '#weight' => $instance['widget']['weight'] + 0.2,
    );
  }

  // Add a date repeat form element, if needed.
  if (module_exists('date_repeat') && $field['settings']['repeat'] == 1) {
    module_load_include('inc', 'date', 'date_repeat');
    _date_repeat_widget($element, $field, $instance, $items, $delta);
    $element['rrule']['#weight'] = $instance['widget']['weight'] + 0.4;
  }
  return $element;
}