I'm trying to use the date_popup element with just the time portion, to allow users to enter a time value in a custom form.

The docs at the top of date_popup.module say this ought to be doable: "If no date elements are included in the format string, only the time textfield, will be created."

Here's my form code:

$form['create_performances']['time'] = array(
    // Use the jQuery date_popup type so the widget is nice to use.
    '#type' => 'date_popup',
    '#title' => t('Default performance time'),
    '#description' => t("Select a time for all performances."),
    '#date_format' => 'H:i',
    '#date_text_parts' => array('hour', 'minute'),
    '#default_value' => '2011-01-01 19:30:00',
  );

This makes the element correctly in the form, complete with a default time. So far so good.

But on submission, the $form_values has a NULL for this element.

I believe the problem is this part of date_popup_validate():

  if (empty($element['#value']['date'])) {
    if ($element['#required']) {
      // Set message on both date and time to get them highlighted properly.
      $message = t('Field %field is required.', array('%field' => $label));
      if (!empty($date_granularity)) {
        form_set_error($error_field .'][date', $message);  
        $message = ' ';
      }
      if (!empty($time_granularity)) {
        form_set_error($error_field .'][time', $message);  
      }
    }
    dsm('setting it to NULL...');
    form_set_value($element, NULL, $form_state);
    return;
  }

Because there is no date part of the value, the whole element gets a NULL.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jlscott’s picture

I have the same error, and found a solution by making a change in "date_popup.module", function "date_popup_validate".

