164 lines
4.7 KiB
Vue
164 lines
4.7 KiB
Vue
<script setup>
|
|
import { onMounted, watch, computed, ref } from 'vue';
|
|
import { date } from 'quasar';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
const model = defineModel({ type: [String, Date] });
|
|
const $props = defineProps({
|
|
isOutlined: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
showEvent: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
});
|
|
|
|
const { t } = useI18n();
|
|
const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
|
|
|
|
const dateFormat = 'DD/MM/YYYY';
|
|
const isPopupOpen = ref();
|
|
const hover = ref();
|
|
const mask = ref();
|
|
|
|
onMounted(() => {
|
|
// fix quasar bug
|
|
mask.value = '##/##/####';
|
|
});
|
|
|
|
const styleAttrs = computed(() => {
|
|
return $props.isOutlined
|
|
? {
|
|
dense: true,
|
|
outlined: true,
|
|
rounded: true,
|
|
}
|
|
: {};
|
|
});
|
|
|
|
const formattedDate = computed({
|
|
get() {
|
|
if (!model.value) return model.value;
|
|
return date.formatDate(new Date(model.value), dateFormat);
|
|
},
|
|
set(value) {
|
|
if (value == model.value) return;
|
|
let newDate;
|
|
if (value) {
|
|
// parse input
|
|
if (value.includes('/')) {
|
|
if (value.length == 6) value = value + new Date().getFullYear();
|
|
if (value.length >= 10) {
|
|
if (value.at(2) == '/') value = value.split('/').reverse().join('/');
|
|
value = date.formatDate(
|
|
new Date(value).toISOString(),
|
|
'YYYY-MM-DDTHH:mm:ss.SSSZ'
|
|
);
|
|
}
|
|
}
|
|
const [year, month, day] = value.split('-').map((e) => parseInt(e));
|
|
newDate = new Date(year, month - 1, day);
|
|
if (model.value) {
|
|
const orgDate =
|
|
model.value instanceof Date ? model.value : new Date(model.value);
|
|
|
|
newDate.setHours(
|
|
orgDate.getHours(),
|
|
orgDate.getMinutes(),
|
|
orgDate.getSeconds(),
|
|
orgDate.getMilliseconds()
|
|
);
|
|
}
|
|
}
|
|
if (!isNaN(newDate)) model.value = newDate.toISOString();
|
|
},
|
|
});
|
|
|
|
const popupDate = computed(() =>
|
|
model.value ? date.formatDate(new Date(model.value), 'YYYY/MM/DD') : model.value
|
|
);
|
|
|
|
watch(
|
|
() => model.value,
|
|
(val) => (formattedDate.value = val),
|
|
{ immediate: true }
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div @mouseover="hover = true" @mouseleave="hover = false">
|
|
<QInput
|
|
v-model="formattedDate"
|
|
class="vn-input-date"
|
|
:mask="mask"
|
|
placeholder="dd/mm/aaaa"
|
|
v-bind="{ ...$attrs, ...styleAttrs }"
|
|
:class="{ required: $attrs.required }"
|
|
:rules="$attrs.required ? [requiredFieldRule] : null"
|
|
:clearable="false"
|
|
@click="isPopupOpen = true"
|
|
>
|
|
<template #append>
|
|
<QIcon
|
|
name="close"
|
|
size="xs"
|
|
v-if="
|
|
($attrs.clearable == undefined || $attrs.clearable) &&
|
|
hover &&
|
|
model &&
|
|
!$attrs.disable
|
|
"
|
|
@click="
|
|
model = null;
|
|
isPopupOpen = false;
|
|
"
|
|
/>
|
|
<QIcon
|
|
v-if="showEvent"
|
|
name="event"
|
|
class="cursor-pointer"
|
|
@click="isPopupOpen = !isPopupOpen"
|
|
:title="t('Open date')"
|
|
/>
|
|
</template>
|
|
<QMenu
|
|
transition-show="scale"
|
|
transition-hide="scale"
|
|
v-model="isPopupOpen"
|
|
anchor="bottom left"
|
|
self="top start"
|
|
:no-focus="true"
|
|
:no-parent-event="true"
|
|
>
|
|
<QDate
|
|
v-model="popupDate"
|
|
:landscape="true"
|
|
:today-btn="true"
|
|
:options="$attrs.options"
|
|
@update:model-value="
|
|
(date) => {
|
|
formattedDate = date;
|
|
isPopupOpen = false;
|
|
}
|
|
"
|
|
/>
|
|
</QMenu>
|
|
</QInput>
|
|
</div>
|
|
</template>
|
|
<style lang="scss">
|
|
.vn-input-date.q-field--standard.q-field--readonly .q-field__control:before {
|
|
border-bottom-style: solid;
|
|
}
|
|
|
|
.vn-input-date.q-field--outlined.q-field--readonly .q-field__control:before {
|
|
border-style: solid;
|
|
}
|
|
</style>
|
|
<i18n>
|
|
es:
|
|
Open date: Abrir fecha
|
|
</i18n>
|