UNPKG

bootstrap-vue

Version:

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens

695 lines (563 loc) 24 kB
# Form Datepicker > `<b-form-datepicker>` is a BootstrapVue custom date picker input form control, which provides full > WAI-ARIA compliance and internationalization support. ## Overview As a form control wrapper component for the [`<b-calendar>`](/docs/components/calendar) component, it provides additional validation state presentation and a compact interface. Native HTML5 date inputs vary in presentation, accessibility, and in some instances are not supported by all browsers. `<b-form-datepicker>` provides a consistent and accessible interface across all browser platforms and devices. ```html <template> <div> <label for="example-datepicker">Choose a date</label> <b-form-datepicker id="example-datepicker" v-model="value" class="mb-2"></b-form-datepicker> <p>Value: '{{ value }}'</p> </div> </template> <script> export default { data() { return { value: '' } } } </script> <!-- b-form-datepicker.vue --> ``` `<b-form-datepicker>` supports many of the props available on [`<b-calendar>`](/docs/components/calendar) as well as some of the props available on [`<b-dropdown>`](/docs/components/dropdown). ## `v-model` return value By default, `<b-form-datepicker>` returns dates as a string in the `YYYY-MM-DD` format, which is the same format returned by native browser `<input type="date">` controls. You can have `<b-form-datepicker>` return a `Date` object (with no time portion) as the `v-model` value instead by setting the `value-as-date` prop. If no date is selected, `<b-form-datepicker>` returns an empty string `''`, or returns `null` if the `value-as-date` prop is set. Note that when `value-as-date` prop is set, the returned `Date` object will be in the browser's default timezone. If `<b-form-datepicker>` has a value set for the `name` prop, a hidden input will be created which will have its name attribute set to the value of the `name` prop, and the value attribute will be set to the selected date as a `YYYY-MM-DD` string. This will allow the `<b-form-datepicker>` selected value to be submitted via native browser form submission. ## Disabled and readonly states Setting the `disabled` prop will remove all interactivity of the `<b-form-datepicker>` component. Setting the `readonly` prop will disable selecting a date, but will keep the component interactive, allowing for date navigation. The `v-model` will not be updated in the readonly state. For disabling specific dates or setting minimum and maximum date limits, refer to the [Date constraints](#date-constraints) section. ```html <template> <div> <b-form-group label="Select date picker interactive state" v-slot="{ ariaDescribedby }" > <b-form-radio-group v-model="state" :aria-describedby="ariaDescribedby" aria-controls="ex-disabled-readonly" > <b-form-radio value="disabled">Disabled</b-form-radio> <b-form-radio value="readonly">Readonly</b-form-radio> <b-form-radio value="normal">Normal</b-form-radio> </b-form-radio-group> </b-form-group> <b-form-datepicker id="ex-disabled-readonly" :disabled="disabled" :readonly="readonly" ></b-form-datepicker> </div> </template> <script> export default { data() { return { state: 'disabled' } }, computed: { disabled() { return this.state === 'disabled' }, readonly() { return this.state === 'readonly' } } } </script> <!-- b-form-datepicker-disabled-readonly.vue --> ``` ## Date constraints ### Minimum and maximum dates Restrict the calendar range via the `min` and `max` props. The props accept a date string in the format of `YYYY-MM-DD` or a `Date` object. ```html <template> <div> <b-form-datepicker v-model="value" :min="min" :max="max" locale="en"></b-form-datepicker> </div> </template> <script> export default { data() { const now = new Date() const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()) // 15th two months prior const minDate = new Date(today) minDate.setMonth(minDate.getMonth() - 2) minDate.setDate(15) // 15th in two months const maxDate = new Date(today) maxDate.setMonth(maxDate.getMonth() + 2) maxDate.setDate(15) return { value: '', min: minDate, max: maxDate } } } </script> <!-- b-form-datepicker-min-max.vue --> ``` ### Disabling dates If you need to disable specific dates within the date picker, specify a function reference to the `date-disabled-fn` prop. The function is passed two arguments: - `ymd` The date as a `YYYY-MM-DD` string - `date` The date as a `Date` object The function should either return `true` if the date _cannot_ be selected (disabled), or `false` if the date _can_ be selected (enabled). Note that the function **cannot** be asynchronous, and should return a value as quickly as possible. ```html <template> <div> <b-form-datepicker v-model="value" :date-disabled-fn="dateDisabled" locale="en"></b-form-datepicker> </div> </template> <script> export default { data() { return { value: '' } }, methods: { dateDisabled(ymd, date) { // Disable weekends (Sunday = `0`, Saturday = `6`) and // disable days that fall on the 13th of the month const weekday = date.getDay() const day = date.getDate() // Return `true` if the date should be disabled return weekday === 0 || weekday === 6 || day === 13 } } } </script> <!-- b-form-datepicker-disabled-dates.vue --> ``` Note the `min` and `max` date constraints are evaluated first, before `date-disabled-fn`. ## Validation states `<b-form-datepicker>` supports invalid and valid styling via the boolean `state` prop. Setting `state` to boolean `false` will style the input as invalid, while setting it to boolean `true` will style it as valid. Setting `state` to `null` will not show any validation state styling (the default). ```html <template> <div> <label for="datepicker-invalid">Choose a date (invalid style)</label> <b-form-datepicker id="datepicker-invalid" :state="false" class="mb-2"></b-form-datepicker> <label for="datepicker-valid">Choose a date (valid style)</label> <b-form-datepicker id="datepicker-valid" :state="true"></b-form-datepicker> </div> </template> <!-- b-form-datepicker-invalid-valid.vue --> ``` Note that native browser validation is _not_ available with `<b-form-datepicker>`. ## Styling ### Variants The selected date button (background color) defaults to the `'primary'` theme variant. You can change this to any of the Bootstrap v4 theme variant colors: `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, etc, via the `selected-variant` prop. Today's date will also be highlighted (text color) using the same variant as the selected date by default. To specify a different theme color to use for today's date, use the `today-variant` prop. To disable highlighting of today's date altogether, set the `no-highlight-today` prop. The navigation buttons default to the `'secondary'` theme variant. You can change this via the `nav-button-variant` prop. ### Control sizing Fancy a smaller or larger `<b-form-datepicker>` control? Set the `size` prop to `'sm'` for a smaller form control, or `'lg'` for a larger form form control. Note this does not affect the size of the popup calendar dialog. ```html <template> <div> <label for="datepicker-sm">Small date picker</label> <b-form-datepicker id="datepicker-sm" size="sm" locale="en" class="mb-2"></b-form-datepicker> <label for="datepicker-lg">Large date picker</label> <b-form-datepicker id="datepicker-lg" size="lg" locale="en"></b-form-datepicker> </div> </template> <!-- b-form-datepicker-sizes.vue --> ``` ### Placeholder Add custom placeholder text to the control, when no date is selected, via the `placeholder` prop. If a placeholder is not provided, the value of the `label-no-date-selected` prop is used. ```html <template> <div> <label for="datepicker-placeholder">Date picker with placeholder</label> <b-form-datepicker id="datepicker-placeholder" placeholder="Choose a date" locale="en"></b-form-datepicker> </div> </template> <!-- b-form-datepicker-placeholder.vue --> ``` ### Optional controls Add optional control buttons to the bottom of the calendar popup via the props `today-button`, `reset-button` and `close-button`. - The today button selects today's date - The reset button either clears the selected date, or sets the date to the value of the prop `reset-value` (if provided) - The close button closes the calendar popup By default, clicking on the today or reset button will also close the calendar popup, unless the prop `no-close-on-select` is set. ```html <template> <div> <label for="datepicker-buttons">Date picker with optional footer buttons</label> <b-form-datepicker id="datepicker-buttons" today-button reset-button close-button locale="en" ></b-form-datepicker> </div> </template> <!-- b-form-datepicker-buttons.vue --> ``` The text for the optional buttons can be set via the `label-today-button`, `label-reset-button`, and the `label-close-button` props. Due to the limited width of the footer section, it is recommended to keep these labels short. Note that the `Set Today` button may not set the control today's date, if today's date is outside of the `min` or `max` date range restrictions. In the case it is outside of the range, it will set to either `min` or `max` (depending on which is closes to today's date). ### Dropdown placement Use the dropdown props `right`, `dropup`, `dropright`, `dropleft`, `no-flip`, and `offset` to control the positioning of the popup calendar. Refer to the [`<b-dropdown>` positioning section](/docs/components/dropdown#positioning) for details on the effects and usage of these props. ### Initial open calendar date <span class="badge badge-info small">v2.7.0+</span> By default, when no date is selected, the calendar view will be set to the current month (or the `min` or `max` date if today's date is out of range of `min` or `max`) when opened. You can change this behaviour by specifying a date via the `initial-date` prop. The initial date prop will be used to determine the calendar month to be initially presented to the user. It does not set the component's value. ### Dark mode Want a fancy popup with a dark background instead of a light background? Set the `dark` prop to `true` to enable the dark background. ### Optional decade navigation buttons Set the prop `show-decade-nav` to enable the previous and next decade buttons in the datepicker's date navigation toolbar. The props `label-prev-decade` and `label-next-decade` props can be used to provide custom label text for the decade buttons. For example usage, refer to the [Internationalization section](#internationalization) below. ### Button only mode <span class="badge badge-info small">v2.7.0+</span> Fancy just a button that launches the date picker dialog, or want to provide your own optional text input field? Use the `button-only` prop to render the datepicker as a dropdown button. The formatted date label will be rendered with the class `sr-only` (available only to screen readers). In the following simple example, we are placing the datepicker (button only mode) as an append to a `<b-input-group>`, and we are using the `context` event to get the formatted date string and value: ```html <template> <div> <label for="example-input">Choose a date</label> <b-input-group class="mb-3"> <b-form-input id="example-input" v-model="value" type="text" placeholder="YYYY-MM-DD" autocomplete="off" ></b-form-input> <b-input-group-append> <b-form-datepicker v-model="value" button-only right locale="en-US" aria-controls="example-input" @context="onContext" ></b-form-datepicker> </b-input-group-append> </b-input-group> <p class="mb-1">Value: '{{ value }}'</p> <p class="mb-1">Selected: '{{ selected }}'</p> <p>Formatted: '{{ formatted }}'</p> </div> </template> <script> export default { data() { return { value: '', formatted: '', selected: '' } }, methods: { onContext(ctx) { // The date formatted in the locale, or the `label-no-date-selected` string this.formatted = ctx.selectedFormatted // The following will be an empty string until a valid date is entered this.selected = ctx.selectedYMD } } } </script> <!-- b-form-datepicker-button-only.vue --> ``` Control the size of the button via the `size` prop, and the button variant via the `button-variant` prop. ### Date string format <span class="badge badge-info small">v2.6.0+</span> To change format options of the displayed date text inside the component, e.g. in the header or placeholder, set the `date-format-options` prop to an object containing the requested format properties for the `Intl.DateTimeFormat` object (see also [Internationalization](#internationalization)). ```html <template> <div> <label for="datepicker-dateformat1">Custom date format</label> <b-form-datepicker id="datepicker-dateformat1" :date-format-options="{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'short' }" locale="en" ></b-form-datepicker> <label class="mt-3" for="datepicker-dateformat2">Short date format</label> <b-form-datepicker id="datepicker-dateformat2" :date-format-options="{ year: 'numeric', month: 'numeric', day: 'numeric' }" locale="en" ></b-form-datepicker> </div> </template> <!-- b-form-datepicker-dateformat.vue --> ``` The following table summarizes the valid options for each format property: | Property | Possible values | | --------- | ------------------------------------------------------------ | | `year` | `'numeric'`, or `'2-digit'` | | `month` | `'numeric'`, `'2-digit'`, `'long'`, `'short'`, or `'narrow'` | | `day` | `'numeric'`, or `'2-digit'` | | `weekday` | `'long'`, `'short'`, or `'narrow'` | Notes: - Leaving out certain options may affect the formatted text string, e.g. the `weekday` - The formatted value will vary according to the resolved locale. Some locales may not support the `'narrow'` format and will fall back to `'short'` or `long'` (if `'short'` is not available) - `year`, `month` and `day` will always be shown. If you need to leave out a value, set the property to `undefined`, although this is highly discouraged for accessibility reasons ### Weekday name header format <span class="badge badge-info small">2.12.0+</span> The calendar weekday name header format defaults to `'short'`, which is typically a three-character abbreviation of the weekday, although some [locales](#internationalization) may override this. The format can be controlled via the prop `weekday-header-format` and accepts one of three values: - `'long'` the full weekday name (e.g. <samp>Tuesday</samp>). Handy when using a full width calendar. Avoid using with the default calendar width. - `'short'` typically is a 2 or 3 letter abbreviation of the weekday name, depending on the selected locale (e.g. "Tue"). - `'narrow'` is typically a single character abbreviation (e.g., <samp>T</samp>). Two weekdays may have the same narrow style for some locales (e.g. Tuesday and Thursday's narrow style are both <samp>T</samp>). This can be handy for those locales that do not support the `'short'` format, such as locales `'ar'` and `'fa'`. ### Date navigation button slots <span class="badge badge-info small">2.12.0+</span> To change the content of the calendar's date navigation buttons, BootstrapVue provides scoped slots for each button: - `'nav-prev-decade'` - `'nav-prev-year'` - `'nav-prev-month'` - `'nav-this-month'` (the go to selected/today button) - `'nav-next-month'` - `'nav-next-year'` - `'nav-next-decade'` All seven slots have the same scoped property available: | Property | Type | Description | | -------- | ------- | --------------------------------------------------------------------- | | `isRTL` | Boolean | Will be `true` when the date navigation bar is rendered right-to-left | You can use the `isRTL` scoped property to "flip" the prev vs next button content to handle the left-to-right to right-to-left orientation change &mdash; i.e. the previous year button will be on the right when `isRTL` is `true`, instead of the left. ### Full width calendar dropdown To create a full width calendar dropdown (where the width matches the input width), simply set the `menu-class` prop to `'w-100'` and set the `calendar-width` prop to `'100%'`: ```html <template> <div> <label for="datepicker-full-width">Choose a date</label> <b-form-datepicker id="datepicker-full-width" v-model="value" menu-class="w-100" calendar-width="100%" class="mb-2" ></b-form-datepicker> <p>Value: '{{ value }}'</p> </div> </template> <script> export default { data() { return { value: '' } } } </script> <!-- b-form-datepicker-full-width.vue --> ``` ## Internationalization Internationalization of the date picker's calendar is provided via [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat), except for labels applied to elements of the calendar control (aria-labels, selected status, and help text). You must provide your own translations for these labels. The available locales will be browser dependent (not all browsers support all locales) By default `<b-form-datepicker>` will use the browser's default locale, but you can specify the locale (or locales) to use via the `locale` prop. The prop accepts either a single locale string, or an array of locale strings (listed in order of preferred locale). The calendar starts the week on Sunday. This can be changed by setting the `start-weekday` prop to a number in the range of `0` to `6` where `0` represents Sunday, `1` for Monday, up to `6` for Saturday. ```html <template> <div> <label for="example-locales">Locale:</label> <b-form-select id="example-locales" v-model="locale" :options="locales" class="mb-2"></b-form-select> <label for="example-weekdays">Start weekday:</label> <b-form-select id="example-weekdays" v-model="weekday" :options="weekdays" class="mb-2"></b-form-select> <div> <b-form-checkbox v-model="showDecadeNav" switch inline class="my-2"> Show decade navigation buttons </b-form-checkbox> <b-form-checkbox v-model="hideHeader" switch inline class="my-2"> Hide calendar header </b-form-checkbox> </div> <label for="example-i18n-picker">Date picker:</label> <b-form-datepicker id="example-i18n-picker" v-model="value" v-bind="labels[locale] || {}" :locale="locale" :start-weekday="weekday" :show-decade-nav="showDecadeNav" :hide-header="hideHeader" class="mb-2" ></b-form-datepicker> <p>Value: <b>'{{ value }}'</b></p> </div> </template> <script> export default { data() { return { value: '', locale: 'en-US', showDecadeNav: false, hideHeader: false, locales: [ { value: 'en-US', text: 'English US (en-US)' }, { value: 'de', text: 'German (de)' }, { value: 'ar-EG', text: 'Arabic Egyptian (ar-EG)' }, { value: 'zh', text: 'Chinese (zh)' } ], weekday: 0, weekdays: [ { value: 0, text: 'Sunday' }, { value: 1, text: 'Monday' }, { value: 6, text: 'Saturday' } ], labels: { de: { labelPrevDecade: 'Vorheriges Jahrzehnt', labelPrevYear: 'Vorheriges Jahr', labelPrevMonth: 'Vorheriger Monat', labelCurrentMonth: 'Aktueller Monat', labelNextMonth: 'Nächster Monat', labelNextYear: 'Nächstes Jahr', labelNextDecade: 'Nächstes Jahrzehnt', labelToday: 'Heute', labelSelected: 'Ausgewähltes Datum', labelNoDateSelected: 'Kein Datum gewählt', labelCalendar: 'Kalender', labelNav: 'Kalendernavigation', labelHelp: 'Mit den Pfeiltasten durch den Kalender navigieren' }, 'ar-EG': { weekdayHeaderFormat: 'narrow', labelPrevDecade: 'العقد السابق', labelPrevYear: 'العام السابق', labelPrevMonth: 'الشهر السابق', labelCurrentMonth: 'الشهر الحالي', labelNextMonth: 'الشهر المقبل', labelNextYear: 'العام المقبل', labelNextDecade: 'العقد القادم', labelToday: 'اليوم', labelSelected: 'التاريخ المحدد', labelNoDateSelected: 'لم يتم اختيار تاريخ', labelCalendar: 'التقويم', labelNav: 'الملاحة التقويم', labelHelp: 'استخدم مفاتيح المؤشر للتنقل في التواريخ' }, zh: { weekdayHeaderFormat: 'narrow', labelPrevDecade: '过去十年', labelPrevYear: '上一年', labelPrevMonth: '上个月', labelCurrentMonth: '当前月份', labelNextMonth: '下个月', labelNextYear: '明年', labelNextDecade: '下一个十年', labelToday: '今天', labelSelected: '选定日期', labelNoDateSelected: '未选择日期', labelCalendar: '日历', labelNav: '日历导航', labelHelp: '使用光标键浏览日期' } } } } } </script> <!-- b-form-datepicker-i18n.vue --> ``` You can listen to for the `context` event to determine the locale and directionality that the calendar has resolved to. Refer to the [`<b-calendar>`](/docs/components/calendar#internationalization) documentation for additional details. ## Accessibility The popup calendar supports the same [keyboard controls as `<b-calendar>`](/docs/components/calendar#accessibility), along with the following: - <kbd>Esc</kbd> will close the popup calendar without selecting a date When internationalizing the datepicker, it is important to also update the `label-*` props with appropriate translated strings, so that international screen reader users will hear the correct prompts and descriptions. Refer to the [`<b-calendar>`](/docs/components/calendar#accessibility) documentation for additional details. ## Implementation notes `<b-form-datepicker>` is based upon the components [`<b-calendar>`](/docs/components/calendar) and [`<b-dropdown>`](/docs/components/dropdown). `<b-form-datepicker>` uses Bootstrap's border and flex utility classes, along with button (`btn-*`) classes, dropdown (`dropdown*`) classes, and the `form-control*` (plus validation) classes. BootstrapVue's Custom SCSS/CSS is also required for proper styling of the date picker and calendar. ## See also - [`<b-form-timepicker>` Time picker custom form input](/docs/components/form-timepicker) - [`<b-calendar>` Calendar date selection widget](/docs/components/calendar) - [`<b-time>` Time selection widget](/docs/components/time) - [`<b-dropdown>` Dropdown component](/docs/components/dropdown)