Re-using the repeating date field widget in custom Drupal forms

Roomify, LLC · June 11, 2015

As part of our work on Rooms Tours, (coming soon!) we wanted to give users the ability to quickly and easily input regular tour dates/times. (This would be something like: California Wine Country Tour, every week from Tuesday at noon to Thursday noon, from May 15th through September 15th.) We quickly thought of using something like the Google calendar interface for inputting recurring calendar events. The good news was that the excellent date module has a recurring event field. The bad news was that we needed to use the inputs in a custom form, and the module isn’t adapted for that use case. Here’s how to use the widget in a manner that such that the validation and generation of the ical RRULE you need at the end works:

 
In your form callback, you’ll need a date field:
 
     $form['date'] = array(
      '#type' => 'date_popup',
      '#required' => TRUE,
      '#date_timezone' => date_default_timezone(),
      '#date_increment' => 2,
      '#date_format' => 'Y-m-d H:i',
      '#date_year_range' => '-0:+1',
      '#date_type' => DATE_DATETIME,
      '#title' => t('Starting date'),
      '#default_value' => '', 
      '#required' => TRUE,
      // The following attributes are necessary for the date repeat field validation not to complain.
      '#element_validate' => array(
        'date_repeat_field_widget_validate',
      ),  
      '#field_name' => 'field_not_really_a_field',
      '#field_parents' => array('dates'),
      '#entity_type' => ‘YOUR_ENTITY_TYPE’,
      '#bundle' => ‘YOUR_ENTITY_BUNDLE’,
      '#date_is_default' => TRUE,
      '#language' => LANGUAGE_NONE,
    );  
 
You’ll also need to simulate the checkbox that tells the date repeat module that this is a repeating date field:
 
     $form['date']['show_repeat_settings'] = array(
      '#type' => 'hidden',
      '#value' => 1,
    );
 
Finally, you’ll need the repeating rule form element, simulating the form structure that the field validation code expects:
 
     $form['parent1'] = array(
      '#tree' => TRUE,
      'parent2' => array(
        '#tree' => TRUE,
        '#required' => TRUE,
        'rrule' => array(
          '#type' => 'date_repeat_rrule',
          '#theme_wrappers' => array('date_repeat_rrule'),
          '#default_value' => isset($instance->repeat_rule) ? $instance->repeat_rule : '',
          '#date_timezone' => date_default_timezone(),
          '#date_label_position' => 'above',
          '#date_format' => 'm/d/Y - H:i',
          '#date_increment' => 1,
          '#date_year_range' => '-0:+1',
          '#date_repeat_widget' => 'date_popup',
          '#date_flexible' => 0,
          '#date_repeat_collapsed' => TRUE,
        ),
      ),
    ); 
 
So, that’s the setup. Given that it’s all correct, the date validation code will insert an iCal RRULE in $form_state[‘values’], with which you can do whatever you need. In your form’s submit handler:
   $rrule = $form_state['values']['parent1']['parent2']['rrule'];
 
For nice example code for generating individual event dates from an rrule, you can have a look at the date_repeat_build_dates function in date_repeat_field.module. Hope this has been helpful!

Twitter, Facebook