I was unsatisfied with the data_popup module and I have extended the module to support more options of the ui.datepicker module. Specifically, I added support to limit the selectable dates using a minimum and maximum day, exclude specific weekdays, exclude specific days and set any other ui.datepicker option from PHP.

The documentation of the date_popup_elements function was appended with the following. This gives a good overview of the things the patch adds:

 * #date_date_min
 *   The minimum selectable date. Give a timestamp or string
 *   that is parseable by strtotime.
 *
 * #date_date_max
 *   The maximum selectable date. Give a timestamp or string
 *   that is parseable by strtotime.
 *
 * #date_weekday_disable
 *   Unselectable weekdays. Give an array of integers, where 0 is
 *   Sunday, 1 is Monday, etc.
 *
 * #date_day_disable
 *   Unselectable days. Give an array of timestamps or strings
 *   that are parseable by strtotime.
 * 
 * #date_datepicker_attributes
 *   Additional ui.datepicker attributes can be supplied in this 
 *   attribute. See http://docs.jquery.com/UI/Datepicker
 *   Example:
 *     array('changeFirstDay' => FALSE)

I have also added server-side validation for these values, so even submitting the form with invalid values is not possible. Also, I've updated the javascript and CSS files to the latest jQuery UI 1.6 versions, because the supplied files are too old: the appearance is much better with the new files.

I have not tested all aspects fully, I hope people wanting these features test this patch. It was created using the latest version of the 6.x-2.x branch. I specifically refer to issues #335933: Easy way to make days unselectable and #510464: more control over settings.

The work in this patch is not entirely finished, but I think it's a good start to begin enhancing this submodule.

Comments

eliosh’s picture

+1 for this solution

Jorrit’s picture

StatusFileSize
new141.43 KB

Small update for IE

aaustin’s picture

Thanks a million for taking this on!

I tried it with this as my form field:

$form['datepicker'] = array(
    '#type' => 'date_popup',
    '#title' => 'Date Needed',
    '#date_weekday_disable' => array(0,1,2),
    '#date_date_min' => time(),
    '#date_date_max' => time() + 60*60*24*12,
    '#date_day_disable' => array(time() + 60*60*24*9, time() + 60*60*24*10),
    );

The #date_date_min and #date_date_max worked like a charm but nothing the #date_weekday_disable and #date_day_disable did nothing for me?

I am going to reinstall date module and reapply the patch to be sure.

If this works, it will be so incredibly helpful!

aaustin’s picture

Reapplied the patch again. Tried changing to generic zen theme. Nothing seems to work.

Do you want me to try something else?

Just let me know.

Jorrit’s picture

The day disable part is not very refined: the timestamps must match exactly in PHP and in Javascript. Why weekday disable doesn't work I don't know. Are you able to submit invalid dates? The PHP part also does validation.

aaustin’s picture

I can confirm that the PHP validation is working for day disable and weekday disable.

I can also confirm that everything, including the javascript pop up, works on a new plain vanilla Drupal installation for me.

I had previously tested this with an existing site configuration of a production site that had a lot of other modules installed.

I am looking in to what is breaking it on my existing site. Drupal and all the contrib modules seem to be up to date, but I am looking at it trying to see if is just a bad piece of custom code or if there is another contrib module and/or theme conflicting with the patch.

aaustin’s picture

I must have run the patch wrong? When I copied the date module over from the new Drupal install that was working, and replaced the whole date module on the regular site; everything worked. I have don't know why originally, some stuff seemed to work but not others, but I'm not complaining.

Sorry for the confusion. Great patch!

This is really awesome! I'm going to start moving forward with it.

Is there anything else I can do?

Alex Andrascu’s picture

Great improvment done. If you have better knowledge of FAPI and Date Api maybe we can join forces to add this feature too #613614: User-friendly multiple date selection.

Jorrit’s picture

I made this patch because I needed the functionality and saw an opportunity to add it quite easily. I do not need the mentioned functionality at this point, so I will not work on that issue.

