160 lines
4.1 KiB
Vue
160 lines
4.1 KiB
Vue
<template>
|
|
<div
|
|
class="control has-icons-left"
|
|
:id="docid"
|
|
>
|
|
<div
|
|
:class="`dropdown ${pos || ''} ${focused ? 'is-active' : ''}`"
|
|
style="width: 100%"
|
|
>
|
|
<div
|
|
class="dropdown-trigger"
|
|
style="width: 100%"
|
|
>
|
|
<input
|
|
:disabled="disabled"
|
|
:class="`input ${error ? 'is-danger' : ''} ${disabled ? 'has-text-dark' : ''}`"
|
|
type="text"
|
|
placeholder="DD/MM/YYYY"
|
|
maxlength="10"
|
|
@focus="setFocus"
|
|
@blur="lostFocus"
|
|
@keyup.enter="pressEnter"
|
|
@keyup="checkDate"
|
|
v-model="show"
|
|
/>
|
|
</div>
|
|
<div
|
|
class="dropdown-menu"
|
|
role="menu"
|
|
@click="doClick()"
|
|
>
|
|
<div class="dropdown-content">
|
|
<PickDay
|
|
v-bind="{ date, maxdate }"
|
|
@date="selectDate"
|
|
></PickDay>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<span class="icon is-left">
|
|
<Icon
|
|
name="material-symbols:calendar-today-outline-rounded"
|
|
:size="21"
|
|
class="has-text-grey"
|
|
/>
|
|
</span>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
export default {
|
|
props: ["record", "attr", "position", "mindate", "maxdate", "disabled"],
|
|
data() {
|
|
return {
|
|
date: undefined,
|
|
show: undefined,
|
|
error: false,
|
|
focused: false,
|
|
docid: this.$id(),
|
|
count1: 0,
|
|
count2: 0,
|
|
pos: undefined,
|
|
};
|
|
},
|
|
created() {
|
|
this.getPos();
|
|
if (this.record) {
|
|
this.date = this.record[this.attr] ? this.$copy(this.record[this.attr]) : undefined;
|
|
if (this.date) this.show = this.$dayjs(this.date).format("DD/MM/YYYY");
|
|
}
|
|
},
|
|
watch: {
|
|
record: function (newVal) {
|
|
if (this.record) {
|
|
this.date = this.record[this.attr] ? this.$copy(this.record[this.attr]) : undefined;
|
|
if (this.date) this.show = this.$dayjs(this.date).format("DD/MM/YYYY");
|
|
}
|
|
},
|
|
},
|
|
methods: {
|
|
pressEnter() {
|
|
this.checkDate();
|
|
if (!this.error) this.focused = false;
|
|
},
|
|
setFocus() {
|
|
this.focused = true;
|
|
this.count1 = 0;
|
|
this.count2 = 0;
|
|
},
|
|
lostFocus() {
|
|
let self = this;
|
|
setTimeout(() => {
|
|
if (self.focused && self.count1 === 0) self.focused = false;
|
|
}, 200);
|
|
},
|
|
processEvent(event) {
|
|
var doc = document.getElementById(this.docid);
|
|
if (!doc) return;
|
|
this.count2 += 1;
|
|
var isClickInside = false;
|
|
isClickInside = doc.contains(event.target);
|
|
if (!isClickInside && this.focused) {
|
|
if (this.count2 - 1 !== this.count1) {
|
|
this.focused = false;
|
|
this.count1 = 0;
|
|
this.count2 = 0;
|
|
}
|
|
}
|
|
},
|
|
doClick() {
|
|
this.count1 += 1;
|
|
},
|
|
selectDate(v) {
|
|
this.date = v;
|
|
this.show = this.$dayjs(v).format("DD/MM/YYYY");
|
|
this.$emit("date", this.date);
|
|
if (this.focused) this.focused = false;
|
|
this.count1 = 0;
|
|
this.count2 = 0;
|
|
},
|
|
getDate(value) {
|
|
let v = value.replace(/\D/g, "").slice(0, 10);
|
|
if (v.length >= 5) {
|
|
return `${v.slice(0, 2)}/${v.slice(2, 4)}/${v.slice(4)}`;
|
|
} else if (v.length >= 3) {
|
|
return `${v.slice(0, 2)}/${v.slice(2)}`;
|
|
}
|
|
return v;
|
|
},
|
|
checkDate() {
|
|
if (!this.focused) this.setFocus();
|
|
this.error = false;
|
|
this.date = undefined;
|
|
if (this.$empty(this.show)) return this.$emit("date", null);
|
|
this.show = this.getDate(this.show);
|
|
let val = `${this.show.substring(6, 10)}-${this.show.substring(3, 5)}-${this.show.substring(0, 2)}`;
|
|
if (this.$dayjs(val, "YYYY-MM-DD", true).isValid()) {
|
|
this.date = val;
|
|
this.$emit("date", this.date);
|
|
} else this.error = true;
|
|
},
|
|
getPos() {
|
|
switch (this.position) {
|
|
case "is-top-left":
|
|
this.pos = "is-up is-left";
|
|
break;
|
|
case "is-top-right":
|
|
this.pos = "is-up is-right";
|
|
break;
|
|
case "is-bottom-left":
|
|
this.pos = "is-left";
|
|
break;
|
|
case "is-bottom-right":
|
|
this.pos = "is-right";
|
|
break;
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|