blob: 16f49bb58182e4785c0266ceb36f59da89cb1f90 [file] [log] [blame]
/** * Licensed to the Apache Software Foundation (ASF) under one or more *
contributor license agreements. See the NOTICE file distributed with * this work
for additional information regarding copyright ownership. * The ASF licenses
this file to You under the Apache License, Version 2.0 * (the "License"); you
may not use this file except in compliance with * the License. You may obtain a
copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless
required by applicable law or agreed to in writing, software * distributed under
the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. * See the License for the
specific language governing permissions and * limitations under the License. */
<template>
<div
class="datepicker"
:class="{
'datepicker-range': range,
datepicker__clearable: clearable && text && !disabled,
}"
>
<!-- <svg class="icon datepicker-icon">
<use xlink:href="#timer"></use>
</svg> -->
<input
class="cp"
readonly
:value="text"
:class="[show ? 'focus' : '', inputClass]"
:disabled="disabled"
:placeholder="placeholder"
:name="name"
v-if="type !== 'inline'"
/>
<a class="datepicker-close" @click.stop="cls"></a>
<transition name="datepicker-anim">
<div
class="datepicker-popup"
:class="[
popupClass,
{ 'datepicker-inline': type === 'inline' },
position === 'top' ? 'top' : 'bottom',
]"
tabindex="-1"
v-if="show || type === 'inline'"
>
<template v-if="range">
<div class="datepicker-popup__sidebar">
<button
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('quarter')"
>
{{ this.local.quarterHourCutTip }}
</button>
<button
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('half')"
>
{{ this.local.halfHourCutTip }}
</button>
<button
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('hour')"
>
{{ this.local.hourCutTip }}
</button>
<button
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('day')"
>
{{ this.local.dayCutTip }}
</button>
<button
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('week')"
>
{{ this.local.weekCutTip }}
</button>
<button
type="button"
class="datepicker-popup__shortcut"
@click="quickPick('month')"
>
{{ this.local.monthCutTip }}
</button>
</div>
<div class="datepicker-popup__body">
<rk-calendar v-model="dates[0]" :left="true"></rk-calendar>
<rk-calendar v-model="dates[1]" :right="true"></rk-calendar>
</div>
</template>
<template v-else>
<rk-calendar v-model="dates[0]"></rk-calendar>
</template>
<div v-if="showButtons" class="datepicker__buttons">
<button
@click.prevent.stop="cancel"
class="datepicker__button-cancel"
>
{{ this.local.cancelTip }}
</button>
<button
@click.prevent.stop="submit"
class="datepicker__button-select"
>
{{ this.local.submitTip }}
</button>
</div>
</div>
</transition>
</div>
</template>
<script lang="js">
import RkCalendar from './rk-date-calendar.vue';
import getLocalTime from '@/utils/localtime';
/* eslint-disable */
/* tslint:disable */
export default {
name: 'VueDatepickerLocal',
components: { RkCalendar },
props: {
position: { type:String, default:'bottom' },
name: [String],
inputClass: [String],
popupClass: [String],
value: [Date, Array, String],
disabled: [Boolean],
type: {
type: String,
default: 'normal',
},
rangeSeparator: {
type: String,
default: '~',
},
clearable: {
type: Boolean,
default: false,
},
placeholder: [String],
disabledDate: {
type: Function,
default: () => false,
},
format: {
type: String,
default: 'YYYY-MM-DD',
},
showButtons: {
type: Boolean,
default: false,
},
dateRangeSelect: [Function],
},
data() {
return {
show: false,
dates: [],
};
},
computed: {
local() {
return {
dow: 1, // Monday is the first day of the week
hourTip: this.$t('hourTip'), // tip of select hour
minuteTip: this.$t('minuteTip'), // tip of select minute
secondTip: this.$t('secondTip'), // tip of select second
yearSuffix: this.$t('yearSuffix'), // format of head
monthsHead: this.$t('monthsHead').split(
'_',
), // months of head
months: this.$t('months').split(
'_',
), // months of panel
weeks: this.$t('weeks').split('_'), // weeks
cancelTip: this.$t('cancel'), // default text for cancel button
submitTip: this.$t('confirm'), // default text for submit button
quarterHourCutTip: this.$t('quarterHourCutTip'),
halfHourCutTip: this.$t('halfHourCutTip'),
hourCutTip: this.$t('hourCutTip'),
dayCutTip: this.$t('dayCutTip'),
weekCutTip: this.$t('weekCutTip'),
monthCutTip: this.$t('monthCutTip'),
};
},
range() {
return this.dates.length === 2;
},
text() {
const val = this.value;
const txt = this.dates
.map(date => this.tf(date))
.join(` ${this.rangeSeparator} `);
if (Array.isArray(val)) {
return val.length > 1 ? txt : '';
}
return val ? txt : '';
},
},
watch: {
value() {
this.dates = this.vi(this.value);
},
},
methods: {
get() {
return Array.isArray(this.value) ? this.dates : this.dates[0];
},
cls() {
this.$emit('clear');
this.$emit('input', this.range ? [] : '');
},
vi(val) {
if (Array.isArray(val)) {
return val.length > 1
? val.map(item => new Date(item))
: [new Date(), new Date()];
}
return val ? [new Date(val)] : [new Date()];
},
ok(leaveOpened) {
this.$emit('input', this.get());
!leaveOpened &&
!this.showButtons &&
setTimeout(() => {
this.show = this.range;
});
},
tf(time, format) {
const year = time.getFullYear();
const month = time.getMonth();
const day = time.getDate();
const hours24 = time.getHours();
const hours = hours24 % 12 === 0 ? 12 : hours24 % 12;
const minutes = time.getMinutes();
const seconds = time.getSeconds();
const milliseconds = time.getMilliseconds();
const dd = t => (`0${t}`).slice(-2);
const map = {
YYYY: year,
MM: dd(month + 1),
MMM: this.local.months[month],
MMMM: this.local.monthsHead[month],
M: month + 1,
DD: dd(day),
D: day,
HH: dd(hours24),
H: hours24,
hh: dd(hours),
h: hours,
mm: dd(minutes),
m: minutes,
ss: dd(seconds),
s: seconds,
S: milliseconds,
};
return (format || this.format).replace(
/Y+|M+|D+|H+|h+|m+|s+|S+/g,
str => map[str],
);
},
dc(e) {
this.show = this.$el.contains(e.target) && !this.disabled;
},
quickPick(type){
const end = new Date();
const start = new Date();
switch (type) {
case 'quarter':
start.setTime(start.getTime() - 60 * 15 * 1000);//15 mins
break;
case 'half':
start.setTime(start.getTime() - 60 * 30 * 1000);//30 mins
break;
case 'hour':
start.setTime(start.getTime() - 3600 * 1000);//1 hour
break;
case 'day':
start.setTime(start.getTime() - 3600 * 1000 * 24);//1 day
break;
case 'week':
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);//1 week
break;
case 'month':
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);//1 month
break;
default:
break;
}
this.dates = [start, end];
this.$emit('input', this.get());
},
submit() {
this.$emit('confirm', this.get());
this.show = false;
},
cancel() {
this.$emit('cancel');
this.show = false;
},
},
mounted() {
this.dates = this.vi(this.value);
document.addEventListener('click', this.dc, true);
},
beforeDestroy() {
document.removeEventListener('click', this.dc, true);
},
};
</script>
<style lang="scss" scoped>
.datepicker {
display: inline-block;
position: relative;
// color: #3d444f;
}
.datepicker-icon {
display: block;
position: absolute;
top: 8px;
left: 8px;
color: #515a6ecc;
}
.datepicker-close {
display: none;
position: absolute;
width: 34px;
height: 100%;
top: 0;
right: 0;
cursor: pointer;
}
.datepicker-close:before {
display: block;
content: '';
position: absolute;
width: 16px;
height: 16px;
left: 50%;
top: 50%;
margin-left: -8px;
margin-top: -8px;
text-align: center;
background: #ccc;
color: #fff;
border-radius: 50%;
background: #ccc
url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3IDciIHdpZHRoPSI3IiBoZWlnaHQ9IjciPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik01LjU4LDVsMi44LTIuODFBLjQxLjQxLDAsMSwwLDcuOCwxLjZMNSw0LjQxLDIuMiwxLjZhLjQxLjQxLDAsMCwwLS41OC41OGgwTDQuNDIsNSwxLjYyLDcuOGEuNDEuNDEsMCwwLDAsLjU4LjU4TDUsNS41OCw3LjgsOC4zOWEuNDEuNDEsMCwwLDAsLjU4LS41OGgwWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEuNSAtMS40OCkiIHN0eWxlPSJmaWxsOiNmZmYiLz48L3N2Zz4NCg==')
no-repeat 50% 50%;
}
.datepicker__clearable:hover:before {
display: none;
}
.datepicker__clearable:hover .datepicker-close {
display: block;
}
.datepicker-close:hover:before {
background-color: #afafaf;
}
.datepicker > input {
color: inherit;
// transition: all 200ms ease;
border-radius: 4px;
border: 0;
background: none;
height: 28px;
box-sizing: border-box;
outline: none;
padding: 0 5px;
width: 100%;
user-select: none;
font-family: Monaco;
letter-spacing: -0.7px;
}
// .datepicker > input.focus {
// border-color: #3f97e3;
// -webkit-box-shadow: 0 0 5px rgba(59, 180, 242, 0.3);
// box-shadow: 0 0 5px rgba(59, 180, 242, 0.3);
// }
.datepicker > input:disabled {
cursor: not-allowed;
background-color: #ebebe4;
border-color: #e5e5e5;
-webkit-box-shadow: none;
box-shadow: none;
}
.datepicker-popup {
right: 0px;
border-radius: 4px;
position: absolute;
transition: all 200ms ease;
opacity: 1;
transform: scaleY(1);
font-size: 12px;
background: #fff;
box-shadow: 0 1px 6px rgba(99, 99, 99, 0.2);
margin-top: 2px;
outline: 0;
padding: 5px;
overflow: hidden;
z-index: 999;
&.top {
bottom: 35px;
transform-origin: center bottom;
}
&.bottom {
top: 35px;
transform-origin: center top;
}
&__sidebar {
position: absolute;
top: 0;
bottom: 0;
width: 100px;
height: 100%;
padding: 5px;
border-right: solid 1px #eaeaea;
}
&__shortcut {
display: block;
width: 100%;
border: 0;
background-color: transparent;
line-height: 34px;
font-size: 12px;
color: #666;
text-align: left;
outline: none;
cursor: pointer;
white-space: nowrap;
&:hover {
color: #3f97e3;
}
}
&__body {
margin-left: 100px;
padding-left: 5px;
}
}
.datepicker-inline {
position: relative;
margin-top: 0;
}
.datepicker-range {
min-width: 280px;
}
.datepicker-range .datepicker-popup {
width: 520px;
}
.datepicker-bottom {
float: left;
width: 100%;
text-align: right;
}
.datepicker-btn {
padding: 5px 10px;
background: #3f97e3;
color: #fff;
border-radius: 2px;
display: inline-block;
cursor: pointer;
}
.datepicker-anim-enter-active {
transform-origin: 0 0;
animation: datepicker-anim-in 0.2s cubic-bezier(0.23, 1, 0.32, 1);
}
.datepicker-anim-leave-active {
transform-origin: 0 0;
animation: datepicker-anim-out 0.2s cubic-bezier(0.755, 0.05, 0.855, 0.06);
}
.datepicker__buttons {
display: block;
text-align: right;
}
.datepicker__buttons button {
display: inline-block;
font-size: 13px;
border: none;
cursor: pointer;
margin: 10px 0 0 5px;
padding: 5px 15px;
color: #ffffff;
}
.datepicker__buttons .datepicker__button-select {
background: #3f97e3;
}
.datepicker__buttons .datepicker__button-cancel {
background: #666;
}
@keyframes datepicker-anim-in {
0% {
opacity: 0;
transform: scaleY(0.8);
}
to {
opacity: 1;
transform: scaleY(1);
}
}
@keyframes datepicker-anim-out {
0% {
opacity: 1;
transform: scaleY(1);
}
to {
opacity: 0;
transform: scaleY(0.8);
}
}
</style>