function datetime_datetime_form_process

Expands a #datetime element type into date and/or time elements.

All form elements are designed to have sane defaults so any or all can be omitted. Both the date and time components are configurable so they can be output as HTML5 datetime elements or not, as desired.

Examples of possible configurations include: HTML5 date and time: #date_date_element = 'date'; #date_time_element = 'time'; HTML5 datetime: #date_date_element = 'datetime'; #date_time_element = 'none'; HTML5 time only: #date_date_element = 'none'; #date_time_element = 'time' Non-HTML5: #date_date_element = 'text'; #date_time_element = 'text';

Required settings:

  • #default_value: A DrupalDateTime object, adjusted to the proper local timezone. Converting a date stored in the database from UTC to the local zone and converting it back to UTC before storing it is not handled here. This element accepts a date as the default value, and then converts the user input strings back into a new date object on submission. No timezone adjustment is performed.

Optional properties include:

  • #date_date_format: A date format string that describes the format that should be displayed to the end user for the date. When using HTML5 elements the format MUST use the appropriate HTML5 format for that element, no other format will work. See the format_date() function for a list of the possible formats and HTML5 standards for the HTML5 requirements. Defaults to the right HTML5 format for the chosen element if a HTML5 element is used, otherwise defaults to config('system.date')->get('formats.html_date.pattern.php').
  • #date_date_element: The date element. Options are:
    • datetime: Use the HTML5 datetime element type.
    • datetime-local: Use the HTML5 datetime-local element type.
    • date: Use the HTML5 date element type.
    • text: No HTML5 element, use a normal text field.
    • none: Do not display a date element.
  • #date_date_callbacks: Array of optional callbacks for the date element. Can be used to add a jQuery datepicker.
  • #date_time_element: The time element. Options are:
    • time: Use a HTML5 time element type.
    • text: No HTML5 element, use a normal text field.
    • none: Do not display a time element.
  • #date_time_format: A date format string that describes the format that should be displayed to the end user for the time. When using HTML5 elements the format MUST use the appropriate HTML5 format for that element, no other format will work. See the format_date() function for a list of the possible formats and HTML5 standards for the HTML5 requirements. Defaults to the right HTML5 format for the chosen element if a HTML5 element is used, otherwise defaults to config('system.date')->get('formats.html_time.pattern.php').
  • #date_time_callbacks: An array of optional callbacks for the time element. Can be used to add a jQuery timepicker or an 'All day' checkbox.
  • #date_year_range: A description of the range of years to allow, like '1900:2050', '-3:+3' or '2000:+3', where the first value describes the earliest year and the second the latest year in the range. A year in either position means that specific year. A +/- value describes a dynamic value that is that many years earlier or later than the current year at the time the form is displayed. Used in jQueryUI datepicker year range and HTML5 min/max date settings. Defaults to '1900:2050'.
  • #date_increment: The increment to use for minutes and seconds, i.e. '15' would show only :00, :15, :30 and :45. Used for HTML5 step values and jQueryUI datepicker settings. Defaults to 1 to show every minute.
  • #date_timezone: The local timezone to use when creating dates. Generally this should be left empty and it will be set correctly for the user using the form. Useful if the default value is empty to designate a desired timezone for dates created in form processing. If a default date is provided, this value will be ignored, the timezone in the default date takes precedence. Defaults to the value returned by drupal_get_user_timezone().

Example usage:

$form = array(
  '#type' => 'datetime',
  '#default_value' => new DrupalDateTime('2000-01-01 00:00:00'),
  '#date_date_element' => 'date',
  '#date_time_element' => 'none',
  '#date_year_range' => '2010:+3',
);

Parameters

array $element: The form element whose value is being processed.

array $form_state: The current state of the form.

Return value

array The form element whose value has been processed.

1 string reference to 'datetime_datetime_form_process'
datetime_element_info in drupal/core/modules/datetime/datetime.module
Implements hook_element_info().

File

drupal/core/modules/datetime/datetime.module, line 489
Field hooks to implement a simple datetime field.

Code

function datetime_datetime_form_process($element, &$form_state) {

  // The value callback has populated the #value array.
  $date = !empty($element['#value']['object']) ? $element['#value']['object'] : NULL;

  // Set a fallback timezone.
  if ($date instanceof DrupalDateTime) {
    $element['#date_timezone'] = $date
      ->getTimezone()
      ->getName();
  }
  elseif (!empty($element['#timezone'])) {
    $element['#date_timezone'] = $element['#date_timezone'];
  }
  else {
    $element['#date_timezone'] = drupal_get_user_timezone();
  }
  $element['#tree'] = TRUE;
  if ($element['#date_date_element'] != 'none') {
    $date_format = $element['#date_date_element'] != 'none' ? datetime_html5_format('date', $element) : '';
    $date_value = !empty($date) ? $date
      ->format($date_format) : $element['#value']['date'];

    // Creating format examples on every individual date item is messy, and
    // placeholders are invalid for HTML5 date and datetime, so an example
    // format is appended to the title to appear in tooltips.
    $extra_attributes = array(
      'title' => t('Date (i.e. !format)', array(
        '!format' => datetime_format_example($date_format),
      )),
      'type' => $element['#date_date_element'],
    );

    // Adds the HTML5 date attributes.
    if ($date instanceof DrupalDateTime && !$date
      ->hasErrors()) {
      $html5_min = clone $date;
      $range = datetime_range_years($element['#date_year_range'], $date);
      $html5_min
        ->setDate($range[0], 1, 1)
        ->setTime(0, 0, 0);
      $html5_max = clone $date;
      $html5_max
        ->setDate($range[1], 12, 31)
        ->setTime(23, 59, 59);
      $extra_attributes += array(
        'min' => $html5_min
          ->format($date_format),
        'max' => $html5_max
          ->format($date_format),
      );
    }
    $element['date'] = array(
      '#type' => 'date',
      '#title' => t('Date'),
      '#title_display' => 'invisible',
      '#value' => $date_value,
      '#attributes' => $element['#attributes'] + $extra_attributes,
      '#required' => $element['#required'],
      '#size' => max(12, strlen($element['#value']['date'])),
    );

    // Allows custom callbacks to alter the element.
    if (!empty($element['#date_date_callbacks'])) {
      foreach ($element['#date_date_callbacks'] as $callback) {
        if (function_exists($callback)) {
          $callback($element, $form_state, $date);
        }
      }
    }
  }
  if ($element['#date_time_element'] != 'none') {
    $time_format = $element['#date_time_element'] != 'none' ? datetime_html5_format('time', $element) : '';
    $time_value = !empty($date) ? $date
      ->format($time_format) : $element['#value']['time'];

    // Adds the HTML5 attributes.
    $extra_attributes = array(
      'title' => t('Time (i.e. !format)', array(
        '!format' => datetime_format_example($time_format),
      )),
      'type' => $element['#date_time_element'],
      'step' => $element['#date_increment'],
    );
    $element['time'] = array(
      '#type' => 'date',
      '#title' => t('Time'),
      '#title_display' => 'invisible',
      '#value' => $time_value,
      '#attributes' => $element['#attributes'] + $extra_attributes,
      '#required' => $element['#required'],
      '#size' => 12,
    );

    // Allows custom callbacks to alter the element.
    if (!empty($element['#date_time_callbacks'])) {
      foreach ($element['#date_time_callbacks'] as $callback) {
        if (function_exists($callback)) {
          $callback($element, $form_state, $date);
        }
      }
    }
  }
  return $element;
}