117 lines
3.1 KiB
Vue
117 lines
3.1 KiB
Vue
<script setup>
|
|
import { watch, computed, ref } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { date } from 'quasar';
|
|
|
|
const model = defineModel({ type: String });
|
|
const props = defineProps({
|
|
timeOnly: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
isOutlined: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
});
|
|
const { t } = useI18n();
|
|
const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
|
|
|
|
const dateFormat = 'HH:mm';
|
|
const isPopupOpen = ref();
|
|
const hover = ref();
|
|
|
|
const styleAttrs = computed(() => {
|
|
return props.isOutlined
|
|
? {
|
|
dense: true,
|
|
outlined: true,
|
|
rounded: true,
|
|
}
|
|
: {};
|
|
});
|
|
|
|
const formattedTime = computed({
|
|
get() {
|
|
if (!model.value || model.value?.length <= 5) return model.value;
|
|
return dateToTime(model.value);
|
|
},
|
|
set(value) {
|
|
if (value == model.value) return;
|
|
let time = value;
|
|
if (time) {
|
|
if (time?.length > 5) time = dateToTime(time);
|
|
if (!props.timeOnly) {
|
|
const hours = time.split(':');
|
|
const date = new Date(model.value);
|
|
date.setHours(hours[0], hours[1], 0);
|
|
time = date.toISOString();
|
|
}
|
|
}
|
|
model.value = time;
|
|
},
|
|
});
|
|
|
|
function dateToTime(newDate) {
|
|
return date.formatDate(new Date(newDate), dateFormat);
|
|
}
|
|
|
|
watch(
|
|
() => model.value,
|
|
(val) => (formattedTime.value = val),
|
|
{ immediate: true }
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div @mouseover="hover = true" @mouseleave="hover = false">
|
|
<QInput
|
|
class="vn-input-time"
|
|
mask="##:##"
|
|
placeholder="--:--"
|
|
v-model="formattedTime"
|
|
v-bind="{ ...$attrs, ...styleAttrs }"
|
|
:class="{ required: $attrs.required }"
|
|
style="min-width: 100px"
|
|
:rules="$attrs.required ? [requiredFieldRule] : null"
|
|
>
|
|
<template #append>
|
|
<QIcon
|
|
name="close"
|
|
size="xs"
|
|
v-if="
|
|
($attrs.clearable == undefined || $attrs.clearable) &&
|
|
hover &&
|
|
model &&
|
|
!$attrs.disable
|
|
"
|
|
@click="
|
|
model = null;
|
|
isPopupOpen = false;
|
|
"
|
|
/>
|
|
<QIcon name="Schedule" class="cursor-pointer" />
|
|
</template>
|
|
<QMenu
|
|
transition-show="scale"
|
|
transition-hide="scale"
|
|
v-model="isPopupOpen"
|
|
anchor="bottom left"
|
|
self="top start"
|
|
:no-focus="true"
|
|
>
|
|
<QTime v-model="formattedTime" mask="HH:mm" landscape now-btn />
|
|
</QMenu>
|
|
</QInput>
|
|
</div>
|
|
</template>
|
|
<style lang="scss">
|
|
.vn-input-time.q-field--standard.q-field--readonly .q-field__control:before {
|
|
border-bottom-style: solid;
|
|
}
|
|
|
|
.vn-input-time.q-field--outlined.q-field--readonly .q-field__control:before {
|
|
border-style: solid;
|
|
}
|
|
</style>
|