Skip to content

Instantly share code, notes, and snippets.

@dsturm
Created November 20, 2017 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsturm/3b15a23bf1f2dd991ad6c6491f946f19 to your computer and use it in GitHub Desktop.
Save dsturm/3b15a23bf1f2dd991ad6c6491f946f19 to your computer and use it in GitHub Desktop.
Vue Datetime Picker Component // source http://jsbin.com/yurexon
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue Datetime Picker Component</title>
<link rel="stylesheet" type="text/css" href="http://cdn.jsdelivr.net/bootstrap/3/css/bootstrap.css"/>
<link rel="stylesheet" type="text/css" href="http://cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css"/>
<style type="text/css">
body {
margin: 5em;
}
</style>
</head>
<body>
<div id="app" class="container">
<p>Basic Example that sets a default start and end date:</p>
<date-range-picker
start-date="2017-11-10"
end-date="2017-11-12"
></date-range-picker>
<hr>
<p>Example using the @apply event handler with custom ranges</p>
<p>Start Date: {{ startDate }}, End Date: {{ endDate }}</p>
<date-range-picker @apply="onDateChange" show-ranges="true"></date-range-picker>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.3/dist/vue.min.js"></script>
<script type="text/x-template" id="date-range-template">
<div class="btn-group">
<a class="btn btn-default btn-rounded calendar-picker"
data-toggle="collapse"
aria-expand="true"
>
<span class="date-range-label">{{ dateRange }}</span>
<span class="caret"></span>
</a>
</div>
</script>
<script>
Vue.component('date-range-picker', {
template: '#date-range-template',
props: {
showRanges: {
type: Boolean,
default: false
},
startDate: {
default: function () {
return moment().subtract(30, 'days');
}
},
endDate: {
default: function () {
return moment();
}
},
minDate: {
default: false
},
opens: {
default: 'right'
},
maxDate: {
default: false
},
autoApply: {
default: false
},
},
data: function () {
return {
start: this.startDate,
end: this.endDate
};
},
computed: {
dateRange: function () {
var start = moment(this.start);
var end = moment(this.end);
var today = moment();
if (
start.format('LL') === end.format('LL') &&
today.format('LL') === start.format('LL')
) {
return 'Today';
} else if (start.format('MM-DD-YYYY') === end.format('MM-DD-YYYY')) {
return start.format('LL');
}
return start.format('LL') + ' - ' + end.format('LL');
}
},
mounted: function () {
var vm = this;
this.start = moment(this.start);
this.end = moment(this.end);
this.$nextTick(function () {
var options = {
opens: this.opens,
startDate: this.start,
endDate: this.end,
autoApply: this.autoApply,
alwaysShowCalendars: true
};
if (this.minDate) {
options.minDate = this.minDate;
}
if (this.maxDate) {
options.maxDate = this.maxDate;
}
if (this.showRanges) {
options.ranges = {
Today: [moment(), moment()],
Yesterday: [
moment().subtract(1, 'days'),
moment().subtract(1, 'days')
],
'Last 7 Days': [
moment().subtract(6, 'days'),
moment()
],
'Last 30 Days': [
moment().subtract(30, 'days'),
moment()
],
'This Month': [
moment().startOf('month'),
moment().endOf('month')
],
'Last Month': [
moment().subtract(1, 'month').startOf('month'),
moment().subtract(1, 'month').endOf('month')
]
};
}
window.$(this.$el)
.daterangepicker(options)
.on('apply.daterangepicker', function (e, picker) {
vm.$emit('apply', picker.startDate, picker.endDate);
vm.start = picker.startDate;
vm.end = picker.endDate;
});
});
}
});
var app = new Vue({
el: '#app',
data: {
start: null,
end: null
},
computed: {
startDate: function () {
if (! this.start) {
return 'Not Set'
}
return this.start.format('MM-DD-YYYY');
},
endDate: function () {
if (! this.end) {
return 'Not Set'
}
return this.end.format('MM-DD-YYYY');
}
},
methods: {
onDateChange: function (start, end) {
this.start = start;
this.end = end;
}
}
});
</script>
<script id="jsbin-source-html" type="text/html"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue Datetime Picker Component</title>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap/3/css/bootstrap.css"/>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css"/>
<style type="text/css">
body {
margin: 5em;
}
</style>
</head>
<body>
<div id="app" class="container">
<p>Basic Example that sets a default start and end date:</p>
<date-range-picker
start-date="2017-11-10"
end-date="2017-11-12"
></date-range-picker>
<hr>
<p>Example using the @apply event handler with custom ranges</p>
<p>Start Date: {{ startDate }}, End Date: {{ endDate }}</p>
<date-range-picker @apply="onDateChange" show-ranges="true"></date-range-picker>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.slim.min.js"><\/script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"><\/script>
<script src="https://cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"><\/script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.3/dist/vue.min.js"><\/script>
<script type="text/x-template" id="date-range-template">
<div class="btn-group">
<a class="btn btn-default btn-rounded calendar-picker"
data-toggle="collapse"
aria-expand="true"
>
<span class="date-range-label">{{ dateRange }}</span>
<span class="caret"></span>
</a>
</div>
<\/script>
<script>
Vue.component('date-range-picker', {
template: '#date-range-template',
props: {
showRanges: {
type: Boolean,
default: false
},
startDate: {
default: function () {
return moment().subtract(30, 'days');
}
},
endDate: {
default: function () {
return moment();
}
},
minDate: {
default: false
},
opens: {
default: 'right'
},
maxDate: {
default: false
},
autoApply: {
default: false
},
},
data: function () {
return {
start: this.startDate,
end: this.endDate
};
},
computed: {
dateRange: function () {
var start = moment(this.start);
var end = moment(this.end);
var today = moment();
if (
start.format('LL') === end.format('LL') &&
today.format('LL') === start.format('LL')
) {
return 'Today';
} else if (start.format('MM-DD-YYYY') === end.format('MM-DD-YYYY')) {
return start.format('LL');
}
return start.format('LL') + ' - ' + end.format('LL');
}
},
mounted: function () {
var vm = this;
this.start = moment(this.start);
this.end = moment(this.end);
this.$nextTick(function () {
var options = {
opens: this.opens,
startDate: this.start,
endDate: this.end,
autoApply: this.autoApply,
alwaysShowCalendars: true
};
if (this.minDate) {
options.minDate = this.minDate;
}
if (this.maxDate) {
options.maxDate = this.maxDate;
}
if (this.showRanges) {
options.ranges = {
Today: [moment(), moment()],
Yesterday: [
moment().subtract(1, 'days'),
moment().subtract(1, 'days')
],
'Last 7 Days': [
moment().subtract(6, 'days'),
moment()
],
'Last 30 Days': [
moment().subtract(30, 'days'),
moment()
],
'This Month': [
moment().startOf('month'),
moment().endOf('month')
],
'Last Month': [
moment().subtract(1, 'month').startOf('month'),
moment().subtract(1, 'month').endOf('month')
]
};
}
window.$(this.$el)
.daterangepicker(options)
.on('apply.daterangepicker', function (e, picker) {
vm.$emit('apply', picker.startDate, picker.endDate);
vm.start = picker.startDate;
vm.end = picker.endDate;
});
});
}
});
var app = new Vue({
el: '#app',
data: {
start: null,
end: null
},
computed: {
startDate: function () {
if (! this.start) {
return 'Not Set'
}
return this.start.format('MM-DD-YYYY');
},
endDate: function () {
if (! this.end) {
return 'Not Set'
}
return this.end.format('MM-DD-YYYY');
}
},
methods: {
onDateChange: function (start, end) {
this.start = start;
this.end = end;
}
}
});
<\/script>
</body>
</html>
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment