Date Picker (datepicker)

As of CoreJs 9.5.0 we have a new date picker field type: 'datepicker'.

This new implementation is preferred over 'datetimepicker'. The new date picker is a forked implementation of ab-datepicker-2.1.17 for more information please see the github page of ab-datepicker

Please be aware that the original ab-datepicker doesn't use moment but it uses the JavaScript Date object in it's backend. Using Date() directly can sometimes cause timezone issues. 

The main object to represent a date in for the forked version is moment.

But since ab-datepicker uses the Date object I use the toDate() function of moment for many of the internal ab-datepicker logic such as the UI for building the calendars. 

This date picker has been tested to support the "YYYY-MM-DD" date format if we need to support additional formats please request them to the CoreJs development team. 

Usage Information

  1. In package.json set "includeDatePicker": true,
  2. Inside a CoT From deffination you can specify the JSON object for a file of type "datepicker"

Examples

Example 1: Minimum Options 

{
  "type": "datepicker",
  "id": "example_one_part_1",
  "title": "Minimum Configuration Date Picker Example",
  "bindTo": "example_one_part_1"
}

Example 2: Defaults Example (same as example 1 but it shows the defaults added by CoT Form)

{
  "type": "datepicker",
  "id": "example_one_part_2",
  "title": "CoT Form Defaults shown",
  "bindTo": "example_one_part_2",
  "options": {
    "firstDayOfWeek": 1,
    "gainFocusOnConstruction": false,
    "weekDayFormat": "narrow",
    "inputFormat": [
      "yyyy-MM-dd"
    ],
    "outputFormat": "yyyy-MM-dd",
    "titleFormat": "EEEE d MMMM y",
    "placeholder": "yyyy-MM-dd",
    "theme": "bootstrap",
    "modal": true,
    "expectedDateFormat": "YYYY-MM-DD",
    "momentValidationFormat": "YYYY-MM-DD",
    "overlayParentElement": "body"
  }
}



Example 3: Advanced Example

{
  "type": "datepicker",
  "id": "advancedDatepickerExample",
  "title": "Advanced Date Picker Example",
  "bindTo": "advancedDatepickerExample",
  "required": true,
  "prehelptext": "Now enter a date!",
  "requiredMessage": "You must enter a date it is required!",
  "infohelp": "This is an infohelp field, do you need help with something?",
  "placeholder": "1900-01-01",
  "posthelptext": "An example of a date picker field",
  "options": {
    "theme": "customThemeExample",
    "daysOfWeekDisabled": [
      0,
      6
    ],
    "datesDisabled": [
      "2020-08-02",
      "2020-08-05"
    ],
    "min": "2020-07-31",
    "max": "2020-08-31",
    "messages": {
      "max": "USER_ENTERED_DATE_VALUE is greater than MAX_DATE_VALUE",
      "min": "USER_ENTERED_DATE_VALUE is less than MIN_DATE_VALUE",
      "invalid_date": "\"USER_ENTERED_DATE_VALUE\" is not a valid date please enter a valid date",
      "empty": "",
      "invalid_selection": "USER_ENTERED_DATE_VALUE is a valid date but USER_ENTERED_DATE_VALUE can not be selected!"
    }
  }
}

Setting the Default Date Value

If you need to set the default date value one you can do this is by setting the value in your CotModel to key that binds to your date property.
So, if you date is defined as:

{
  "type": "datepicker",
  "id": "example_one_part_1",
  "title": "Minimum Configuration Date Picker Example",
  "bindTo": "example_one_part_1"
}

In your CotModel set the value of example_one_part_1 to the default date value. 


More Example:
Please see:
https://webapps.intra.qa-toronto.ca/webapps/corejs/showcase/#showcase_testDatePickerForm

Options

Please see: https://github.com/eureka2/ab-datepicker for documentation from original plugin author. 

Below are some important options that might be used most of the times or you need to be aware of for development. 


OptionDefault ValueDescription
options.expectedDateFormat"YYYY-MM-DD"

The expected date format value that will be displayed during the validation screen. This is only used to display validation issues to the user. 

Recommendation is to keep the default and not change the date format. 

options.momentValidationFormat"YYYY-MM-DD"MomentJs is used to validate a date. It will try to parse the date that has been entered to the given format.
Recommendation is to keep the default and not change the date format. 
options.inputFormat["yyyy-MM-dd"]How ab-datepicker should allow the user to input a date, ab-datepicker support many formats we haven't tested all of them. 
Recommendation is not change this but if you are going to be changing this then please to an end to end test. Change this will have an implication for the momentValidationFormat option. 
options.outputFormatyyyy-MM-ddHow we want ab-datepicker to output the user selected date as.
options.startingDatecurrent date using this code to get the date:
new moment().format("YYYY-MM-DD")
Allows you to set the starting date for the date picker calendar UI. Please provide the date as a string "YYYY-MM-DD" you can do that using new moment().format("YYYY-MM-DD"). The reason why we need the date as a string is because ab-datepicker has it's own parseDate function. 