The test in line 374:

  if (empty($element['#value']['date'])) {
    if ($element['#required']) {

needs to be replaced with

  if (($date_granularity && empty($element['#value']['date'])) ||
      ($time_granularity && empty($element['#value']['time']))) {
    if ($element['#required']) {

and the test on line 431

  if (is_array($element['#value']) && !empty($element['#value']['date'])) {
    $date = date_convert_from_custom(trim(!empty($element['#value']['date']) ? $element['#value']['date'] : ''), $date_format);
    $time = date_convert_from_custom(trim(!empty($element['#value']['time']) ? $element['#value']['time'] : ''), $time_format);

should be replaced with

  if (is_array($element['#value'])) {
    if (!empty($element['#value']['date'])) {
      $date = date_convert_from_custom(trim($element['#value']['date']), $date_format);
    }
    else {
      $date = '0000-00-00';
    }
    if (!empty($element['#value']['time'])) {
      $time = date_convert_from_custom(trim($element['#value']['time']), $time_format);
    }
    else {
      $time = '00:00';
    }

I haven't tested whether there are any problems in CCK date fields as a result of this change, as I don't use CCK.

raggax2’s picture

Status: Active » Needs work

I have the same need of just needing a time field without the date. I tested your suggestion out with the most current branch of date. This code starts to break down during the date_make_date. The result of just the time being in the value array is that the ultimate $value ends up being 0000-00-00 01:34 (for example). When you pass that through the date_make_date function ends up with a funky date like -01-34-0001.

This issue seems to be apart of a larger feature request at http://drupal.org/node/127200

I think this proposal is on the right path, but it seems like recent changes to the module may have broken them.

raggax2’s picture

Status: Needs work » Needs review
FileSize
1.51 KB

I've attached a patch based on the code recommended by jlscott. It basically only adds some extra logic to the branch statements in the validation process. All current simpletests pass on my local environment. One of the weird things about this issue is that we are validating time against a date object. This patch does end up producing a date like the one mentioned in comment #2. However, if you are doing a format_date() or something similar, the invalid date may not matter. There may be some additional processing needed to make this patch production worthy.

bartl’s picture

I'm having the same problem and luckily I went to google for it, so I found this thread...

I like the original solution #1 better than the patch in #3, because the latter ignores granularity. That is essential.

To solve the problem will the zero date, I'd prefer to copy the original date (and/or time) from the default value if the only granularity present, is time.

One possible solution may be, when the element is processed, in this case, to have the date alone stored as a value, instead of just dropped.

You'd still get an error if there is no default date...

Status: Needs review » Needs work

The last submitted patch, date_popup_time_only-1037150-3.patch, failed testing.

raggax2’s picture

Version: 6.x-2.7 » 6.x-2.x-dev
Status: Needs work » Needs review
FileSize
1.52 KB

I don't necessarily think that the submitted patch ignores granularity. I think granularity is already taken into consideration in the nested ifs:

  if (empty($element['#value']['date']) || empty($element['#value']['time'])) {
    if ($element['#required']) {
      // Set message on both date and time to get them highlighted properly.
      $message = t('Field %field is required.', array('%field' => $label));
      if (!empty($date_granularity)) {
        form_set_error($error_field .'][date', $message);
        $message = ' ';
      }
      if (!empty($time_granularity)) {
        form_set_error($error_field .'][time', $message);
      }
    }
    form_set_value($element, NULL, $form_state);
    return;
  }

They way I understand the code is that if either the time or date fields are empty and the field is required, then set the error message. Granularity is taken into consideration on the actual set errors. I don't see how adding the granularity in the initial branch test would gain you anything in terms of what the block is actually executing. I've included an updated patch to the most current version of the 6.x branch. I've updated a little bit of the branch logic around line 459. I have not yet included basing the time / date components on the #default_values.

As to the 2nd suggestion of setting the element value based on the #default_value components, that is an interesting idea. Is there any feedback from the module maintainers for this suggestion?

vishy_singhal’s picture

Title: date_popup element with just time doesn't work » solution

use the following property of the type date_popup

as
'#dateonly' => TRUE

or/and

'#timeonly' => TRUE

joachim’s picture

Title: solution » date_popup element with just time doesn't work

Thanks, will try it!

(Fixing title)

vishy_singhal’s picture

Sorry, forgot to mention the following integration of code as well.

Version 7.x-2.6
Drupal 7.20

File date_popup.module

/**
 * Helper function for extracting a date value out of user input.
 *
 * @param autocomplete
 *   Should we add a time value to complete the date if there is no time?
 *   Useful anytime the time value is optional.
 */
function date_popup_input_date($element, $input, $auto_complete = FALSE) {
  if (empty($input) || !is_array($input) || !array_key_exists('date', $input) || empty($input['date'])) {
      //check if there is no time associated in the input variable. This is the exception scenario where the user has entered only time and not date.
      if(empty($input['time']))
            return NULL;
  }
  date_popup_add();
  $granularity = date_format_order($element['#date_format']);
  $has_time = date_has_time($granularity);
  $flexible = !empty($element['#date_flexible']) ? $element['#date_flexible'] : 0;

  $format = date_popup_date_format($element);
  $format .= $has_time ? ' ' . date_popup_time_format($element) : '';
//check if date is empty, if yes, then leave it blank.
  $datetime = !empty($input['date']) ? $input['date'] : '';
  $datetime .= $has_time ? ' ' . $input['time'] : '';
  $date = new DateObject($datetime, $element['#date_timezone'], $format);
//if the variable is time only then set TimeOnly to TRUE
    if(empty($input['date']) && !empty($input['time']) ){
        $date->timeOnly = 'TRUE';
    }
  if (is_object($date)) {
    $date->limitGranularity($granularity);
    if ($date->validGranularity($granularity, $flexible)) {
      date_increment_round($date, $element['#date_increment']);
    }
    return $date;
  }
  return NULL;
}

Function - date_popup_validate

 //if (empty($date) || !empty($date->errors)) {
if ((empty($element['#value']['date']) && empty($element['#value']['time']))  || !empty($date->errors)) {
joachim’s picture

Could you post that as a patch please?

vishy_singhal’s picture

I definitely can. Will do it within a few days.

vishy_singhal’s picture

Version: 6.x-2.x-dev » 7.x-2.6
FileSize
2.34 KB

Submitting patch as requested.

Status: Needs review » Needs work

The last submitted patch, date_popup-time_only-1037150-12.patch, failed testing.

vishy_singhal’s picture

Can you post results of test

Risse’s picture

I am still getting this bug on the latest 7.x-2.x version.

The previous patch fixes the bug, here it is modified to work on the latest version.

Risse’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 15: date_popup_time_only-1037150-15.patch, failed testing.

vijaycs85’s picture

Issue tags: +sprint
antroxim’s picture

Assigned: Unassigned » antroxim
antroxim’s picture

Version: 7.x-2.6 » 7.x-2.x-dev
Status: Needs work » Needs review

All patches should be tested against dev version.

antroxim’s picture

Submitting a fixed patch from #15 for latest dev version

Status: Needs review » Needs work

The last submitted patch, 21: date_popup-time_only_submit-1037150-21.patch, failed testing.

  • podarok committed c9f9c1e on 7.x-2.x authored by antroxim
    Issue #1037150 by raggax2, vishy_singhal, antroxim, Risse: date_popup...
podarok’s picture

Status: Needs work » Fixed
Issue tags: +CodeSprintUA

Thanks, merged

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.