date type input 달력, 데이트피커 추가

This commit is contained in:
yoon 2025-03-24 15:40:23 +09:00
parent 9249610442
commit 7050709c31
4 changed files with 187 additions and 43 deletions

View File

@ -40,6 +40,7 @@
class="flatpickr-calendar-only"
>
</full-calendar>
<input ref="calendarDatepicker" type="text" class="d-none" />
</div>
</div>
</div>
@ -79,7 +80,7 @@ import FullCalendar from '@fullcalendar/vue3';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import CenterModal from '@c/modal/CenterModal.vue';
import { computed, inject, onMounted, reactive, ref, watch } from 'vue';
import { computed, inject, nextTick, onMounted, reactive, ref, watch } from 'vue';
import $api from '@api';
import 'flatpickr/dist/flatpickr.min.css';
import '@/assets/css/app-calendar.css';
@ -89,6 +90,9 @@ import { useProjectStore } from '@/stores/useProjectStore';
import CommuterBtn from '@c/commuters/CommuterBtn.vue';
import CommuterProjectList from '@c/commuters/CommuterProjectList.vue';
import BackBtn from '@c/button/BackBtn.vue';
import flatpickr from 'flatpickr';
import monthSelectPlugin from 'flatpickr/dist/plugins/monthSelect/index';
import 'flatpickr/dist/plugins/monthSelect/style.css';
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
const user = ref({});
@ -110,6 +114,8 @@ const isModalOpen = ref(false);
const commuters = ref([]);
const monthlyCommuters = ref([]);
const calendarDatepicker = ref(null);
let fpInstance = null;
//
const handleWorkTimeUpdate = () => {
@ -400,5 +406,66 @@ onMounted(async () => {
selectedProject.value = storedProject.PROJCTSEQ;
checkedInProject.value = storedProject;
}
nextTick(() => {
// input
const datePickerInput = document.createElement('input');
datePickerInput.type = 'text';
datePickerInput.style.display = 'none';
document.body.appendChild(datePickerInput);
calendarDatepicker.value = datePickerInput;
// Flatpickr ( )
fpInstance = flatpickr(calendarDatepicker.value, {
dateFormat: "Y-m",
plugins: [
new monthSelectPlugin({
shorthand: true,
dateFormat: "Y-m",
altFormat: "F Y"
})
],
onOpen: function() {
document.querySelector('.flatpickr-input').style.visibility = 'hidden';
},
onChange: function(selectedDatesArr, dateStr) {
//
fullCalendarRef.value.getApi().gotoDate(dateStr + "-01");
const [year, month] = dateStr.split("-");
lastRemainingYear.value = parseInt(year, 10);
lastRemainingMonth.value = month;
loadCalendarData(lastRemainingYear.value, lastRemainingMonth.value);
},
onClose: function() {
calendarDatepicker.value.style.display = "none";
}
});
// FullCalendar (.fc-toolbar-title)
const titleEl = document.querySelector('.fc-toolbar-title');
if (titleEl) {
titleEl.style.cursor = 'pointer';
titleEl.addEventListener('click', () => {
const rect = titleEl.getBoundingClientRect();
const dpEl = calendarDatepicker.value;
dpEl.style.display = 'block';
dpEl.style.position = 'fixed';
dpEl.style.top = `${rect.bottom + window.scrollY}px`;
dpEl.style.left = `${rect.left + window.scrollX}px`;
dpEl.style.transform = 'translate(-50%, -50%)';
dpEl.style.zIndex = '9999';
dpEl.style.border = 'none';
dpEl.style.outline = 'none';
dpEl.style.backgroundColor = 'transparent';
//
// CSS transform
// dpEl.style.setProperty('--left-position', `${rect.left + window.scrollX}px`);
// dpEl.style.transform = 'translateX(-50%)';
fpInstance.open();
});
}
});
});
</script>

View File

