Skip to content

Instantly share code, notes, and snippets.

@booni3
Created June 2, 2019 17:22
Show Gist options
  • Save booni3/5f7e069fd7f8847a6e98c77662871faa to your computer and use it in GitHub Desktop.
Save booni3/5f7e069fd7f8847a6e98c77662871faa to your computer and use it in GitHub Desktop.
v-calendar with range selection in dropdown
<template>
<component class="dropdown btn-form date-picker"
:is="tag"
:class="[{open: isOpen}, {show: isOpen}]"
aria-haspopup="true"
:aria-expanded="isOpen"
v-click-outside="closeDropDown">
<slot name="title" :is-open="isOpen">
<a class="dropdown-toggle nav-link"
:class="{'no-caret': hideArrow}"
@click="toggleDropDown">
<i class="fa fa-calendar"></i>
<span class="no-icon">{{title}}</span>
</a>
</slot>
<ul class="dropdown-menu datepicker-container"
:x-placement="directionAttribute"
:class="[{'dropdown-menu-right': position === 'right'}, {open: isOpen}]">
<div class="datepicker-left">
<button
class="btn-form btn-datepicker"
v-for="(value, key) in ranges"
@click=clickRange(value)
:data-range-key="key"
:key="key"
>{{key}}
</button>
</div>
<div class="datepicker-right">
<v-date-picker
ref="picker"
:first-day-of-week="2"
:mode='mode'
v-model='selectedDate'
:max-date='new Date()'
:columns="2"
is-inline>
</v-date-picker>
</div>
</ul>
</component>
</template>
<script>
export default {
name: 'drop-down',
model: {
prop: 'selectedDate',
// event: 'update',
},
props: {
direction: {
type: String,
default: 'down',
description: 'Drop down menu direction (up|down)'
},
// title: String,
icon: String,
position: {
type: String,
description: 'Drop down menu arrow position (left|right)'
},
hideArrow: {
type: Boolean,
default: false,
description: 'Whether to hide drop down arrow'
},
tag: {
type: String,
default: 'li',
description: 'Html tag of the dropdnown'
}
},
data() {
return {
isOpen: false,
// Data used by the date picker
mode: 'range',
selectedDate: {
start: moment().subtract(30, 'days').toDate(),
end: new Date(),
date: new Date()
},
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'This month': [moment().startOf('month'), moment().endOf('day')],
'This year': [moment().startOf('year'), moment().endOf('day')],
'Last week': [moment().subtract(1, 'week').startOf('week'), moment().subtract(1, 'week').endOf('week')],
'Last month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
}
}
},
computed: {
directionAttribute() {
let baseDirection = '';
if (this.direction === 'up') {
baseDirection = 'top-start';
} else if (this.direction === 'down') {
baseDirection = 'bottom-start';
}
return baseDirection;
},
title() {
if (this.mode === 'range') {
return this.formatDate(this.selectedDate.start) + ' - ' + this.formatDate(this.selectedDate.end)
}
return this.formatDate(this.selectedDate.date)
}
},
methods: {
toggleDropDown() {
this.isOpen = !this.isOpen
this.$emit('change', this.isOpen)
},
openDropDown() {
this.isOpen = true
this.$emit('change', this.isOpen)
},
closeDropDown() {
this.isOpen = false
this.$emit('change', this.isOpen)
},
clickRange(value) {
this.selectedDate.start = new Date(value[0])
this.selectedDate.end = new Date(value[1])
this.$refs.picker.adjustPageRange()
},
formatDate(date) {
var day = date.getDate();
var month = date.getMonth() + 1;
var year = date.getFullYear();
return day + '/' + month + '/' + year;
}
}
}
</script>
<style>
.dropdown {
list-style-type: none;
}
.dropdown .dropdown-toggle {
cursor: pointer;
}
.datepicker-container .vc-container {
border: none;
}
</style>
<style scoped>
.dropdown-menu {
left: -100px !important;
}
.datepicker-container {
width: 650px;
}
.dropdown-menu:before, .dropdown-menu:after {
right: 480px !important;
}
.btn-datepicker {
width: 120px;
margin-bottom: 3px;
}
.datepicker-left {
float: left;
width: 120px;
margin-top: 5px;
}
.datepicker-right {
float: right;
margin: 5px;
}
.date-picker.btn-form{
font-size: inherit;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment