You are here

public static function DatexDateList::processDatelist in Datex 8

Expands a date element into an array of individual elements.

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_part_order: Array of date parts indicating the parts and order that should be used in the selector, optionally including 'ampm' for 12 hour time. Default is array('year', 'month', 'day', 'hour', 'minute').
  • #date_text_parts: Array of date parts that should be presented as text fields instead of drop-down selectors. Default is an empty array.
  • #date_date_callbacks: Array of optional callbacks for the date element.
  • #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. 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. Defaults to 1 to show every minute.
  • #date_timezone: The Time Zone Identifier (TZID) to use when displaying or interpreting dates, i.e: 'Asia/Kolkata'. Defaults to the value returned by date_default_timezone_get().

Example usage:

$form = array(
  '#type' => 'datelist',
  '#default_value' => new DrupalDateTime('2000-01-01 00:00:00'),
  '#date_part_order' => array(
    'month',
    'day',
    'year',
    'hour',
    'minute',
    'ampm',
  ),
  '#date_text_parts' => array(
    'year',
  ),
  '#date_year_range' => '2010:2020',
  '#date_increment' => 15,
  '#date_timezone' => 'Asia/Kolkata',
);

Parameters

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

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

array $complete_form: The complete form structure.

Return value

array

Overrides Datelist::processDatelist

File

src/Element/DatexDateList.php, line 106

Class

DatexDateList
Plugin annotation @FormElement("datelist");

Namespace

Drupal\datex\Element

Code

public static function processDatelist(&$element, FormStateInterface $form_state, &$complete_form) {

  // 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();
  }
  $cal = datex_factory($element['#timezone'], 'en');
  if (!$cal) {
    return parent::processDatelist($element, $form_state, $complete_form);
  }
  $e_cal = datex_factory($element['#timezone'], 'en', 'gregorian');
  if ($date) {
    $date = DatexDrupalDateTime::convert($date);
  }

  // Load translated date part labels from the appropriate calendar plugin.
  $date_helper = new DateHelper();
  $element['#tree'] = TRUE;

  // Determine the order of the date elements.
  $order = !empty($element['#date_part_order']) ? $element['#date_part_order'] : [
    'year',
    'month',
    'day',
  ];
  $text_parts = !empty($element['#date_text_parts']) ? $element['#date_text_parts'] : [];

  // Output multi-selector for date.
  foreach ($order as $part) {
    switch ($part) {
      case 'day':
        $options = $date_helper
          ->days($element['#required']);
        $format = 'j';
        $title = t('Day');
        break;
      case 'month':
        $fac = datex_factory();
        $options = $fac
          ->listOptions('monthNames', $element['#required']);
        $format = 'n';
        $title = t('Month');
        break;
      case 'year':
        $range = static::datexDatetimeRangeYears($element['#date_year_range'], $date, $cal
          ->getCalendarName());
        $min = $range[0];
        $max = $range[1];
        $cal
          ->setTimestamp(REQUEST_TIME);
        $rng = range(empty($min) ? intval($cal
          ->format('Y') - 3) : $min, empty($max) ? intval($cal
          ->format('Y') + 3) : $max);
        $rng = array_combine($rng, $rng);
        $options = !$element['#required'] ? [
          '' => '',
        ] + $rng : $rng;
        $format = 'Y';
        $title = t('Year');
        break;
      case 'hour':
        $format = in_array('ampm', $element['#date_part_order']) ? 'g' : 'G';
        $options = $date_helper
          ->hours($format, $element['#required']);
        $title = t('Hour');
        break;
      case 'minute':
        $format = 'i';
        $options = $date_helper
          ->minutes($format, $element['#required'], $element['#date_increment']);
        $title = t('Minute');
        break;
      case 'second':
        $format = 's';
        $options = $date_helper
          ->seconds($format, $element['#required'], $element['#date_increment']);
        $title = t('Second');
        break;
      case 'ampm':
        $format = 'a';
        $options = $date_helper
          ->ampm($element['#required']);
        $title = t('AM/PM');
        break;
      default:
        $format = '';
        $options = [];
        $title = '';
    }
    $default = isset($element['#value'][$part]) && trim($element['#value'][$part]) != '' ? $element['#value'][$part] : '';
    $value = $date instanceof DrupalDateTime && !$date
      ->hasErrors() ? $date
      ->format($format) : $default;
    if (!empty($value) && $part != 'ampm') {
      $value = intval($value);
    }
    $element['#attributes']['title'] = $title;
    $element[$part] = [
      '#type' => in_array($part, $text_parts) ? 'textfield' : 'select',
      '#title' => $title,
      '#title_display' => 'invisible',
      '#value' => $value,
      '#attributes' => $element['#attributes'],
      '#options' => $options,
      '#required' => $element['#required'],
      '#error_no_message' => FALSE,
      '#empty_option' => $title,
    ];
  }

  // 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);
      }
    }
  }
  return $element;
}