I shared the patch because I wanted to help other people and when it's committed to the main source, I don't have to maintain a separate patch myself. However, I will not provide support for the patch because I don't have time to do so. I expect people who try out the patch to fix bugs they find themselves and share the improvements here.

j0rd’s picture

Also, I've updated the javascript and CSS files to the latest jQuery UI 1.6 versions, because the supplied files are too old: the appearance is much better with the new files.

This is not required as date will use the jquery_ui's datepicker if you have that module enabled and the latest jquery.ui lib installed. Also the jQuery UI version you have added is not minified and results in far much more code to get downloaded.

As for the patch, thank you. I need this support myself.

For those of us who use date_popup in CCK, it will be required that we can configure this when we edit a field. Could that functionality get added.

Thanks again for your work.
Jordan

nicolash’s picture

subscribe

Durrok’s picture

Jorrit - Found a bug in your code that is causing the weekend and day disable not to work.

Your jquery.inArray has it's variables reversed... it should be needle, haystack instead of haystack, needle.

So change:

var dayDisabled = jQuery.inArray(settings.dayDisable, date.getTime() / 1000) != -1;
var weekdayDisabled = jQuery.inArray(settings.weekdayDisable, date.getDay()) != -1;

to

var dayDisabled = jQuery.inArray(date.getTime() / 1000, settings.dayDisable) != -1;
var weekdayDisabled = jQuery.inArray(date.getDay(), settings.weekdayDisable) != -1;

and now it works great! Thanks for all your work!

robby.smith’s picture

subscribing

netourish’s picture

Title: Improvements to date_popup module » Implemtented the above provided patch and it worked fine. But, I have 2 issues in my part.
Assigned: Jorrit » Unassigned
Category: task » feature
Priority: Normal » Critical

Hi Jorrit,
I have implemented the above provided patch and it is really awesome. I was wondering that how can I manage some of the settings, which are not in the original date_popup module. Then after a long search I came across this post and once again I am very thankful to you.

I have one more issue in my part.

My requirement is :- There is a date_popup field which takes the date of birth of a person during registration. I needed the validation that the person's age cannot be less than 15 years. Which I have achieved with the help of this going throug this post and applying the patch. But, the default_value in the date_popup field is not getting populated. I want to populate the default value as the date before 15 years.

Code:-

$form['account']['dob'] = array(
'#type' => 'date_popup',
'#title' => t('Date of birth'),
'#date_format' => 'm-d-Y',
'#default_value' => strftime('%m-%d-%Y',strtotime('-15 years')),
'#date_year_range' => '-100:-15',
'#date_date_max' => strtotime("-15 years"),
'#description' => t('Select date of birth'),
'#required' => TRUE,
'#element_validate' => array('user_register_extra_fields_validate'),
'#attributes' => array('readonly' => 'readonly',
'autocomplete' => 'off',
),
);

Just, now I realized that when I provide the format as 'Y-m-d' it is working fine but, I require date to be in the month-day-Year format.

Second issue :-

On changing the year in the year drop down the dates are shifting towards right side and sometimes they are out of the div, it is happening until any date is selected once any date has been selected this issue is not remaining, and also this issue is happening in the Garland theme but in Chameleon theme this issue is not there.

I am sorry if I have confused you, because believe me I am very very new to drupal world and this beautiful family.

Any or all help will be greatly appreciated.
Thank you,
Pradeep.

netourish’s picture

Title: Implemtented the above provided patch and it worked fine. But, I have 2 issues in my part. » The first issue has been solved.

On hit and tiral method I kept on changing the formats in date_format and in the defualt_date and at one instance I got the right hit. I am really not getting the words to explain it.

I hope the below code will somewhat understandable.

