changes
This commit is contained in:
@@ -1,19 +1,13 @@
|
||||
<template>
|
||||
<div
|
||||
class="control has-icons-left"
|
||||
:id="docid"
|
||||
ref="datepickerRoot"
|
||||
>
|
||||
<div
|
||||
:class="`dropdown ${pos || ''} ${focused ? 'is-active' : ''}`"
|
||||
style="width: 100%"
|
||||
>
|
||||
<div
|
||||
class="dropdown-trigger"
|
||||
style="width: 100%"
|
||||
>
|
||||
<div :class="['dropdown w-full', pos, focused && 'is-active']">
|
||||
<div class="dropdown-trigger w-full">
|
||||
<input
|
||||
:disabled="disabled"
|
||||
:class="`input ${error ? 'is-danger' : ''} ${disabled ? 'has-text-dark' : ''}`"
|
||||
:class="['input', error && 'is-danger', disabled && 'has-text-dark']"
|
||||
type="text"
|
||||
placeholder="DD/MM/YYYY"
|
||||
maxlength="10"
|
||||
@@ -33,7 +27,7 @@
|
||||
<PickDay
|
||||
v-bind="{ date, maxdate }"
|
||||
@date="selectDate"
|
||||
></PickDay>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,119 +35,131 @@
|
||||
<Icon
|
||||
name="material-symbols:calendar-today-outline-rounded"
|
||||
:size="21"
|
||||
class="has-text-grey"
|
||||
:class="focused ? 'has-text-primary' : '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");
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
record: Object,
|
||||
attr: String,
|
||||
position: String,
|
||||
mindate: String,
|
||||
maxdate: String,
|
||||
disabled: Boolean,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["date"]);
|
||||
const { $id, $copy, $dayjs, $empty } = useNuxtApp();
|
||||
|
||||
const date = ref();
|
||||
const show = ref();
|
||||
const error = ref(false);
|
||||
const focused = ref(false);
|
||||
const count1 = ref(0);
|
||||
const count2 = ref(0);
|
||||
const pos = ref();
|
||||
const datepickerRoot = useTemplateRef("datepickerRoot");
|
||||
|
||||
function getPos() {
|
||||
switch (props.position) {
|
||||
case "is-top-left":
|
||||
pos.value = "is-up is-left";
|
||||
break;
|
||||
case "is-top-right":
|
||||
pos.value = "is-up is-right";
|
||||
break;
|
||||
case "is-bottom-left":
|
||||
pos.value = "is-left";
|
||||
break;
|
||||
case "is-bottom-right":
|
||||
pos.value = "is-right";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function initializeDate() {
|
||||
if (props.record) {
|
||||
date.value = props.record[props.attr] ? $copy(props.record[props.attr]) : undefined;
|
||||
if (date.value) show.value = $dayjs(date.value).format("L");
|
||||
}
|
||||
}
|
||||
|
||||
function pressEnter() {
|
||||
checkDate();
|
||||
if (!error.value) focused.value = false;
|
||||
}
|
||||
|
||||
function setFocus() {
|
||||
focused.value = true;
|
||||
count1.value = 0;
|
||||
count2.value = 0;
|
||||
}
|
||||
|
||||
function lostFocus() {
|
||||
setTimeout(() => {
|
||||
if (focused.value && count1.value === 0) focused.value = false;
|
||||
}, 200);
|
||||
}
|
||||
|
||||
function processEvent(event) {
|
||||
count2.value += 1;
|
||||
const isClickInside = datepickerRoot.value.contains(event.target);
|
||||
if (!isClickInside && focused.value) {
|
||||
if (count2.value - 1 !== count1.value) {
|
||||
focused.value = false;
|
||||
count1.value = 0;
|
||||
count2.value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function doClick() {
|
||||
count1.value += 1;
|
||||
}
|
||||
|
||||
function selectDate(v) {
|
||||
date.value = v;
|
||||
show.value = $dayjs(v).format("L");
|
||||
emit("date", date.value);
|
||||
if (focused.value) focused.value = false;
|
||||
count1.value = 0;
|
||||
count2.value = 0;
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
|
||||
function checkDate() {
|
||||
if (!focused.value) setFocus();
|
||||
error.value = false;
|
||||
date.value = undefined;
|
||||
if ($empty(show.value)) return emit("date", null);
|
||||
show.value = getDate(show.value);
|
||||
let val = `${show.value.substring(6, 10)}-${show.value.substring(3, 5)}-${show.value.substring(0, 2)}`;
|
||||
if ($dayjs(val, "YYYY-MM-DD", true).isValid()) {
|
||||
date.value = val;
|
||||
emit("date", date.value);
|
||||
} else error.value = true;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getPos();
|
||||
initializeDate();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.record,
|
||||
() => {
|
||||
initializeDate();
|
||||
},
|
||||
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>
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<span
|
||||
class="has-text-primary hyperlink"
|
||||
@click="chooseToday()"
|
||||
>{{ $dayjs(today).format("DD/MM/YYYY") }}</span
|
||||
>{{ $dayjs(today).format("L") }}</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -56,26 +56,26 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:class="`columns is-mobile mx-0 mb-1 ${i === weeks.length - 1 ? 'mb-1' : ''}`"
|
||||
v-for="(v, i) in weeks"
|
||||
:key="i"
|
||||
:class="`columns is-mobile mx-0 mb-1 ${i === weeks.length - 1 ? 'mb-1' : ''}`"
|
||||
>
|
||||
<div
|
||||
class="column p-0 is-flex is-justify-content-center is-align-items-center"
|
||||
style="width: 40px; height: 32px"
|
||||
v-for="(m, h) in v.dates"
|
||||
:key="h"
|
||||
class="column p-0 is-flex is-justify-content-center is-align-items-center"
|
||||
style="width: 40px; height: 32px"
|
||||
>
|
||||
<span
|
||||
class="fs-13 has-text-grey-80"
|
||||
v-if="m.disable"
|
||||
class="fs-13 has-text-grey-80"
|
||||
>
|
||||
{{ m.dayPrint }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
class="fs-13 is-clickable"
|
||||
@click="choose(m)"
|
||||
v-else
|
||||
>
|
||||
<span
|
||||
style="width: 25px; height: 25px"
|
||||
@@ -96,36 +96,33 @@
|
||||
<hr class="my-1" />
|
||||
<div class="mt-2 fs-14">
|
||||
<span class="ml-2">Hôm nay: </span>
|
||||
<a
|
||||
class="has-text-primary"
|
||||
@click="chooseToday()"
|
||||
>{{ $dayjs(today).format("DD/MM/YYYY") }}</a
|
||||
>
|
||||
<a @click="chooseToday()">{{ $dayjs(today).format("L") }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<PickMonth
|
||||
v-else-if="type === 'months'"
|
||||
@month="selectMonth"
|
||||
></PickMonth>
|
||||
/>
|
||||
<PickYear
|
||||
v-else-if="type === 'years'"
|
||||
v-bind="{ year, month, action }"
|
||||
@year="selectYear"
|
||||
@caption="changeCaption"
|
||||
></PickYear>
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import PickMonth from "@/components/datepicker/PickMonth";
|
||||
import PickYear from "@/components/datepicker/PickYear";
|
||||
|
||||
const { $id, $dayjs, $unique } = useNuxtApp();
|
||||
const emit = defineEmits(["date"]);
|
||||
var props = defineProps({
|
||||
const props = defineProps({
|
||||
date: String,
|
||||
maxdate: String,
|
||||
});
|
||||
var dates = [];
|
||||
var dateOfWeek = [
|
||||
const dates = ref([]);
|
||||
const dateOfWeek = [
|
||||
{ id: 0, text: "CN" },
|
||||
{ id: 1, text: "T2" },
|
||||
{ id: 2, text: "T3" },
|
||||
@@ -134,18 +131,19 @@ var dateOfWeek = [
|
||||
{ id: 5, text: "T6" },
|
||||
{ id: 6, text: "T7" },
|
||||
];
|
||||
var weeks = ref([]);
|
||||
var year = ref(undefined);
|
||||
var month = undefined;
|
||||
var type = ref("days");
|
||||
var caption = ref(undefined);
|
||||
var action = ref(undefined);
|
||||
var curdate = undefined;
|
||||
var today = new Date();
|
||||
const weeks = ref([]);
|
||||
const year = ref();
|
||||
let month;
|
||||
const type = ref("days");
|
||||
const caption = ref();
|
||||
const action = ref();
|
||||
const curdate = ref();
|
||||
const today = new Date();
|
||||
|
||||
function showDate() {
|
||||
curdate = props.date ? props.date.replaceAll("-", "/") : undefined;
|
||||
year.value = $dayjs(curdate || today).year();
|
||||
month = $dayjs(curdate || today).month() + 1;
|
||||
curdate.value = props.date ? props.date.replaceAll("-", "/") : undefined;
|
||||
year.value = $dayjs(curdate.value || today).year();
|
||||
month = $dayjs(curdate.value || today).month() + 1;
|
||||
getDates();
|
||||
}
|
||||
function chooseToday() {
|
||||
@@ -169,12 +167,12 @@ function selectYear(v) {
|
||||
}
|
||||
function getDates() {
|
||||
caption.value = undefined;
|
||||
dates = allDaysInMonth(year.value, month);
|
||||
weeks.value = $unique(dates, ["week"]).map((v) => {
|
||||
dates.value = allDaysInMonth(year.value, month);
|
||||
weeks.value = $unique(dates.value, ["week"]).map((v) => {
|
||||
return { week: v.week };
|
||||
});
|
||||
weeks.value.map((v) => {
|
||||
v.dates = dates.filter((x) => x.week === v.week);
|
||||
v.dates = dates.value.filter((x) => x.week === v.week);
|
||||
});
|
||||
}
|
||||
function nextMonth() {
|
||||
@@ -248,7 +246,7 @@ showDate();
|
||||
// change date
|
||||
watch(
|
||||
() => props.date,
|
||||
(newVal, oldVal) => {
|
||||
() => {
|
||||
showDate();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
<template>
|
||||
<div class="columns is-mobile is-multiline mx-0">
|
||||
<span
|
||||
v-for="month in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]"
|
||||
:id="String(month)"
|
||||
class="column has-text-centered is-4 is-clickable fs-14"
|
||||
v-for="v in months"
|
||||
@click="$emit('month', v)"
|
||||
>Tháng {{ v }}</span
|
||||
>
|
||||
@click="$emit('month', month)"
|
||||
>Tháng {{ month }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,65 +1,53 @@
|
||||
<template>
|
||||
<div class="columns is-mobile is-multiline mx-0">
|
||||
<span
|
||||
v-for="(v, i) in years"
|
||||
class="column is-4 has-text-centered is-clickable fs-14"
|
||||
:class="i === 0 || i === 11 ? 'has-text-grey-light' : ''"
|
||||
@click="$emit('year', v)"
|
||||
>{{ v }}</span
|
||||
v-for="(year, i) in years"
|
||||
:key="year"
|
||||
:class="['column is-4 has-text-centered is-clickable fs-14', (i === 0 || i === 11) && 'has-text-grey-light']"
|
||||
@click="$emit('year', year)"
|
||||
>
|
||||
{{ year }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: ["year", "month", "action"],
|
||||
data() {
|
||||
return {
|
||||
years: [],
|
||||
};
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
year: Number,
|
||||
month: Number,
|
||||
action: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["caption"]);
|
||||
const years = ref(
|
||||
Array.from({ length: 12 })
|
||||
.fill(props.year)
|
||||
.map((y, i) => y + i - 6),
|
||||
);
|
||||
emit("caption", `${years.value[1]} – ${years.value[10]}`);
|
||||
|
||||
watch(
|
||||
() => props.action,
|
||||
(newVal) => {
|
||||
if (newVal.name === "next") next();
|
||||
if (newVal.name === "previous") previous();
|
||||
},
|
||||
created() {
|
||||
this.years = [this.year];
|
||||
for (let i = 1; i < 7; i++) {
|
||||
this.years.push(this.year + i);
|
||||
this.years.push(this.year - i);
|
||||
}
|
||||
this.years.sort(function (a, b) {
|
||||
return a - b;
|
||||
});
|
||||
this.years = this.years.slice(0, 12);
|
||||
this.$emit("caption", `${this.years[1]}-${this.years[10]}`);
|
||||
},
|
||||
watch: {
|
||||
action: function (newVal) {
|
||||
if (newVal.name === "next") this.next();
|
||||
if (newVal.name === "previous") this.previous();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
next() {
|
||||
let year = this.years[this.years.length - 1];
|
||||
this.years = [];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
this.years.push(year + i);
|
||||
}
|
||||
this.years.sort(function (a, b) {
|
||||
return a - b;
|
||||
});
|
||||
this.years = this.years.slice(0, 12);
|
||||
this.$emit("caption", `${this.years[1]}-${this.years[10]}`);
|
||||
},
|
||||
previous() {
|
||||
let year = this.years[0];
|
||||
this.years = [];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
this.years.push(year - i);
|
||||
}
|
||||
this.years.sort(function (a, b) {
|
||||
return a - b;
|
||||
});
|
||||
this.years = this.years.slice(0, 12);
|
||||
this.$emit("caption", `${this.years[1]}-${this.years[10]}`);
|
||||
},
|
||||
},
|
||||
};
|
||||
);
|
||||
|
||||
watch(years, () => {
|
||||
emit("caption", `${years.value[1]} – ${years.value[10]}`);
|
||||
});
|
||||
|
||||
function next() {
|
||||
const baseYear = years.value[11];
|
||||
years.value = Array.from({ length: 12 })
|
||||
.fill(baseYear)
|
||||
.map((y, i) => y + i - 6);
|
||||
}
|
||||
|
||||
function previous() {
|
||||
const baseYear = years.value[0];
|
||||
years.value = Array.from({ length: 12 })
|
||||
.fill(baseYear)
|
||||
.map((y, i) => y + i - 6);
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user