I know for D7 they are working on a nice jQuery UI for date picking--but for Drupal 6, how do you at least let the user know, that there is no date.

Currently, using PHP Date(), the date field when being edited, sometimes is a zero. So the zero translates to December 31st 1969 based on UNIX Timestamp. However, this is confusing to users who do not understand this. They think it's "the wrong date", not "an unentered date".

Can't we add an option for the 3 select boxes like "None" or "N/A" or "0" or "Pick:"??

Am I suppose to use form_alter for this? If so, how?

Comments

jaypan’s picture

Zero is actually January 1st, 1970, but you must be west of GMT :D

Anyways, it really depends on where you are trying to output the date. Basically, I would use something along the lines of:

$date = ($date) ? format_date($date) : t('There is no date');

Now you can output date and it will show either the formatted date, or the message indicating that there is no date.

Contact me to contract me for D7 -> D10/11 migrations.

executex’s picture

Damn!!! All this time I thought it was December 31st 1969, I need to rethink my life. (GMT -5:00) :)

But doesn't format_date return a string?

Here's the situation: User loads a form someone else edited, the form says 1969, the user gets confused. What the user is suppose to think is... 'Oh, the form says 1969 or null, I better enter a date today then because the last guy did not.'

It's a form element, dealing with FAPI not a text string for displaying right? Unless I'm missing something here.

jaypan’s picture

Can you show some code? As I mentioned previously, it depends on where you are outputting the date. If I can see the code you are working with, I can give a suggestion on how to deal with it.

Contact me to contract me for D7 -> D10/11 migrations.

executex’s picture

This would be an example I use. Sometimes the field is disabled for certain users, who see 1969, but they want to see like "no date" or something.

I don't want to hide or display a message, because sometimes the field is enabled, and still 1969, I want them to actually go ahead and enter a new date.

In other words, they need to be able to tell the difference between a form that someone else already entered a date on, and a form where no one has yet entered a date.


  $form['f1']['StartDate'] = array(
      '#type' => 'date',
      '#title' => t('Start Date'),
      '#disabled' => $disable,
      '#default_value' => array('year' => date('Y', $default['StartDate']), 'month' => date('n', $default['StartDate']), 'day' => date('j', $default['StartDate'])),
  );

jaypan’s picture

That's tricky. And to tell the truth, I haven't worked with the 'date' type form element for a long time, so it's hard to remember.

You can try using hook_form_alter() to add another option to the select elements for the date. So in the initial form definition, you would definite as you are, then hook into it with hook_form_alter(), and add something with a value of --- (or whatever) to each of the three date elements. You can use array_unshift() for this.

I *think* it will be something like this:

function my_module_form_alter(&$form, &$form_state, $form_id)
{
  if($form_id == 'my_forms_id')
  {
    if(!$default['StartDate']) // this is when the value is zero. You will have to pull this value from somewhere as it's not set in my code here.
    {
      array_unshift($form['f1']['StartDate']['year']['#options'], '---');
      array_unshift($form['f1']['StartDate']['month']['#options'], '---');
      array_unshift($form['f1']['StartDate']['day']['#options'], '---');
     }
  }
}

I'm typing this all off my head with no testing, so the likelihood of it actually working as-is is pretty close to none, but hopefully it can give you some ideas to work with.

Contact me to contract me for D7 -> D10/11 migrations.

executex’s picture

I have too many forms and too many fields to change. And I can't get $default into form_alter...

How can I do this?


function cts_form_alter(&$form, &$form_state, $form_id){
  foreach($form as $key => $val){
    foreach($val as $k => $v){
      if($k == "#type"){
        if($v == "date"){
          array_unshift($form[$key][$k]['year']['#options'], '---');
          array_unshift($form[$key][$k]['month']['#options'], '---');
          array_unshift($form[$key][$k]['day']['#options'], '---');
        } 
        //$form[$key][$k]['#default_value']
        //$form[$key][$k]['#default_value']
      }
    }
  }
 }

This seems so nasty and is probably completely wrong. And I also need to check if it has a default value timestamp is zero or not.

Isn't there a way to just modify the original date field function?? Or another date field module that is designed by someone who thought of this situation?

jaypan’s picture

Actually, now that you mention it, I think there is... I just don't remember what it is :D

Maybe use the #after_build attribute of the form element. It will work the same sort of way as hook_form_alter() I think, but you define a function in which you can alter the form element. You can then attach #after_build to every form element, which is a lot easier than calling hook_form_alter on all your form elements.

Contact me to contract me for D7 -> D10/11 migrations.

executex’s picture

You're right after_build was the best idea.

However, because of the limitations of date() function, and my weird -5 timezone. I can see --- for year, but for month/day it says 12/31.
Any ideas?


function _add_null_date($form_element, &$form_state) {
  // echo "addnull: ".print_r($form_element['#default_value'], TRUE);
  $time_array = $form_element['#default_value']; // grab the default value to see if it's zero null date or not.
  $date = mktime(19,0,0,$time_array['month'], $time_array['day'], $time_array['year']); // 19 is required on hour for date to equal zero. 24-5
  // echo "date: $date";
  if($date == 0){
    array_unshift($form_element['year']['#options'], '---'); // works
    array_unshift($form_element['month']['#options'], '---'); // 12 it fails
    array_unshift($form_element['day']['#options'], '---'); // 31 it fails
  }
  return $form_element;
}

executex’s picture

Ok so I changed it from #after_build to #pre_render

Because pre_render should modify the default_value and value of the 'date' field before rendering it.
However, my changes are not taking effect. Drupal is essentially ignoring the command to pre_render month and day. Why?

function _add_null_date($form_element) {
  $time_array = $form_element['#default_value'];
  //$date = mktime(0,0,0,$time_array['month'], $time_array['day'], $time_array['year']);
  if($time_array['year'] == 1969){
    array_unshift($form_element['year']['#options'], '---');
    array_unshift($form_element['month']['#options'], '---');
    array_unshift($form_element['day']['#options'], '---');
    $form_element['#default_value']['year'] = 0;
    $form_element['#default_value']['month'] = 0;
    $form_element['#default_value']['day'] = 0;
    $form_element['year']['#value'] = 0;
    $form_element['month']['#value'] = 0;
    $form_element['day']['#value'] = 0;
  }
  return $form_element;
}

Year is changing because date('Y', 0) returns 0. But I don't understand why $form_element['month']['#value'] is not changing neither is default_value.

I think I figured it out. I needed #process, and copy the function from form.inc called Expand_date, and modify it appropriately.

emclaughlin’s picture

To anyone else who has googled this post up, wanting to add a blank date to a drupal form, the solution I found was to set the default value for the date to be zeroes:

$form['date'] = array(
  '#type' => 'date',
  '#default_value' => array('year' => 0, 'month' => 0, 'day' => 0),
  '#pre_render' => array('add_null_date'),
);

with this as the pre_render function:

function add_null_date($form, &$form_state) {
  array_unshift($form['year']['#options'], '--');
  array_unshift($form['month']['#options'], '--');
  array_unshift($form['day']['#options'], '--');

  return $form;
}