December 3, 2012 - Comments Off on Drupal 7 Forms API: The One About the Date Fields

Drupal 7 Forms API: The One About the Date Fields

Drupal, as a content management system, allows you to create content types with date fields which means you can create events and calendars. There are many great modules which allow you to display content with date fields in calendars, forms, etc. But before you can fly, you must first learn to code... I think that's how the saying goes. Entering one, or even a couple of events into you site is not too difficult or cumbersome. The default node add forms are utilitarian if nothing else. I have even been know to gussy the forms up with some fieldsets, CSS and some occasional Jquery whiz-bang-iness. The challenge comes when you have to enter months worth of events at one sitting. After entering and saving a new event, the system will default to the current day (or whatever default relative date you set in the widget) the next time you add the next event. This means each time you add an event you have to set the month/day/year each time- and when this spans the next calendar year, or even several months, you finger may fall off from all the clicking needed.

The solution? Set the default date in the date widget programmatically, based on the last saved event date. This means if you are entering a lot of events in sequential order, you will have less clicking to do to set the date. It also means if you save an event several months in the future and later add a new event you will have to do the clicky-dance, but for adding many events at once, you will have saved yourself some time.

The way to change the default date in the form is to use the Drupal Forms API (formerly FAPI in D6). You will need to create a module, or add this code to an existing custom module. The Forms API, in simple terms, allows you to talk to Drupal and manipulate the forms through code. Instead of hacking away at a flat HTML file, editing <inputs> and trying to get form values to save in the right places, you can systematically address each form element and get/set values, change CSS attributes, add JS/Jquery and manipulate field settings/defaults. If you've ever installed Captcha, LoginToboggan or any other Drupal form altering module, that's exactly what they are doing. By 'hooking' into the Form API, they can perform all sorts of manipulation without rewriting or replacing the form's core- they simply alter it.

This function will find the currently displayed form and alter it if and only if it is the event form we want to alter. It next retrieves the date of the last event you saved and changes the sets that as the default value. If no date was last saved, then the form will default to the current date.

[cce_php]

function mymodule_form_alter($form, &$form_state, $form_id) {
switch ($form_id) {
case 'event_node_form' :
// Set the default start date for Events to the last saved event month
if ($form['#action'] == '/node/add/event') {
$date = variable_get('event_last_date', '');
$form['field_event_date']['und'][0]['#default_value']['value'] = $date['start'];
if (isset($date['end'])) {
$form['field_event_date']['und'][0]['#default_value']['value2'] = $date['end'];
}
}
break;
}
}

[/cce_php]

This next function reads the values of the event being saved and stores the date(s) as an array to the system table.

[cce_php]

function mymodule_node_presave($node) {
switch ($node->type) {
case 'event' :
$date['start'] = $node->field_event_date['und'][0]['value'];
if (isset($node->field_event_date['und'][0]['value2'])) {
$date['end'] = $node->field_event_date['und'][0]['value2'];
}
variable_set('event_last_date', $date);
break;
}
}

[/cce_php]

You will notice that there are 2 date fields being saved here, value and value2. If you have set the date field to allow an end date value to be set, it is called value2, and in this code is also saved. If you do not set it, or do not have it visible on the form, it will ignore it. The Second function calls hook_node_presave() which, like the Forms API, is an entry point into the Node API and allows you to interact with the node object via code. When any node is being processed for insertion/updating in Drupal, it will call this function and if it matches your 'event' type it will save the date field(s) to the system table for later retrieval by the first function. Place these two functions in a module and test it out. You will need to make sure your code matches  the content type name and CCK date field names of your site.

Modifications such as these can greatly improve the user experience of a site. When you are creating sites to be turned over to others for the content management, this attention to detail and usability can make their lives much easier.

Links:

Published by: chazcheadle in The Programming Mechanism
Tags:

Comments are closed.