#6917 - inputDate_inpuTime #498
|
@ -90,7 +90,7 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
||||||
const modelValue = computed(
|
const modelValue = computed(
|
||||||
() => $props.model ?? `formModel_${route?.meta?.title ?? route.name}`
|
() => $props.model ?? `formModel_${route?.meta?.title ?? route.name}`,
|
||||||
).value;
|
).value;
|
||||||
const componentIsRendered = ref(false);
|
const componentIsRendered = ref(false);
|
||||||
const arrayData = useArrayData(modelValue);
|
const arrayData = useArrayData(modelValue);
|
||||||
|
@ -137,7 +137,7 @@ onMounted(async () => {
|
||||||
JSON.stringify(newVal) !== JSON.stringify(originalData.value);
|
JSON.stringify(newVal) !== JSON.stringify(originalData.value);
|
||||||
isResetting.value = false;
|
isResetting.value = false;
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -145,7 +145,7 @@ onMounted(async () => {
|
||||||
if (!$props.url)
|
if (!$props.url)
|
||||||
watch(
|
watch(
|
||||||
() => arrayData.store.data,
|
() => arrayData.store.data,
|
||||||
(val) => updateAndEmit('onFetch', val)
|
(val) => updateAndEmit('onFetch', val),
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(formUrl, async () => {
|
watch(formUrl, async () => {
|
||||||
|
@ -206,11 +206,11 @@ async function save() {
|
||||||
|
|
||||||
updateAndEmit('onDataSaved', formData.value, response?.data);
|
updateAndEmit('onDataSaved', formData.value, response?.data);
|
||||||
if ($props.reload) await arrayData.fetch({});
|
if ($props.reload) await arrayData.fetch({});
|
||||||
|
hasChanges.value = false;
|
||||||
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
notify('errors.writeRequest', 'negative');
|
notify('errors.writeRequest', 'negative');
|
||||||
} finally {
|
} finally {
|
||||||
hasChanges.value = false;
|
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ function filter(value, update, filterOptions) {
|
||||||
(ref) => {
|
(ref) => {
|
||||||
ref.setOptionIndex(-1);
|
ref.setOptionIndex(-1);
|
||||||
ref.moveOptionSelection(1, true);
|
ref.moveOptionSelection(1, true);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
import { date } from 'quasar';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import isValidDate from 'filters/isValidDate';
|
|
||||||
|
|
||||||
const props = defineProps({
|
const model = defineModel({ type: String });
|
||||||
modelValue: {
|
const $props = defineProps({
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
readonly: {
|
readonly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -21,64 +18,16 @@ const props = defineProps({
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const hover = ref(false);
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
|
const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
|
||||||
|
|
||||||
const joinDateAndTime = (date, time) => {
|
|
||||||
if (!date) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!time) {
|
|
||||||
return new Date(date).toISOString();
|
|
||||||
}
|
|
||||||
const [year, month, day] = date.split('/');
|
|
||||||
return new Date(`${year}-${month}-${day}T${time}`).toISOString();
|
|
||||||
};
|
|
||||||
|
|
||||||
const time = computed(() => (props.modelValue ? props.modelValue.split('T')?.[1] : null));
|
|
||||||
const value = computed({
|
|
||||||
get() {
|
|
||||||
return props.modelValue;
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
emit(
|
|
||||||
'update:modelValue',
|
|
||||||
props.emitDateFormat ? new Date(value) : joinDateAndTime(value, time.value)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const isPopupOpen = ref(false);
|
const isPopupOpen = ref(false);
|
||||||
|
const hover = ref(false);
|
||||||
const onDateUpdate = (date) => {
|
|
||||||
value.value = date;
|
|
||||||
isPopupOpen.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const padDate = (value) => value.toString().padStart(2, '0');
|
|
||||||
const formatDate = (dateString) => {
|
|
||||||
const date = new Date(dateString || '');
|
|
||||||
return `${date.getFullYear()}/${padDate(date.getMonth() + 1)}/${padDate(
|
|
||||||
date.getDate()
|
|
||||||
)}`;
|
|
||||||
};
|
|
||||||
const displayDate = (dateString) => {
|
|
||||||
if (!dateString || !isValidDate(dateString)) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return new Date(dateString).toLocaleDateString([], {
|
|
||||||
year: 'numeric',
|
|
||||||
month: '2-digit',
|
|
||||||
day: '2-digit',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const styleAttrs = computed(() => {
|
const styleAttrs = computed(() => {
|
||||||
return props.isOutlined
|
return $props.isOutlined
|
||||||
? {
|
? {
|
||||||
dense: true,
|
dense: true,
|
||||||
outlined: true,
|
outlined: true,
|
||||||
|
@ -86,42 +35,89 @@ const styleAttrs = computed(() => {
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const dateFormat = 'DD/MM/YYYY';
|
||||||
|
const formattedDate = computed({
|
||||||
|
get() {
|
||||||
|
if (!model.value) return model.value;
|
||||||
|
return date.formatDate(new Date(model.value), dateFormat);
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
let newDate;
|
||||||
|
if (value) {
|
||||||
|
// parse input
|
||||||
|
if (value.includes('/') && 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',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let ymd = value.split('-').map((e) => parseInt(e));
|
||||||
|
newDate = new Date(ymd[0], ymd[1] - 1, ymd[2]);
|
||||||
|
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,
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div @mouseover="hover = true" @mouseleave="hover = false">
|
<div @mouseover="hover = true" @mouseleave="hover = false">
|
||||||
<QInput
|
<QInput
|
||||||
|
v-model="formattedDate"
|
||||||
class="vn-input-date"
|
class="vn-input-date"
|
||||||
readonly
|
mask="##/##/####"
|
||||||
:model-value="displayDate(value)"
|
placeholder="dd/mm/aaaa"
|
||||||
v-bind="{ ...$attrs, ...styleAttrs }"
|
v-bind="{ ...$attrs, ...styleAttrs }"
|
||||||
:class="{ required: $attrs.required }"
|
:class="{ required: $attrs.required }"
|
||||||
:rules="$attrs.required ? [requiredFieldRule] : null"
|
:rules="$attrs.required ? [requiredFieldRule] : null"
|
||||||
@click="isPopupOpen = true"
|
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon
|
<QIcon
|
||||||
name="close"
|
name="close"
|
||||||
size="xs"
|
size="xs"
|
||||||
v-if="hover && value && !readonly"
|
v-if="hover && model && !readonly"
|
||||||
@click="onDateUpdate(null)"
|
@click="
|
||||||
></QIcon>
|
model = null;
|
||||||
<QIcon name="event" class="cursor-pointer">
|
isPopupOpen = false;
|
||||||
<QPopupProxy
|
"
|
||||||
v-model="isPopupOpen"
|
/>
|
||||||
cover
|
<QIcon name="event" class="cursor-pointer" />
|
||||||
transition-show="scale"
|
|
||||||
transition-hide="scale"
|
|
||||||
:no-parent-event="props.readonly"
|
|
||||||
>
|
|
||||||
<QDate
|
|
||||||
:today-btn="true"
|
|
||||||
:model-value="formatDate(value)"
|
|
||||||
@update:model-value="onDateUpdate"
|
|
||||||
/>
|
|
||||||
</QPopupProxy>
|
|
||||||
</QIcon>
|
|
||||||
</template>
|
</template>
|
||||||
|
<QMenu
|
||||||
|
transition-show="scale"
|
||||||
|
transition-hide="scale"
|
||||||
|
v-model="isPopupOpen"
|
||||||
|
anchor="bottom left"
|
||||||
|
self="top start"
|
||||||
|
:no-focus="true"
|
||||||
|
>
|
||||||
|
<QDate
|
||||||
|
v-model="popupDate"
|
||||||
|
:today-btn="true"
|
||||||
|
@update:model-value="
|
||||||
|
(date) => {
|
||||||
|
formattedDate = date;
|
||||||
|
isPopupOpen = false;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</QMenu>
|
||||||
</QInput>
|
</QInput>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue
Sino al fallar te dice que no tienes cambios, cuando realmente si hay. (Te deshabilitaba los botones)