Playbook's date picker is built using flatpickr, a vanilla js library. Common date picker use cases and features have been adapted into simple prop based configuration detailed in the docs below. You can implement additional features and functionality by accessing a flatpickr instance directly (demonstrated in the 'flatpickr methods' example below). This is done with the following code.
const fpInstance = document.querySelector('#pickerId')._flatpickr
pickerId
is a prop passed to the date picker kit. Flatpickr uses this id to target an input and attach a flatpickr instance to that input.
To learn more visit flatpickr's docs or see the hook doc section below for an applied example.
The Date Picker works best with Javascript Date Objects or ISO Date strings. If you're programming in js use Date Objects. If you're using rails convert your date object (with timezone) to UTC and then to an ISO Date string. For example, DateTime.now.utc.iso8601
. This ensures that the string passed to the Date Picker kit behaves as expected.
<%= pb_rails("date_picker", props: { hide_icon: true, picker_id: "date-picker-hide-icon" }) %>
The defaultDate
/default_date
prop has a null or empty string value by default. You can pass an ISO date string (preferred rails method) or date object (preferred JS method) if you want a default value on page load. Use Ruby UTC DateTime objects and convert them to ISO date strings with DateTime.now.utc.iso8601
.
If you use a Date object without UTC time standardization the Date Picker kit may misinterpret that date as yesterdays date (consequence of timezone differentials and the Javascript Date Object constructor). See this GitHub issue for more information and the anti-pattern examples below.
<%= pb_rails("date_picker", props: { default_date: "07/25/2020", label: "Default Date String", picker_id: "date-picker-default-date1" }) %> <%= pb_rails("date_picker", props: { default_date: DateTime.current.utc.iso8601, label: "Default Date Dynamic", picker_id: "date-picker-default-date2" }) %> <%= pb_rails("date_picker", props: { default_date: [DateTime.current.utc.iso8601, (DateTime.current + 7.day).utc.iso8601], label: "Default Date Range", mode: "range", picker_id: "date-picker-default-date3" }) %> <%= pb_rails("date_picker", props: { label: "Default Behavior", picker_id: "date-picker-default-date4" }) %>
The date picker is built with the text input kit. Text input props you pass to the date picker kit will be forwarded to the input, with a few exceptions. The value
attribute is automatically handled and bound to whatever date string is contained by the input field. You cannot pass a custom value prop. id
props passed to the date picker kit will be assigned to it's parent/wrapper div. The pickerId
prop is passed directly to the input and is required to instatiate the date picker.
You must use inputAria
or input_aria
and inputData
or input_data
props if you wish to pass data or aria attributes to the text input kit. If you use data
or aria
props they will be passed to the date picker kit itself instead. Also be aware the default behavior of text input aria and data props is to pass those props to attributes on the wrapping div not on the input itself.
The placeholder prop has a default string value: "Select Date". You can replace this with your own string or an empty string if you'd prefer it blank.
<%= pb_rails("date_picker", props: { input_aria: { label: "input-field" }, input_data: { key: "value", key2: "value2" }, label: "Aria, Name, and Data Attributes", name: "date-field", picker_id: "date-picker-input1", }) %> <%= pb_rails("date_picker", props: { label: "Custom Placeholder", picker_id: "date-picker-input2", placeholder: "custom-placeholder", }) %> <%= pb_rails("date_picker", props: { label: "Blank Placeholder", picker_id: "date-picker-input3", placeholder: "" }) %> <%= pb_rails("date_picker", props: { disable_input: true, label: "Disable Input", picker_id: "date-picker-input4", placeholder: "Disabled Input" }) %>
Default label prop is "Date Picker"
. To remove the label set the hideLabel
prop in React or the hide_label
prop in Rails to true
.
<%= pb_rails("date_picker", props: { label: "Your Label Here", picker_id: "date-picker-label" }) %> <%= pb_rails("date_picker", props: { hide_label: true, picker_id: "date-picker-hide-label" }) %>
<%= pb_rails("date_picker", props: { default_date: [DateTime.current.utc.iso8601, (DateTime.current + 7.day).utc.iso8601], mode: "range", picker_id: "date-picker-range" }) %>
A full list of formatting tokens, i.e. "m/d/Y"
can be found here.
<%= pb_rails("date_picker", props: { default_date: DateTime.current.utc.iso8601, format: "m-d-Y", picker_id: "date-picker-format1" }) %> <%= pb_rails("date_picker", props: { default_date: DateTime.current.utc.iso8601, format: "m/d/y", picker_id: "date-picker-format2" }) %> <%= pb_rails("date_picker", props: { default_date: DateTime.current.utc.iso8601, format: "n-j-y", picker_id: "date-picker-format3" }) %> <%= pb_rails("date_picker", props: { default_date: DateTime.current.utc.iso8601, format: "Y-d-m", picker_id: "date-picker-format4" }) %>
<%= pb_rails("date_picker", props: { disable_date: [(DateTime.current + 1.day).utc.iso8601], label: "Disable Single Date", picker_id: "single-disabled-date" }) %> <%= pb_rails("date_picker", props: { disable_date: [(DateTime.current + 1.day).utc.iso8601, (DateTime.current + 2.day).utc.iso8601], label: "Disable Multiple Dates", picker_id: "multiple-disabled-dates" }) %> <%= pb_rails("date_picker", props: { disable_range: [ { from: DateTime.current.utc.iso8601, to: (DateTime.current + 7.day).utc.iso8601, }, ], label: "Disable Single Range", picker_id: "single-date-range" }) %> <%= pb_rails("date_picker", props: { disable_range: [ { from: (DateTime.current + 1.day).utc.iso8601, to: (DateTime.current + 2.day).utc.iso8601, }, { from: (DateTime.current + 7.day).utc.iso8601, to: (DateTime.current + 14.day).utc.iso8601, }, ], label: "Disable Multiple Ranges", picker_id: "multiple-date-ranges" }) %> <%= pb_rails("date_picker", props: { disable_weekdays: ['Sunday', 'Saturday'], label: "Disable Specific Weekdays", picker_id: "disabled-weekdays" }) %>
<%= pb_rails("date_picker", props: { label: "Dynamic dates", max_date: (DateTime.current + 1.day).utc.iso8601, min_date: (DateTime.current - 1.day).utc.iso8601, picker_id: "date-picker-min-max1" }) %> <%= pb_rails("date_picker", props: { format: "m/d/Y", label: "Absolute formatted dates", max_date: "10/20/2020", min_date: "10/10/2020", picker_id: "date-picker-min-max2" }) %>
<%= pb_rails("date_picker", props: { error: "Invalid date. Please pick a valid date.", picker_id: "date-picker-error" }) %>
<%= pb_rails("button", props: { id: "close-btn", margin_right: "sm", text: "Close" }) %> <%= pb_rails("button", props: { id: "clear-btn", margin_right: "sm", text: "Clear" }) %> <%= pb_rails("button", props: { id: "today-btn", text: "Today" }) %> <%= pb_rails("date_picker", props: { hide_label: true, margin_top: "sm", picker_id: "fp-methods" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { const fp = document.querySelector("#fp-methods")._flatpickr const closeBtn = document.querySelector("#close-btn") const clearBtn = document.querySelector("#clear-btn") const todayBtn = document.querySelector("#today-btn") closeBtn.addEventListener("click", () => { fp.close() }) clearBtn.addEventListener("click", () => { fp.clear() }) todayBtn.addEventListener("click", () => { fp.setDate(new Date(), true) }) }) <% end %>
You can find a full list of flatpickr events and hooks in their documentation.
<%= pb_rails("date_picker", props: { label: "onChange", picker_id: "date-picker-hooks-onchange" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { <%# Access flatpickr instance with picker id and assign it a variable %> const fp = document.querySelector("#date-picker-hooks-onchange")._flatpickr <%# Define Hook %> const changeHook = () => { alert('date changed') } <%# Push one or more hooks to onChange config array %> fp.config.onChange.push(changeHook) }) <% end %> <%= pb_rails("date_picker", props: { label: "onOpen", picker_id: "date-picker-hooks-onopen" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { <%# Access flatpickr instance with picker id and assign it a variable %> const fp = document.querySelector("#date-picker-hooks-onopen")._flatpickr <%# Define Hook %> const openHook = () => { alert('calendar opened') } <%# Push one or more hooks to onOpen config array %> fp.config.onOpen.push(openHook) }) <% end %>
Defaults to [1900, 2100]
. Combine with min-max prop for best results.
<%= pb_rails("date_picker", props: { default_date: "05/05/2015", max_date: "12/31/2018", min_date: "01/01/2015", picker_id: "date-picker-year-range", year_range: [2015, 2018] }) %>
<%= pb_rails("date_picker", props: { label: "Unformatted Date Object", default_date: Date.today, picker_id: "date-picker-anti-pattern1" }) %> <%= pb_rails("date_picker", props: { label: "Date Object Without Time - Displays Yesterday's Date", default_date: Date.today.to_datetime.utc.iso8601, picker_id: "date-picker-anti-pattern2" }) %> <%= pb_rails("date_picker", props: { label: "Unformatted DateTime Object", default_date: DateTime.current, picker_id: "date-picker-anti-pattern3" }) %> <%= pb_rails("date_picker", props: { label: "String Conversion Without ISO Formatting", default_date: DateTime.current.utc.to_s, picker_id: "date-picker-anti-pattern5" }) %>
<%= pb_rails("date_picker", props: { classname: "inline-date-picker", hide_icon: true, inline: true, picker_id: "date-picker-inline" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", (event) => { const fpInline = document.querySelector("#date-picker-inline")._flatpickr <!-- Display the angle-down icon when a date has been selected --> const showAngleDownHandler = () => { document.querySelector('.inline-date-picker').classList.add('show-angle-down-icon') } fpInline.config.onChange.push(showAngleDownHandler) }) <% end %>
By default selectType prop is disabled. To activate it set selectionType
prop in JSX/TSX to month
. To activate it set selection_type
prop in a rails file to month
.
<%= pb_rails("date_picker", props: { label: "Date Picker", picker_id: "disabled_date", selection_type: "month" }) %>
By default selectType prop is disabled. To activate it set selectionType
prop in JSX/TSX to week
. To activate it set selection_type
prop in a rails file to week
.
<%= pb_rails("date_picker", props: { label: "Date Picker", picker_id: "week_date_picker", selection_type: "week" }) %>
To select time as well, you should pass the enableTime
boolean prop. You can also enable timezone display by passing showTimezone
.
<%= pb_rails("date_picker", props: { default_date: DateTime.now.utc.iso8601, picker_id: "date-picker-time", enable_time: true, show_timezone: true }) %>