@ -31,6 +31,8 @@
:maxLength="maxlength"
:placeholder="title"
@blur="$emit('blur')"
@click="handleDateClick"
ref="inputElement"
/>
</div>
<div class="invalid-feedback" :class="isAlert ? 'd-block' : ''">{{ title }} 확인해주세요.</div>
@ -39,7 +41,7 @@
</template>
<script setup>
import { inject, computed } from 'vue';
import { inject, computed, ref } from 'vue';
const props = defineProps({
title: {
@ -95,6 +97,7 @@
});
const emits = defineEmits(['update:data', 'update:alert', 'blur']);
const inputElement = ref(null);
// dayjs
const dayjs = inject('dayjs');
@ -123,4 +126,12 @@
emits('update:alert', false);
}
};
// date input
const handleDateClick = (event) => {
if (props.type === 'date' && inputElement.value) {
// : UI
inputElement.value.showPicker();
}
};
</script>

View File

@ -130,6 +130,7 @@
</div>
<!-- 시작일 -->
<div @click="openStartDatePicker">
<FormInput
title="시작일"
type="date"
@ -138,9 +139,11 @@
:is-alert="startDayAlert"
:modelValue="selectedProject.PROJCTSTR"
@update:modelValue="selectedProject.PROJCTSTR = $event"
ref="startDateInput"
/>
</div>
<!-- 종료일 -->
<div @click="openEndDatePicker">
<FormInput
title="종료일"
type="date"
@ -148,8 +151,9 @@
:min="selectedProject.PROJCTSTR"
:modelValue="selectedProject.PROJCTEND"
@update:modelValue="selectedProject.PROJCTEND = $event"
ref="endDateInput"
/>
</div>
<FormInput
title="설명"
name="description"
@ -288,6 +292,27 @@ const selectedUsers = ref({
});
const startDateInput = ref(null);
const endDateInput = ref(null);
// DOM
let startInputElement = null;
let endInputElement = null;
const openStartDatePicker = () => {
if (startInputElement) {
startInputElement.showPicker();
}
};
const openEndDatePicker = () => {
if (endInputElement) {
endInputElement.showPicker();
}
};
//
const handleEditUserListUpdate = (userLists) => {
selectedUsers.value = userLists;
@ -581,8 +606,18 @@ onMounted(async () => {
user.value = userStore.user;
convertAddressToCoordinates();
if (startDateInput.value) {
// FormInput input
startInputElement = startDateInput.value.$el.querySelector('input[type="date"]');
}
if (endDateInput.value) {
endInputElement = endDateInput.value.$el.querySelector('input[type="date"]');
}
});
</script>

View File

@ -71,6 +71,7 @@
</div>
</div>
<div @click="openStartDatePicker">
<FormInput
title="시작 일"
name="startDay"
@ -79,8 +80,10 @@
:is-essential="true"
:modelValue="startDay"
v-model="startDay"
ref="startDateInput"
/>
</div>
<div @click="openEndDatePicker">
<FormInput
title="종료 일"
name="endDay"
@ -88,8 +91,9 @@
:modelValue="endDay"
:min="startDay"
@update:modelValue="endDay = $event"
ref="endDateInput"
/>
</div>
<FormInput
title="설명"
name="description"
@ -165,6 +169,26 @@
const addressAlert = ref(false);
const startDayAlert = ref(false);
const startDateInput = ref(null);
const endDateInput = ref(null);
// DOM
let startInputElement = null;
let endInputElement = null;
const openStartDatePicker = () => {
if (startInputElement) {
startInputElement.showPicker();
}
};
const openEndDatePicker = () => {
if (endInputElement) {
endInputElement.showPicker();
}
};
const addressData = ref({
postcode: '',
@ -333,6 +357,13 @@
await userStore.userInfo();
user.value = userStore.user;
if (startDateInput.value) {
// FormInput input
startInputElement = startDateInput.value.$el.querySelector('input[type="date"]');
}
if (endDateInput.value) {
endInputElement = endDateInput.value.$el.querySelector('input[type="date"]');
}
});
</script>