Tech Blog :: Customizing Drupal date field with hook_form_alter and #after_build
Customizing Drupal date field with hook_form_alter and #after_build
I spent a long time today trying to figure out how to customize a Date field in Drupal 6. The field is called field_recurring_dates and looked like this:

I wanted the "To" date to only show the time, no date - so the field has Date, Start Time, and End Time. The field is repeating/"unlimited" so the whole unit gets returned via AHAH with the "Add Another Item" button. Renaming that to "Add another day" was easy, but getting the date/time fields to change was elusive. I tried everything else I could think of: #process, theme overrides for every element, preprocess, with no luck. The field is generated by a hook_elements inside the Date module, and I couldn't find the equivalent of a hook_elements_alter ... until I asked on IRC and got the perfect solution from Fox: the Form API's #after_build callback.
So here's the code, finally working, inside a custom module:
function MODULE_form_alter(&$form, $form_state, $form_id) { // work on initial node form and AHAH-generated partial form if ($form['#id'] == 'node-form' || $form_id == 'content_add_more_js') { if (isset($form['field_recurring_dates'])) { $form['field_recurring_dates']['#after_build'][] = 'custom_date_combo_after_build'; } // rename the 'Add' button if (isset($form['field_recurring_dates']['field_recurring_dates_add_more'])) { $form['field_recurring_dates']['field_recurring_dates_add_more']['#value'] = 'Add Another Day'; } } } function custom_date_combo_after_build(&$element) { // can be MULTIPLE items // need to find all the NUMERICALLY-KEYED elements foreach($element as $key => &$field) { if (is_numeric($key) && is_array($field) && isset($field['value']) && isset($field['value2'])) { // remove the Date part of 'To Date's unset($field['value2']['date']); // rename 'From Date' => 'Date' $field['value']['#title'] = 'Date'; $field['value']['time']['#title'] = 'From Time'; $field['value2']['time']['#title'] = 'To Time'; // remove 'To date' block title $field['value2']['#title'] = ''; // only need helper text outside whole group unset($field['#fieldset_description']); } } return $element; }
With a little CSS, it now looks like this:

Perfect!
Update and Correction: The above line,
unset($field['value2']['date']);
didn't work, because the missing 2nd date field messed up the field's validation.
So I checked out the Date Single Day module mentioned in the comments, and it's pretty much identical to this method except for this change:
$field['value2']['date']['#type'] = 'hidden'; // not unset()!
That seems to work well.
As a side note, I tried the #date_format attribute mentioned in the comments and couldn't get that to work at all. Also the first and second dates aren't separated in the form array enough to set a different #date_format on each. So #after_build seems to be the best bet.

@thebuckst0p
Google: TheBuckSt0p
Facebook: BenBuckman
LinkedIn
Skype: thebuckst0p
AIM: thebuckst0p
Amazon Wish List
Delicious: thebuckst0p
Drupal.org: thebuckst0p
The trick is the '#date_format' property of the field. The date module automatically figures out whether to show the date, time, or date and time fields based on whether the '#date_format' property includes date and/or time indicators. So probably all you had to do was this:
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
if ($form['#id'] == 'node-form' || $form_id == 'content_add_more_js') {
foreach ($form['field_recurring_dates'] as $key => &$field) {
if (is_numeric($key) && is_array($field)) {
$field['#date_format'] = 'H:i';
}
}
}
Here you find an existing module that does the same:
http://drupal.org/project/date_single_day
Nice to see a selection of options to achieve the same effect!
The #after_build property could be used in many cases, so good to see a real world example of it in action.
Very cool. It looks like date_single_day uses the same #after_build method, but I'll keep #date_format in mind for the future!
Thanks for all the comments guys, I added an update and correction to the post which relates to them.
- Ben
yea! i love good things. i'll keep sending out good vibes for the apartment to sell! :-) hentaiube [url="http://www.vishuis.co.za/cartoon"]hentaiube[/url] http://www.vishuis.co.za/cartoon hentaiube tarahentai [url="http://abigames.com/girl"]tarahentai[/url] http://abigames.com/girl tarahentai tetrahentai [url="http://www.sitedoadvogado.com.br/cartoon"]tetrahentai[/url] http://www.sitedoadvogado.com.br/cartoon tetrahentai
Post new comment