Usage Example
To have your date picker start in 1955.
options: {
startingDate: new moment("1955-01-01").format("YYYY-MM-DD"),
}
options.titleFormat"EEEE d MMMM y"Used to configure how the date is displayed on the ab-datepicker calendar. Please see the ab-datepicker documentation for details. 
placeholder"yyyy-MM-dd"What placeholder text should be displayed. 
options.modaltrueShows the date picker in a modal. You don't want to change this setting in most cases. If you are facing issues with modal view and the calendar is behind the overlay then please see the overlayParentElement option.
options.theme
"bootstrap"
The CSS theme you want to use please see the showcase example for details on how to use it option. 
options.firstDayOfWeek1The first day of the week with 1 being Monday.
options.gainFocusOnConstructionfalseIf you set this to thru the datepicker will get focus with it is added to the UI. In most cases you don't want to set this to true.
options.weekDayFormat"narrow"controls how the weekdays are displayed on the calendar UI.
options.overlayParentElement"body"The DOM element on which the overlay will be inserted. This value will change automatically for stand alone and embedded apps. In most cases developer will not need to modify this value or just go with the default. You might need to change it if you are noticing the z-index on your page isn't working correctly. 
options.maxThere is no default.If the user entered dates is equal to or less then the max then that date is valid. The max date is specified as a string in this format "YYYY-MM-DD".
options.minThere is no default.If the user entered dates is equal to or greater then the min then that date is valid. The min date is specified as a string in this format "YYYY-MM-DD".
options.datesDisabledThere is no default.You can disable specific dates just specify them in the array in this format: "YYYY-MM-DD". Example: "datesDisabled": [ "2020-08-02", "2020-08-05" ]
options.daysOfWeekDisabledThere is no default.There is no default for this field. You can turn this setting on to disable certain days of the week. 0 is Sunday, 6 is Saturday.
options.messagesThere is no default.

A JSON object which contains the error messages you can customaize and show to the user.

message.max is displayed when a date user has entered doesn't meet the max condition.
message.min is displayed when a date user has entered doesn't meet the min condition.
message.invalid_date is displayed when a value the user has entered isn't a valid date
message.empty is displayed when a value the user has entered is "blank"/"empty" if you leave this property empty then no message will be displayed. 
message.invalid_selection is displayed when a user types a date but the date they have typed isn't a valid section.

Example of options.messages
    {
      "max": "USER_ENTERED_DATE_VALUE is greater than MAX_DATE_VALUE",
      "min": "USER_ENTERED_DATE_VALUE is less than MIN_DATE_VALUE",
      "invalid_date": "\"USER_ENTERED_DATE_VALUE\" is not a valid date please enter a valid date",
      "empty": "",
      "invalid_selection": "USER_ENTERED_DATE_VALUE is a valid date but USER_ENTERED_DATE_VALUE can not be selected!"
    }

All of these messages have string values that are replaced by a dynamic value during run time.
USER_ENTERED_DATE_VALUE is replaced with the date the user has entered int he date picker.

MAX_DATE_VALUE is replaced with the max date set in the options.

MIN_DATE_VALUE is replaced with the min date set in the options.

options.bindAsISO8601datefalseTry to convert the date to a ISO 8601 date string and set it in the model. This has not been fully tested.
options.bindAsMomentDateObjfalseTry to convert the date to a moment date object and set it in the model. This has not been fully tested.
default binding to model behaviourdefaultBy default the binding will be done by string if the field is empty or only has spaces (.trim()) is empty then null will be used. 

Modify the Options After Rendering

All options are set during rendering time of the CotForm if you need to change that please consider this:
Use the ID of your date picker to get access to the date picker object. 

let abDatepickerObj = $("#example_one_part_1").data("ab.datepicker");

Access the options and change them as required, you might need to test this for different options types since some of them get changed from string type to objects. 

abDatepickerObj.options.max = new Date("2021-09-24")


Implementation Notes

If you are running into issues related to overlay that is displayed when the calender open look in to this property:
options.overlayParentElement

Date Related Standards

Date Format

If you want to read date related standards please go to: Date / Time

Accessibility

Accessible Calendar / Date Picker Widgets Test Cases

Below are some of the test cases that were used to test this date picker these test cases are from: http://whatsock.com/bootstrap/. Click on the bootstrap button. 

Test CasesTest Result
  • When the calendar is opened, focus is set on the current date.

  • Press the LEFT and RIGHT arrow keys to navigate the row by week day.

  • Press the HOME and END keys to jump to the beginning or end of the current row.

  • Press the UP and DOWN arrow keys to navigate between weeks on the same week day.

  • Press the PAGEDOWN and PAGEUP keys to navigate backwards or forwards by month.
Needs Review, when we have limited the date range
  • Press ALT+PAGEDOWN and ALT+PAGEUP to navigate backwards or forwards by year.
Needs Review, when we have limited the date range
  • Press the ENTER key to activate the selected date.

  • Press ESCAPE to close the calendar without making a selection.

  • Mouse users can click the desired date buttons as usual.

Advanced Information for CoreJs Maintainers 

Making changes to the (ab-datepicker) in CoreJs

If you need to upgrade the ab-datepicker here are the instructions for CoreJs:

Note not all changes are documented but this should help if you reviewing the code.

src/forked_libs/ab-datepicker-2.1.17/js/datepicker.js

Modified:
Datepicker.prototype.greyOut - some overlay logic
datepickerButton3 - changed how the aria-labelledby is defined
Added: This was added to make the validation logic work
Datepicker.prototype.getDateFieldValidation
Datepicker.prototype.setDateFieldValidation
Modified:
Datepicker.prototype.initializeDate - to allow the user to specify a starting date for the calender 
Datepicker.prototype.setDate - sets the data and

Modified: a lot of places were a new Date() or any Date object was being created was changed to use moment. We continue to use new moment().toDate() to get a date object.

/src/forked_libs/ab-datepicker-2.1.17/css/datepicker_customizations.css

Contains some custom CSS to meet our requirements