Code :-
$form['account']['dob'] = array(
'#type' => 'date_popup',
'#title' => t('Date of birth'),
'#date_format' => 'm-d-Y',
'#default_value' => strftime('%Y-%m-%d',strtotime('-15 years')),//$edit['dob'],
'#date_year_range' => '-100:-15',
'#date_date_max' => strtotime("-15 years"),
'#description' => t('Select date of birth'),
'#required' => TRUE,
'#element_validate' => array('user_register_extra_fields_validate'),
'#attributes' => array('readonly' => 'readonly',
'autocomplete' => 'off',
),
);
In the date_format I have provided the format 'm-d-Y' and in the default_value I am extracting the date in the format of 'Y-m-d'. I do not know the logic behind it but it worked for me.

Thank you,
Pradeep

asimmonds’s picture

Title: The first issue has been solved. » Improvements to date_popup module
Priority: Critical » Normal

Fixing issue title and priority

arlinsandbulte’s picture

Status: Needs review » Needs work

@Jorrit
This patch contains changes for at least 2 different issues (adding configuration options & css changes), making the patch overly big, complex, and very difficult to review.

Please split the various issues into separate issues for review.

Also, the configuration option changes appear to be very similar to #510464: more control over settings... one of these issues should be a duplicate of the other.... which one would be best to proceed with?

Thanks

uccio’s picture

any news?

Jorrit’s picture

I have not been able to find time to improve the patch. If anyone else has, please feel free to step in.

Jorrit’s picture

StatusFileSize
new2.79 KB
new6.29 KB
new19.03 KB

I have updated my patches to the latest DRUPAL-6--2 branch version and separated the CSS changes from the code changes. There is one small CSS change in the code patch for some extra margin after the calendar image.

I have also attached the test module that I use to test the various date_popup controls.

karens’s picture

Status: Needs work » Postponed (maintainer needs more info)

Another issue, #510464: more control over settings, addresses the same idea and we need to have a single issue with a single patch. I can't do anything at all until we have a single issue with a single patch. One of these has to be marked a duplicate and everyone needs to work on the other until we have a patch that everyone agrees will work.

arlinsandbulte’s picture

Bump,
Can someone look into KarenS's comments in #21?

Jorrit’s picture

StatusFileSize
new9.5 KB

I have updated the patch date-improvements.patch to the current Git version of date. I have also incorporated the patch from #510464: more control over settings comment #23 with the following change: instead of using key #datepicker_settings, I use #date_datepicker_settings, which is more in line with the attribute naming scheme of the date module.

googletorp’s picture

Status: Postponed (maintainer needs more info) » Needs work

We only have a single issue now which is great. One thing missing from #510464: more control over settings though which is the ability to override and add any setting wanted:

Right now the patch is doing:

  $settings = array(...

What I would like to do, which was the key in patch #23 which was an updated version of patch #13 is this (from the issue mentioned above):

  $element_settings = is_array($element['#datepicker_settings']) ? $element['#datepicker_settings'] : array();
  $settings = $element_settings + array(...

This allows developers to override the default values provided by the date module.

Jorrit’s picture

I append the values to $settings later on. In that way, you can override all values. If I'm not mistaken, if you do it like you propose the second array will override the first one.

Your patch:

$settings = $theoverrides + $thedefaults;

My patch:

$settings = $thedefaults;

foreach($theoverrides as $k=>$v) {
$settings[$k] = $v;
}

Or am I missing something?

lperalta’s picture

You are missing that in

$settings = $theoverrides + $thedefaults;

The + operator appends elements of remaining keys from $thedefaults to $theoverrides, whereas duplicated keys are NOT overwritten.

That way, you are allowed to:

a) add more settings
b) replace default settings
c) and keep using default untouched settings, keeping the module original functionality.

