Hi, I'm creating a new module, I have a field named "Due Date", which need three select drop down in mm/dd/yyyy format.

So at first, I use
$form[due_date] = array('#type' => 'date', ......);

And it gives me a nice date three dropdown selection. But the problem is, it default to today's date, but what I really need is default to the date two weeks from today. So I'm thinking of using "default_value" attribute to change the default date. But no matter how I tried, it just won't work. Can anyone give me some suggestion on how to properly use the default value? what's the format requirement? I searched a lot on site, but not much infomation. I'm really new to drupal, Thanks so much for any suggestion.

Also besides this problem. I also can't find a way to do error checking for the select dropdown. I can only get the error message on the top, but can't get the error red box surrounding the select drop downs like it does with textarea and textfield....

Comments

sanjingbai’s picture

what's the '#default_value' format for the date type in

$form[..] = array('#type' => 'date', '#default_value' => ...);

Ariel T Glenn’s picture

Doing this:

'#default_value' => array('day'=> 1,'month'=>1,'year'=>2003)

gave me a default value of Jan 1, 2003 (for example).

Maybe there's a better approved way to set the default that doesn't rely on knowing the internal structure of the date variable, but I don't know what that would be.

Cainan’s picture

try #value instead.

from form.inc:

  // Default to current date
  if (!isset($element['#value'])) {
    $element['#value'] = array('day' => format_date(time(), 'custom', 'j'),
                            'month' => format_date(time(), 'custom', 'n'),
                            'year' => format_date(time(), 'custom', 'Y'));
  }

merlinofchaos’s picture

  $form['due_date'] = array(
    '#type' => 'date',
    '#default_value' => array('year' => 2006, 'month' => 12, 'day' => 3),
    '#title' => 'Due Date',
  );

Of course, I've hardcoded the values, so to actually figure out the date from 2 years ago you probably want to do this:

  $date = time() - 60 * 60 * 24 * 14; // 60 sec * 60 minutes * 24 hrs * 14 days = 2 weeks

  list($sec, $min, $hour, $day, $month, $year) = localtime($date);
  $form['due_date'] = array(
    '#type' => 'date',
    '#default_value' => array('year' => $year, 'month' => $month, 'day' => $day),
    '#title' => 'Due Date',
  );

** I haven't tested the localtime() call but I recall having used it in the past.
-- Merlin

[Point the finger: Assign Blame!]
[Read my writing: ehalseymiles.com]
[Read my Coding blog: Angry Donuts]

-- Merlin

[Read my writing: ehalseymiles.com]
[Read my Coding blog: Angry Donuts]

fatfish’s picture

2 function I'v added :

function  format_timestamp($date = 1) {
   return mktime(0,0,0,$date['month'],$date['day'],$date['year']);
}
function format_timestamp_to_date($timestamp = 1) {
  $day = date('j',$timestamp);
  $month = date('n',$timestamp);
  $year = date('Y',$timestamp);
  return array('day'=> $day,'month'=>$month,'year'=>$year);
}

and now - to give the elemnt defulte value I use :

$form['birth'] = array(
        '#type' => 'date',
        '#title' => t('Date of birth'),
        '#default_value' => format_timestamp_to_date($node->birth));

And for saving it in DB I use:

 db_query("UPDATE {extra_info} SET  birth = %d WHERE nid = %d",  format_timestamp($node->birth),  $node->nid);

I think the expand_date($element) function sould suport data in timestamp format as well.

..:| Tomer Fish |:..
fatFish - Lean Mean Coding Machine

Suuch’s picture

I suggest you put this code snippet in the handbook. Very useful.

Suuch Solutions supports The GhanaThink Foundation

jmanico’s picture

I have been using this code for a little while on 4.7.4 with no problem. Now I think that at 4.75. my days are off by one when I go back to edit that change.

Anyone else see this?

jmanico’s picture

This is a way more systemic problem at: http://drupal.org/node/65210 - But this did fix the problem for me by modifying your functions as so:

function format_timestamp_to_drupal_date($timestamp) {
  $day = format_date($timestamp, 'custom', d);
  $month = format_date($timestamp, 'custom', n);
  $year = format_date($timestamp, 'custom', Y);
  return array('day'=> $day,'month'=>$month,'year'=>$year);
}

and

function format_timestamp($date = 1) {
  return mktime(0,0,0,$date['month'],$date['day'],$date['year']) + 36000;
}

36000 being the specific timezone offset in seconds for my server.

alexis’s picture

Hi, I installed Javascript Tools module and enabled jscalendar for some of my forms. Here some ideas for the conversion to timestamp when using jscalendar.

An important detail: #type must be textfield, I had troubles at first because foolishly declared #type as date.

These are just parts of code so you have to put them in context for your own code.

The first condition checks if this is a form for editing an existing record and retrieves the date set, if it's a new record then uses today's date.

