Skip to content

Commit dcc33d6

Browse files
authored
Merge branch 'master' into master
2 parents 6f0ce4d + 2400ab1 commit dcc33d6

File tree

6 files changed

+246
-94
lines changed

6 files changed

+246
-94
lines changed

README.md

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,43 @@ Inline always open version
5858
```
5959
## Available props
6060

61-
| Prop | Type | Default | Description |
62-
|-----------------|--------------|-------------|---------------------------------------|
63-
| value | Date/String | | Date value of the datepicker |
64-
| name | String | | input name property |
65-
| id | String | | input id |
66-
| format | String | dd MMM yyyy | Date formatting string |
67-
| language | String | en | Translation for days and months |
68-
| disabled | Object | | See below for configuration |
69-
| placeholder | String | | input placeholder text |
70-
| inline | Boolean | | to show the datepicker always open |
71-
| input-class | String | | css class applied to the input el |
72-
| wrapper-class | String | | css class applied to the outer div |
73-
| monday-first | Boolean | false | To start the week on Monday |
74-
| clear-button | Boolean | false | Show an icon for clearing the date |
75-
| disabled-picker | Boolean | false | If true, disable Datepicker on screen |
76-
| required | Boolean | false | Sets html required attribute on input |
61+
| Prop | Type | Default | Description |
62+
|-----------------------|--------------|-------------|------------------------------------------|
63+
| value | Date/String | | Date value of the datepicker |
64+
| name | String | | Input name property |
65+
| id | String | | Input id |
66+
| format | String | dd MMM yyyy | Date formatting string |
67+
| language | String | en | Translation for days and months |
68+
| disabled | Object | | See below for configuration |
69+
| placeholder | String | | Input placeholder text |
70+
| inline | Boolean | | To show the datepicker always open |
71+
| input-class | String | | CSS class applied to the input el |
72+
| wrapper-class | String | | CSS class applied to the outer div |
73+
| monday-first | Boolean | false | To start the week on Monday |
74+
| clear-button | Boolean | false | Show an icon for clearing the date |
75+
| clear-button-icon | String | | Use icon for button (ex: fa fa-times) |
76+
| calendar-button | Boolean | false | Show an icon that that can be clicked |
77+
| calendar-button-icon | String | | Use icon for button (ex: fa fa-calendar) |
78+
| bootstrapStyling | Boolean | false | Output bootstrap styling classes |
79+
| initial-view | String | 'day' | If 'month' or 'year', open on that view |
80+
| disabled-picker | Boolean | false | If true, disable Datepicker on screen |
81+
| required | Boolean | false | Sets html required attribute on input |
82+
83+
## Events
84+
85+
These events are emitted on actions in the datepicker
86+
87+
| Event | Output | Description |
88+
|---------------|------------|-------------------------------|
89+
| opened | | The picker is opened |
90+
| closed | | The picker is closed |
91+
| selected | Date\|null | A date has been selected |
92+
| input | Date\|null | Input value has been modified |
93+
| cleared | | Selected date has been cleared|
94+
| changedMonth | Object | Month page has been changed |
95+
| changedYear | Object | Year page has been changed |
96+
| changedDecade | Object | Decade page has been changed |
97+
7798

7899
## Date formatting
79100

@@ -147,9 +168,11 @@ Available languages
147168
| Abbr | Language | |
148169
| ----------- |------------------|----------|
149170
| en | English | *Default*|
171+
| bs | Bosnian | |
150172
| es | Spanish | |
151173
| fi | Finnish | |
152174
| fr | French | |
175+
| hu | Hungarian | |
153176
| hr | Croatian | |
154177
| id | Indonesian | |
155178
| it | Italian | |
@@ -165,6 +188,7 @@ Available languages
165188
| ja | Japanese | |
166189
| he | Hebrew | |
167190
| ru | Russian | |
191+
| sk | Slovak | |
168192
| sl-si | Slovenian | |
169193
| sv | Swedish | |
170194
| th | Thai | |
@@ -174,4 +198,6 @@ Available languages
174198
| ar | Arabic | |
175199
| ee | Estonian | |
176200
| ko | Korean | |
177-
| tr | Turkish | |
201+
| tr | Turkish | |
202+
| uk | Ukrainian | |
203+
| is | Icelandic | |

build/dev.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Vue from 'vue'
22
import Datepicker from '../src/Datepicker.vue'
33

4+
/* eslint-disable no-new */
45
new Vue({
56
el: 'body',
67
components: { Datepicker }

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vuejs-datepicker",
3-
"version": "0.7.4",
3+
"version": "0.7.16",
44
"description": "A simple Vue.js datepicker component. Supports disabling of dates, inline mode, translations",
55
"keywords": [
66
"vue",

src/Datepicker.vue

Lines changed: 91 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
<template>
22
<div class="vdp-datepicker" :class="wrapperClass">
3-
<input
3+
<div :class="{'input-group' : bootstrapStyling}">
4+
<span class="vdp-datepicker__calendar-button" :class="{'input-group-addon' : bootstrapStyling}" v-if="calendarButton" @click="showCalendar"><i :class="calendarButtonIcon"><span v-if="calendarButtonIcon.length === 0">&hellip;</span></i></span>
5+
<input
46
:type="inline ? 'hidden' : 'text'"
5-
:class="inputClass"
7+
:class="[ inputClass, { 'form-control' : bootstrapStyling } ]"
68
:name="name"
79
:id="id"
8-
@click="showCalendar()"
10+
@click="showCalendar"
911
:value="formattedValue"
1012
:placeholder="placeholder"
1113
:clear-button="clearButton"
1214
:disabled="disabledPicker"
1315
:required="required"
1416
readonly>
15-
<i class="vdp-datepicker__clear-button" v-if="clearButton" @click="clearDate()">&times;</i>
17+
<span class="vdp-datepicker__clear-button" :class="{'input-group-addon' : bootstrapStyling}" v-if="clearButton && selectedDate" @click="clearDate()"><i :class="clearButtonIcon"><span v-if="calendarButtonIcon.length === 0">&times;</span></i></span>
18+
</div>
19+
1620
<!-- Day View -->
1721
<div class="vdp-datepicker__calendar" v-show="showDayView" v-bind:style="calendarStyle">
1822
<header>
@@ -31,12 +35,12 @@
3135
--><span class="cell day"
3236
v-for="day in days"
3337
track-by="timestamp"
34-
v-bind:class="{ 'selected':day.isSelected, 'disabled':day.isDisabled, 'highlighted': day.isHighlighted}"
38+
v-bind:class="{ 'selected':day.isSelected, 'disabled':day.isDisabled, 'highlighted': day.isHighlighted, 'today': day.isToday}"
3539
@click="selectDate(day)">{{ day.date }}</span>
3640
</div>
3741

3842
<!-- Month View -->
39-
<div class="vdp-datepicker__calendar" v-show="showMonthView" v-bind:style="calendarStyleSecondary">
43+
<div class="vdp-datepicker__calendar" v-show="showMonthView" v-bind:style="calendarStyle">
4044
<header>
4145
<span
4246
@click="previousYear"
@@ -56,7 +60,7 @@
5660
</div>
5761

5862
<!-- Year View -->
59-
<div class="vdp-datepicker__calendar" v-show="showYearView" v-bind:style="calendarStyleSecondary">
63+
<div class="vdp-datepicker__calendar" v-show="showYearView" v-bind:style="calendarStyle">
6064
<header>
6165
<span @click="previousDecade" class="prev"
6266
v-bind:class="{ 'disabled' : previousDecadeDisabled(currDate) }">&lt;</span>
@@ -71,7 +75,6 @@
7175
v-bind:class="{ 'selected': year.isSelected, 'disabled': year.isDisabled }"
7276
@click.stop="selectYear(year)">{{ year.year }}</span>
7377
</div>
74-
7578
</div>
7679
</template>
7780

@@ -126,6 +129,26 @@ export default {
126129
type: Boolean,
127130
default: false
128131
},
132+
clearButtonIcon: {
133+
type: String,
134+
default: ''
135+
},
136+
calendarButton: {
137+
type: Boolean,
138+
default: false
139+
},
140+
calendarButtonIcon: {
141+
type: String,
142+
default: ''
143+
},
144+
bootstrapStyling: {
145+
type: Boolean,
146+
default: false
147+
},
148+
initialView: {
149+
type: String,
150+
default: 'day'
151+
},
129152
disabledPicker: {
130153
type: Boolean,
131154
default: false
@@ -217,7 +240,8 @@ export default {
217240
timestamp: dObj.getTime(),
218241
isSelected: this.isSelectedDate(dObj),
219242
isDisabled: this.isDisabledDate(dObj),
220-
isHighlighted: this.isHighlightedDate(dObj)
243+
isHighlighted: this.isHighlightedDate(dObj),
244+
isToday: dObj.toDateString() === (new Date()).toDateString()
221245
})
222246
dObj.setDate(dObj.getDate() + 1)
223247
}
@@ -257,70 +281,77 @@ export default {
257281
},
258282
calendarStyle () {
259283
let styles = {}
260-
if (!this.$isServer) {
261-
let elSize = {
262-
top: 0,
263-
height: 0
264-
}
265-
if (this.$el) {
266-
elSize = this.$el.getBoundingClientRect()
267-
}
268-
let heightNeeded = elSize.top + elSize.height + this.calendarHeight || 0
269-
// if the calendar doesn't fit on the window without scrolling position it above the input
270-
if (heightNeeded > window.innerHeight) {
271-
styles = {
272-
'bottom': elSize.height + 'px'
273-
}
274-
}
275-
}
276-
if (this.isInline()) {
284+
285+
if (this.isInline) {
277286
styles.position = 'static'
278287
}
279288
280289
return styles
281290
},
282-
calendarStyleSecondary () {
283-
return (this.isInline()) ? { 'position': 'static' } : {}
291+
isOpen () {
292+
return this.showDayView || this.showMonthView || this.showYearView
293+
},
294+
isInline () {
295+
return typeof this.inline !== 'undefined' && this.inline
284296
}
285297
},
286298
methods: {
299+
/**
300+
* Close all calendar layers
301+
*/
287302
close () {
288303
this.showDayView = this.showMonthView = this.showYearView = false
289304
this.$emit('closed')
305+
document.removeEventListener('click', this.clickOutside, false)
290306
},
291307
getDefaultDate () {
292308
return new Date(new Date().getFullYear(), new Date().getMonth(), 1).getTime()
293309
},
294310
resetDefaultDate () {
295-
this.currDate = (this.selectedDate === null) ? this.getDefaultDate() : this.selectedDate.getTime()
296-
},
297-
isOpen () {
298-
return this.showDayView || this.showMonthView || this.showYearView
299-
},
300-
isInline () {
301-
return typeof this.inline !== 'undefined' && this.inline
311+
if (this.selectedDate === null) {
312+
this.currDate = this.getDefaultDate()
313+
return
314+
}
315+
this.currDate = this.currDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), 1).getTime()
302316
},
317+
/**
318+
* Effectively a toggle to show/hide the calendar
319+
* @return {[type]} [description]
320+
*/
303321
showCalendar () {
304-
if (this.isInline()) {
322+
if (this.isInline) {
305323
return false
306324
}
307-
if (this.isOpen()) {
325+
if (this.isOpen) {
308326
return this.close()
309327
}
310-
this.showDayCalendar()
328+
switch (this.initialView) {
329+
case 'year':
330+
this.showYearCalendar()
331+
break
332+
case 'month':
333+
this.showMonthCalendar()
334+
break
335+
default:
336+
this.showDayCalendar()
337+
break
338+
}
311339
},
312340
showDayCalendar () {
313341
this.close()
314342
this.showDayView = true
315343
this.$emit('opened')
344+
document.addEventListener('click', this.clickOutside, false)
316345
},
317346
showMonthCalendar () {
318347
this.close()
319348
this.showMonthView = true
349+
document.addEventListener('click', this.clickOutside, false)
320350
},
321351
showYearCalendar () {
322352
this.close()
323353
this.showYearView = true
354+
document.addEventListener('click', this.clickOutside, false)
324355
},
325356
326357
setDate (timestamp) {
@@ -332,7 +363,8 @@ export default {
332363
333364
clearDate () {
334365
this.selectedDate = null
335-
this.$emit('selected', this.selectedDate)
366+
this.$emit('selected', null)
367+
this.$emit('input', null)
336368
this.$emit('cleared')
337369
},
338370
@@ -344,7 +376,7 @@ export default {
344376
return false
345377
}
346378
this.setDate(day.timestamp)
347-
if (this.isInline()) {
379+
if (this.isInline) {
348380
return this.showDayCalendar()
349381
}
350382
this.close()
@@ -713,29 +745,28 @@ export default {
713745
this.currDate = new Date(date.getFullYear(), date.getMonth(), 1).getTime()
714746
},
715747
748+
/**
749+
* Close the calendar if clicked outside the datepicker
750+
* @param {Event} event
751+
*/
752+
clickOutside (event) {
753+
if (this.$el && !this.$el.contains(event.target)) {
754+
if (this.isInline) {
755+
return this.showDayCalendar()
756+
}
757+
this.resetDefaultDate()
758+
this.close()
759+
document.removeEventListener('click', this.clickOutside, false)
760+
}
761+
},
762+
716763
init () {
717764
if (this.value) {
718765
this.setValue(this.value)
719766
}
720-
if (this.isInline()) {
767+
if (this.isInline) {
721768
this.showDayCalendar()
722769
}
723-
724-
if (!this.$isServer) {
725-
this.$nextTick(() => {
726-
this.calendarHeight = this.$el.querySelector('.vdp-datepicker__calendar').getBoundingClientRect().height
727-
})
728-
}
729-
730-
document.addEventListener('click', (e) => {
731-
if (this.$el && !this.$el.contains(e.target)) {
732-
if (this.isInline()) {
733-
return this.showDayCalendar()
734-
}
735-
this.resetDefaultDate()
736-
this.close()
737-
}
738-
}, false)
739770
}
740771
},
741772
/**
@@ -857,7 +888,7 @@ $width = 300px
857888
.year
858889
width 33.333%
859890
860-
.vdp-datepicker__clear-button
861-
cursor: pointer
862-
font-style: normal
891+
.vdp-datepicker__clear-button, .vdp-datepicker__calendar-button
892+
cursor pointer
893+
font-style normal
863894
</style>

0 commit comments

Comments
 (0)