in a more elegant way than a foreach. (don't know about which has the best performance).

That said, i still prefer the code at:

<?php
  $element_settings = is_array($element['#datepicker_settings']) ? $element['#datepicker_settings'] : array();
  $settings = $element_settings + array(...
?>
Jorrit’s picture

I still don't understand you. Do you want #datepicker_settings to override the defaults or not?

Because here the overrides are overriden by the defaults:

$settings = $theoverrides + $thedefaults;

I think what you want is:

$settings = $thedefaults + $theoverrides;
googletorp’s picture

Jorrit, I think you need to brush up your php ;)

Example:

$arr1 = array(1 => 2, 4 => 6);
$arr2 = array(3 => 6, 4 => 10);
$arr1 + $arr2 == array(1 => 2, 3 => 6, 4 => 6); // TRUE
$arr2 + $arr1 == array(1 => 2, 3 => 6, 4 => 10); // TRUE

When doing array + array all of the first array values will be kept and all the new ones in the second array will be added

So the code

$settings = $element_settings + array(...

is what I would like which would allow to add any option to the settings array.

Jorrit’s picture

You're right, I always assumed that existing keys would be overwritten, but with the + operator they are kept. Luckily, I don't use the + operator for arrays most of the times :)

It is good to know that we both want to achieve the same thing. In think our code is interchangeable, so your version is fine with me as well.

sydneyshan’s picture

Great to see movement on this concept! Well done guys (and gals)!

I'm curious to know how far away from being committed to a dev version you think this is...

I'd like to start using it, but my git/diff knowledge is not up to speed yet to jump on board.

[update]
I've worked out diff ;-) "patch -p0 < date-improvements-625264-23.diff" worked a treat on Mac OS X.

I've tested this on an internal D6 website (our intranet). Results:

It seems the 'Today' button doesn't work (switches to the current month, but nothing more). Is this functionality working normally, or has this patch broken this...?

I tried applying this to a 'date_combo' form element #type (ie day + time) however it did not appear. Changing the #type to 'date_popup' worked, but I lost the time input facility.

Is there much work involved in ensuring the time input is maintained so that 'date_combo' form element #types can be used with this fantastic patch?

skizzo’s picture

subscribing

aaron.ferris’s picture

Sub

mlyno’s picture

Is there something similar for D7? Some settings to control the clickable dates in the popup. For example to disable the weekends or whatever pre-defined dates.
something like this
thanks

aether’s picture

For anyone trying to get the patch in #23 working with D6 CCK, for now you can modify the datepicker via a form API #after_build function for the node form.

<?php
/**
 * Implementation of hook_form_alter() specific to mynode_node_form.
 */
function mymodule_form_mynode_node_form_alter(&$form, &$form_state) {
  $form['#after_build'][] = 'mymodule_mynode_node_form_after_build';
}

/**
 * After build handler for mynode_node_form.
 */
function mymodule_mynode_node_form_after_build($form, &$form_state) {
  $today = mktime(0, 0, 0, date('n'), date('j'));
  
  // Additional properties for the datepicker.
  $form['field_mydatefield'][0]['value']['#date_date_min'] = $today - 604800; // -1 week
  $form['field_mydatefield'][0]['value']['#date_date_max'] = $today + 31536000; // +1 year
  $form['field_mydatefield'][0]['value']['#date_datepicker_settings'] = array(
    'showOn' => 'focus',
    'gotoCurrent' => TRUE,
  );
  
  // We must run the date popup element back through date_popup_process()
  // to pick up and apply our changes.
  $element = $form['field_mydatefield'][0]['value'];
  $form['field_mydatefield'][0]['value'] = date_popup_process($element);
  
  return $form;
}
?>
karens’s picture

Status: Needs work » Postponed (maintainer needs more info)

Would the patch at #1143680: Add selector to date_popup element to allow additional options to be passed to jQuery datepicker be sufficient? That seems like the most general fix. If that will do what is needed, add a D6 backport to that issue and let's close this issue.

karens’s picture

Status: Postponed (maintainer needs more info) » Closed (duplicate)

I committed #1143680: Add selector to date_popup element to allow additional options to be passed to jQuery datepicker for D7 and marked it for backport to D6. Closing this issue as a duplicate.

Jorrit’s picture

StatusFileSize
new9.67 KB

Rebased 23 on the d6 lts version.