I'm using a field called txnid (which is short for transaction id), what you may use depends on your table.


 if ($edit->txnid) {
    $default_date = date('m-d-Y',$edit->payment_date);
  } else {
    $default_date = date('m-d-Y');
  }

  $form['payment_date'] = array(
    '#type' => 'textfield',
    '#title' => t('Payment date'),
    '#default_value' => $default_date,
    '#attributes' => array('class' => 'jscalendar'),
    '#jscalendar_showsTime' => 'false',
    '#jscalendar_ifFormat' => '%m-%d-%Y',
    '#description' => t('Payment Date in mm-dd-yyyy format.')
  );

Then I have this function:


function format_timestamp($textdate, $lang = 'en') {
  if ($lang = 'en') {
    $day = substr($textdate,3,2);
    $month = substr($textdate,0,2) ;
    $year = substr($textdate,6,4);

    return mktime(0, 0, 0, $month, $day, $year);
  }
}

And use this for inserting:

db_query("INSERT INTO {ebook_transaction} (nid, payment_date) VALUES (%d, %d)", $form_values['nid'], format_timestamp($form_values['payment_date']));

and this for updating:

db_query("UPDATE {ebook_transaction} SET nid = %d, payment_date = %d WHERE txnid = %d", $form_values['nid'], format_timestamp($form_values['payment_date']), $txnid);

Of course this is SQL which will change for you particular table definition.

I hope it helps.

Cheers.

Alexis Bellido
Visit my new Drupal-based site on music, movies and books.

pauly-1’s picture

Any idea why the database type a text field, why's it not converted into a date or at least an integer like "created" is? If I use #type => "date", what format does that correspond to in the database?
UPDATE: I'm using snippets as above, ta, surprised it's not built in though (at least as far as I've noticed)

jmcclelland’s picture

I had a similar problem. I have a module which wants to track date/time information. Just like drupal, I made the date/time field in the database an integer with the intention of holding a UTC timestamp, and then using the Drupal functions to properly display it for the users.

I ended up with the following functons:

// This function expects a UTC timestamp
function reg_convert_timestamp_to_date_array($timestamp = null)
{
  if(is_null($timestamp))
  {
    // get the current timestamp in UTC (not converted for the
    // server timezone)
    $timestamp = gmmktime();
  }

  // drupal's format_date function will return a date array
  // in the current user's timezone based on a UTC timstamp
  $day = format_date($timestamp, 'custom', 'j');
  $month = format_date($timestamp, 'custom', 'n');
  $year = format_date($timestamp, 'custom', 'Y');
  return array('day'=> $day,'month'=>$month,'year'=>$year);
}

// take a date array in the current user's timezone and
// convert to a UTC time stamp. Since the date array will not
// include the hour, minute, second - add the current hour, minute
// and second in the timestamp creation
function reg_convert_date_array_to_timestamp($date)
{
  // how many seconds passed midnight is it in UTC? 
  $ts = gmmktime();
  $hour = gmdate('H',$ts);
  $minute = gmdate('i',$ts);
  $second = gmdate('s',$ts);
  $seconds_passed_midnight = ($hour * 60 * 60) + ($minute * 60) + $second;

  // Get the drupal user's timezone offset
  $offset = reg_get_user_timezone();

  // we can't use mktime because it will do conversions based on the
  // timezone of the server. We want conversion to happen based on the
  // timezone of the drupal installation *or* the user's settings - 
  // because it is those settings that will govern how the date widget
  // is created to start with
  $user_timestamp = gmmktime(0,0,0,$date['month'],$date['day'],$date['year']);

  // now adjust for the user's time zone to get the true UTC time
  $utc_timestamp = $user_timestamp + $offset;
  // now add the hours passed midnight to the UTC timestamp:
  return $utc_timestamp + $seconds_passed_midnight;
}

function reg_get_user_timezone()
{
  // taken from the drupal format_date function
  global $user;
  if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone))
  {
    $timezone = $user->timezone;
  }
  else
  {
    $timezone = variable_get('date_default_timezone', 0);
  }
  return $timezone;
}

Then, in the form:

    $form['admin']['payment_date'] = array(
     '#type' => 'date',
     '#title' => t('Payment date'),
    );

And in the submit function:

$ts = reg_convert_date_array_to_timestamp($form_values['admin']['payment_date']);
sonofkc’s picture

when i need to add a datee filed in my module i used this code

// Provide a format using regular PHP format parts (see documentation on php.net).
// If you're using a date_select, the format will control the order of the date parts in the selector,
// rearrange them any way you like. Parts left out of the format will not be displayed to the user.
$format = 'Y-m-d';
$date = date($format);

$form['date2'] = array(
'#type' => 'date_popup', // types 'date_text' and 'date_timezone' are also supported. See .inc file.
'#title' => 'select a date',
'#default_value' => $date,
'#date_format' => $format,
'#date_label_position' => 'within', // See other available attributes and what they do in date_api_elements.inc
'#date_increment' => 15, // Optional, used by the date_select and date_popup elements to increment minutes and seconds.
'#date_year_range' => '-3:+3', // Optional, used to set the year range (back 3 years and forward 3 years is the default).
);

i got this from

http://drupal.org/node/292667

only diffrence i made is to generate a popup calender by changing '#type' =>'date_select' to '#type' => 'date_popup'

depened on date, date popup modules.