Fixed position
-
+
<datepicker :fixed-position="'top-right'"></datepicker>
@@ -57,7 +74,7 @@
RTL datepicker
-
+
<datepicker :language="$datepickerLocals.he"></datepicker>
@@ -171,6 +188,6 @@ export default {
diff --git a/docs/guide/Props/README.md b/docs/guide/Props/README.md
index 87313caf..3fee7de1 100755
--- a/docs/guide/Props/README.md
+++ b/docs/guide/Props/README.md
@@ -9,26 +9,26 @@
| calendar-button | Boolean | false | Show an icon that that can be clicked |
| calendar-button-icon | String | | Use icon for button (ex: fa fa-calendar) |
| calendar-button-icon-content | String | | Use for material-icons (ex: event) |
-| calendar-class | String\|Object | | CSS class applied to the calendar el |
+| calendar-class | String\|Object | | CSS class applied to the calendar el |
| clear-button | Boolean | false | Show an icon for clearing the date |
| clear-button-icon | String | | Use icon for button (ex: fa fa-times) |
| day-cell-content | Function | | Use to render custom content in day cell |
| disabled | Boolean | false | If `true`, disable Datepicker on screen |
| disabled-dates | Object | | See below for configuration |
+| first-day-of-week | String | sun | Sets the first day of the week. Possible values: _sun_, _mon_, _tue_, _wed_, _thu_, _fri_, _sat_ |
| fixed-position | String | | Set a fixed position for the picker. Possible values: _bottom_, _bottom-left_, _bottom-right_, _top_, _top-left_ and _top-right_ |
-| format | String\|Function | dd MMM yyyy | Date formatting string or function |
+| format | String|Function | dd MMM yyyy | Date formatting string or function |
| full-month-name | Boolean | false | To show the full month name |
| id | String | | Input id |
| initial-view | String | minimumView | If set, open on that view |
| inline | Boolean | | To show the datepicker always open |
-| input-class | String\|Object\|Array | | CSS class(es) applied to the input el |
+| input-class | String|Object|Array| | CSS class(es) applied to the input element |
| language | Object | en | Translation for days and months |
| maxlength | String | | Sets html `maxlength` attribute on input |
-| maximum-view | String | 'year' | If set, higher-level views won't show |
-| minimum-view | String | 'day' | If set, lower-level views won't show |
-| monday-first | Boolean | false | To start the week on Monday |
+| maximum-view | String | year | If set, higher-level views won't show |
+| minimum-view | String | day | If set, lower-level views won't show |
| name | String | | Input name property |
-| open-date | Date\|String | | If set, open on that date |
+| open-date | Date|String | | If set, open on that date |
| pattern | String | | Sets html `pattern` attribute on input |
| placeholder | String | | Input placeholder text |
| required | Boolean | false | Sets html required attribute on input |
@@ -36,9 +36,9 @@
| show-header | Boolean | true | If `false`, the header section won't show |
| show-calendar-on-focus | Boolean | false | Opens the calendar on input focus |
| show-calendar-on-button-click | Boolean | false | Only open the calendar on calendar-button click |
-| tabindex | String\|Number | | Tabindex for the input field |
+| tabindex | String|Number | | Tabindex for the input field |
| typeable | Boolean | false | If `true`, allow the user to type the date |
| use-utc | Boolean | false | Use UTC for time calculations |
-| value | Date\|String | | Date value of the datepicker |
-| wrapper-class | String\|Object | | CSS class applied to the outer div |
-| year-picker-range | Number | 10 | Amount of years inside the year picker |
+| value | Date|String | | Date value of the datepicker |
+| wrapper-class | String|Object | | CSS class applied to the outer div |
+| year-picker-range | Number | 10 | How many years to display in the _year picker_ |
diff --git a/example/Demo.vue b/example/Demo.vue
index 5777d579..47fb20f1 100755
--- a/example/Demo.vue
+++ b/example/Demo.vue
@@ -12,6 +12,19 @@
+
+
Custom first-day-of-week datepicker
+
+
+ <datepicker placeholder="Type or select date"
+ first-day-of-week="mon"
+ ></datepicker>
+
+
+
Typeable datepicker
parseInt(day, 10))
+ const highlightedDays = elem.target.value.split(',')
+ .map((day) => parseInt(day, 10))
this.highlighted = {
from: this.highlighted.from,
to: this.highlighted.to,
@@ -483,7 +497,8 @@ export default {
if (elem.target.value === 'undefined') {
return
}
- const disabledDays = elem.target.value.split(',').map((day) => parseInt(day, 10))
+ const disabledDays = elem.target.value.split(',')
+ .map((day) => parseInt(day, 10))
this.disabledDates = {
from: this.disabledDates.from,
to: this.disabledDates.to,
diff --git a/src/components/Datepicker.vue b/src/components/Datepicker.vue
index f32c3f0c..17287031 100644
--- a/src/components/Datepicker.vue
+++ b/src/components/Datepicker.vue
@@ -70,9 +70,9 @@
:allowed-to-show-view="allowedToShowView"
:day-cell-content="dayCellContent"
:disabled-dates="disabledDates"
+ :first-day-of-week="firstDayOfWeek"
:highlighted="highlighted"
:is-rtl="isRtl"
- :monday-first="mondayFirst"
:page-date="pageDate"
:page-timestamp="pageTimestamp"
:selected-date="selectedDate"
@@ -113,12 +113,12 @@
import '~/utils/polyfills'
import en from '~/locale/translations/en'
import { makeDateUtils } from '~/utils/DateUtils'
+import calendarSlots from '~/utils/calendarSlots'
import DateInput from '~/components/DateInput'
+import inputProps from '~/mixins/inputProps'
import PickerDay from '~/components/PickerDay'
import PickerMonth from '~/components/PickerMonth'
import PickerYear from '~/components/PickerYear'
-import inputProps from '~/mixins/inputProps'
-import calendarSlots from '~/utils/calendarSlots'
import Popup from '~/components/Popup'
const validDate = (val) => val === null
@@ -139,6 +139,10 @@ export default {
inputProps,
],
props: {
+ appendToBody: {
+ type: Boolean,
+ default: false,
+ },
calendarClass: {
type: [
String,
@@ -157,6 +161,10 @@ export default {
return {}
},
},
+ firstDayOfWeek: {
+ type: String,
+ default: 'sun',
+ },
fixedPosition: {
type: String,
default: '',
@@ -194,10 +202,6 @@ export default {
type: String,
default: 'day',
},
- mondayFirst: {
- type: Boolean,
- default: false,
- },
showHeader: {
type: Boolean,
default: true,
@@ -223,10 +227,6 @@ export default {
type: Number,
default: 10,
},
- appendToBody: {
- type: Boolean,
- default: false,
- },
},
data() {
// const startDate = this.openDate ? new Date(this.openDate) : new Date()
@@ -239,25 +239,25 @@ export default {
}
const pageTimestamp = constructedDateUtils.setDate(startDate, 1)
return {
+ /*
+ * Positioning
+ */
+ calendarHeight: 0,
+ calendarSlots,
+ currentPicker: '',
/*
* Vue cannot observe changes to a Date Object so date must be stored as a timestamp
* This represents the first day of the current viewing month
* {Number}
*/
pageTimestamp,
- currentPicker: '',
+ resetTypedDate: constructedDateUtils.getNewDateObject(),
/*
* Selected Date
* {Date}
*/
selectedDate: null,
- /*
- * Positioning
- */
- calendarHeight: 0,
- resetTypedDate: constructedDateUtils.getNewDateObject(),
utils: constructedDateUtils,
- calendarSlots,
}
},
computed: {
diff --git a/src/components/PickerDay.vue b/src/components/PickerDay.vue
index d1ca8938..50b3c078 100644
--- a/src/components/PickerDay.vue
+++ b/src/components/PickerDay.vue
@@ -70,9 +70,9 @@ export default {
return {}
},
},
- mondayFirst: {
- type: Boolean,
- default: false,
+ firstDayOfWeek: {
+ type: String,
+ default: 'sun',
},
showFullMonthName: {
type: Boolean,
@@ -87,10 +87,7 @@ export default {
*/
blankDays() {
const dObj = this.newPageDate()
- if (this.mondayFirst) {
- return this.utils.getDay(dObj) > 0 ? this.utils.getDay(dObj) - 1 : 6
- }
- return this.utils.getDay(dObj)
+ return (7 - this.firstDayOfWeekNumber + this.utils.getDay(dObj)) % 7
},
/**
* Gets the name of the month the current page is on
@@ -130,12 +127,14 @@ export default {
* @return {String[]}
*/
daysOfWeek() {
- if (this.mondayFirst) {
- const tempDays = this.translation.days.slice()
- tempDays.push(tempDays.shift())
- return tempDays
- }
- return this.translation.days
+ return this.translation.getDaysStartingOn(this.firstDayOfWeekNumber)
+ },
+ /**
+ * Returns first-day-of-week as a number (Sunday is 0)
+ * @return {Number}
+ */
+ firstDayOfWeekNumber() {
+ return this.utils.getDayFromAbbr(this.firstDayOfWeek)
},
/**
* Is the next month disabled?
@@ -334,14 +333,6 @@ export default {
isSunday,
}
},
- /**
- * Increment the current page month
- */
- nextMonth() {
- if (!this.isNextDisabled) {
- this.changeMonth(+1)
- }
- },
/**
* Set up a new date object to the first day of the current 'page'
* @return Date
@@ -352,6 +343,14 @@ export default {
? new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1))
: new Date(d.getFullYear(), d.getMonth(), 1, d.getHours(), d.getMinutes())
},
+ /**
+ * Increment the current page month
+ */
+ nextMonth() {
+ if (!this.isNextDisabled) {
+ this.changeMonth(+1)
+ }
+ },
/**
* Decrement the page month
*/
diff --git a/src/components/PickerHeader.vue b/src/components/PickerHeader.vue
index 885546e3..9426d709 100644
--- a/src/components/PickerHeader.vue
+++ b/src/components/PickerHeader.vue
@@ -1,8 +1,8 @@
@@ -11,8 +11,8 @@
diff --git a/src/components/PickerMonth.vue b/src/components/PickerMonth.vue
index eb03da64..2eeedb54 100644
--- a/src/components/PickerMonth.vue
+++ b/src/components/PickerMonth.vue
@@ -7,8 +7,8 @@
:previous="previousYear"
>
{{ pageYearName }}
diff --git a/src/components/PickerYear.vue b/src/components/PickerYear.vue
index 695ed110..1b476fd6 100644
--- a/src/components/PickerYear.vue
+++ b/src/components/PickerYear.vue
@@ -94,7 +94,6 @@ export default {
years() {
const d = this.pageDate
const years = []
-
const year = this.useUtc
? Math.floor(d.getUTCFullYear() / this.yearRange) * this.yearRange
: Math.floor(d.getFullYear() / this.yearRange) * this.yearRange
diff --git a/src/locale/Language.js b/src/locale/Language.js
index 5a778ba1..5262a96e 100755
--- a/src/locale/Language.js
+++ b/src/locale/Language.js
@@ -54,6 +54,13 @@ export default class Language {
this._days = days
}
+ getDaysStartingOn(firstDayOfWeek) {
+ const firstDays = this._days.slice(firstDayOfWeek)
+ const lastDays = this._days.slice(0, firstDayOfWeek)
+
+ return firstDays.concat(lastDays)
+ }
+
getMonthByAbbrName(name) {
const monthValue = this._monthsAbbr.findIndex((month) => month === name) + 1
return monthValue < 10 ? `0${monthValue}` : `${monthValue}`
diff --git a/src/utils/DateUtils.js b/src/utils/DateUtils.js
index 362aca9e..45fb61dd 100755
--- a/src/utils/DateUtils.js
+++ b/src/utils/DateUtils.js
@@ -120,6 +120,20 @@ const utils = {
return days[this.getDay(date)]
},
+ /**
+ * Return day number from abbreviated week day name
+ * @param {String} abbr
+ * @return {Number}
+ */
+ getDayFromAbbr(abbr) {
+ for (let i = 0; i < en.days.length; i += 1) {
+ if (abbr.toLowerCase() === en.days[i].toLowerCase()) {
+ return i
+ }
+ }
+ throw TypeError('Invalid week day')
+ },
+
/**
* Return name of the month
* @param {Number|Date} month
diff --git a/test/unit/specs/DateUtils.spec.js b/test/unit/specs/DateUtils.spec.js
index d90c5deb..5563ef23 100755
--- a/test/unit/specs/DateUtils.spec.js
+++ b/test/unit/specs/DateUtils.spec.js
@@ -219,4 +219,10 @@ describe('UTC functions', () => {
expect(DateUtils.setDate(date, 31)).toEqual(date.setDate(31))
expect(utcUtils.setDate(date, 31)).toEqual(date.setUTCDate(31))
})
+
+ it('returns the correct day number from an abbreviated day name', () => {
+ expect(DateUtils.getDayFromAbbr('sun')).toEqual(0)
+ expect(DateUtils.getDayFromAbbr('sat')).toEqual(6)
+ expect(() => DateUtils.getDayFromAbbr('nonsense')).toThrow('Invalid week day')
+ })
})
diff --git a/test/unit/specs/PickerDay/firstDayOfWeek.spec.js b/test/unit/specs/PickerDay/firstDayOfWeek.spec.js
new file mode 100644
index 00000000..cb0360f3
--- /dev/null
+++ b/test/unit/specs/PickerDay/firstDayOfWeek.spec.js
@@ -0,0 +1,75 @@
+import { shallowMount } from '@vue/test-utils'
+import PickerDay from '~/components/PickerDay'
+import { en } from '~/locale'
+
+describe('PickerDay: Set first day of week', () => {
+ let wrapper
+ beforeEach(() => {
+ wrapper = shallowMount(PickerDay, {
+ propsData: {
+ firstDayOfWeek: 'mon',
+ translation: en,
+ allowedToShowView: () => true,
+ pageDate: new Date(2018, 1, 1),
+ },
+ })
+ })
+
+ afterEach(() => {
+ wrapper.destroy()
+ })
+
+ it('should return Monday as a first day of week', () => {
+ expect(wrapper.vm.daysOfWeek[0]).toEqual('Mon')
+ })
+
+ it('should return Sunday as a seventh day of week', () => {
+ expect(wrapper.vm.daysOfWeek[6]).toEqual('Sun')
+ })
+
+ it('should have 6 blankDays when month starts on a Sunday', () => {
+ wrapper.setProps({
+ pageDate: new Date(2018, 3, 1),
+ })
+ expect(wrapper.vm.blankDays).toEqual(6)
+ })
+
+ it('should have no blankDays when month starts on a Monday', () => {
+ wrapper.setProps({
+ pageDate: new Date(2018, 9, 1),
+ })
+ expect(wrapper.vm.blankDays).toEqual(0)
+ })
+})
+
+describe('PickerDay: Datepicker with Saturday as first day of week', () => {
+ let wrapper
+ beforeEach(() => {
+ wrapper = shallowMount(PickerDay, {
+ propsData: {
+ firstDayOfWeek: 'sat',
+ translation: en,
+ allowedToShowView: () => true,
+ pageDate: new Date(2018, 1, 1),
+ },
+ })
+ })
+
+ afterEach(() => {
+ wrapper.destroy()
+ })
+
+ it('should have 6 blankDays when month starts on a Friday', () => {
+ wrapper.setProps({
+ pageDate: new Date(2021, 0, 1),
+ })
+ expect(wrapper.vm.blankDays).toEqual(6)
+ })
+
+ it('should have no blankDays when month starts on a Saturday', () => {
+ wrapper.setProps({
+ pageDate: new Date(2020, 7, 1),
+ })
+ expect(wrapper.vm.blankDays).toEqual(0)
+ })
+})
diff --git a/test/unit/specs/PickerDay/mondayFirst.spec.js b/test/unit/specs/PickerDay/mondayFirst.spec.js
deleted file mode 100755
index 1cb81c2a..00000000
--- a/test/unit/specs/PickerDay/mondayFirst.spec.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import { shallowMount } from '@vue/test-utils'
-import PickerDay from '~/components/PickerDay'
-import { en } from '~/locale'
-
-describe('PickerDay: Datepicker with monday as first day of week', () => {
- let wrapper
- beforeEach(() => {
- wrapper = shallowMount(PickerDay, {
- propsData: {
- mondayFirst: true,
- translation: en,
- allowedToShowView: () => true,
- pageDate: new Date(2018, 1, 1),
- },
- })
- })
-
- afterEach(() => {
- wrapper.destroy()
- })
-
- it('should return Monday as a first day of week', () => {
- expect(wrapper.vm.daysOfWeek[0]).toEqual('Mon')
- })
-
- it('should return Sunday as a seventh day of week', () => {
- expect(wrapper.vm.daysOfWeek[6]).toEqual('Sun')
- })
-
- it('should have 6 blankDays when month starts from Sunday', () => {
- wrapper.setProps({
- pageDate: new Date(2018, 3, 1),
- })
- expect(wrapper.vm.blankDays).toEqual(6)
- })
-
- it('should have no blankDays when month starts from Monday', () => {
- wrapper.setProps({
- pageDate: new Date(2018, 9, 1),
- })
- expect(wrapper.vm.blankDays).toEqual(0)
- })
-})