opnform/resources/js/components/forms/DateInput.vue

191 lines
5.1 KiB
Vue
Raw Normal View History

2022-09-20 19:59:52 +00:00
<template>
2023-11-28 07:47:40 +00:00
<input-wrapper
2023-12-01 20:24:38 +00:00
v-bind="inputWrapperProps"
2023-11-28 07:47:40 +00:00
>
<template #label>
<slot name="label" />
</template>
2023-12-01 20:24:38 +00:00
<div v-if="!dateRange" class="flex">
<input :id="id?id:name" v-model="fromDate" :type="useTime ? 'datetime-local' : 'date'" :class="inputClasses"
:disabled="disabled?true:null"
2023-10-28 10:17:50 +00:00
:style="inputStyle" :name="name" data-date-format="YYYY-MM-DD"
:min="setMinDate" :max="setMaxDate"
2023-12-01 20:24:38 +00:00
>
</div>
2023-12-01 20:24:38 +00:00
<div v-else :class="inputClasses">
<div class="flex -mx-2">
2023-12-01 20:24:38 +00:00
<p class="text-gray-900 px-4">
From
</p>
<input :id="id?id:name" v-model="fromDate" :type="useTime ? 'datetime-local' : 'date'" :disabled="disabled?true:null"
2023-10-28 10:17:50 +00:00
:style="inputStyle" :name="name" data-date-format="YYYY-MM-DD"
class="flex-grow border-transparent focus:outline-none "
:min="setMinDate" :max="setMaxDate"
2023-12-01 20:24:38 +00:00
>
<p class="text-gray-900 px-4">
To
</p>
<input v-if="dateRange" :id="id?id:name" v-model="toDate" :type="useTime ? 'datetime-local' : 'date'"
:disabled="disabled?true:null"
2023-10-28 10:17:50 +00:00
:style="inputStyle" :name="name" class="flex-grow border-transparent focus:outline-none"
:min="setMinDate" :max="setMaxDate"
2023-12-01 20:24:38 +00:00
>
</div>
</div>
2023-11-28 07:47:40 +00:00
<template #help>
<slot name="help" />
</template>
<template #error>
<slot name="error" />
</template>
</input-wrapper>
2022-09-20 19:59:52 +00:00
</template>
<script>
2023-11-28 07:47:40 +00:00
import { inputProps, useFormInput } from './useFormInput.js'
import InputWrapper from './components/InputWrapper.vue'
2023-12-01 20:24:38 +00:00
import { fixedClasses } from '../../plugins/config/vue-tailwind/datePicker.js'
2022-09-20 19:59:52 +00:00
export default {
name: 'DateInput',
2023-11-28 07:47:40 +00:00
components: { InputWrapper },
mixins: [],
2022-09-20 19:59:52 +00:00
props: {
2023-11-28 07:47:40 +00:00
...inputProps,
2023-12-01 20:24:38 +00:00
withTime: { type: Boolean, default: false },
dateRange: { type: Boolean, default: false },
disablePastDates: { type: Boolean, default: false },
disableFutureDates: { type: Boolean, default: false }
2022-09-20 19:59:52 +00:00
},
2023-11-28 07:47:40 +00:00
setup (props, context) {
return {
2023-12-01 20:24:38 +00:00
...useFormInput(props, context)
2023-11-28 07:47:40 +00:00
}
},
2022-09-20 19:59:52 +00:00
data: () => ({
2023-11-17 10:55:10 +00:00
fixedClasses: fixedClasses,
fromDate: null,
toDate: null
2022-09-20 19:59:52 +00:00
}),
computed: {
2023-12-01 20:24:38 +00:00
inputClasses () {
let str = 'border border-gray-300 dark:bg-notion-dark-light dark:border-gray-600 dark:placeholder-gray-500 dark:text-gray-300 flex-1 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-opacity-100 placeholder-gray-400 px-4 py-2 rounded-lg shadow-sm text-base text-black text-gray-700'
str += this.dateRange ? ' w-50' : ' w-full'
str += this.disabled ? ' !cursor-not-allowed !bg-gray-200' : ''
return str
},
2023-12-01 20:24:38 +00:00
useTime () {
2022-09-20 19:59:52 +00:00
return this.withTime && !this.dateRange
},
2023-12-01 20:24:38 +00:00
setMinDate () {
if (this.disablePastDates) {
return new Date().toISOString().split('T')[0]
}
return false
},
2023-12-01 20:24:38 +00:00
setMaxDate () {
if (this.disableFutureDates) {
return new Date().toISOString().split('T')[0]
}
return false
2022-09-20 19:59:52 +00:00
}
},
watch: {
color: {
2023-12-01 20:24:38 +00:00
handler () {
2022-09-20 19:59:52 +00:00
this.setInputColor()
},
immediate: true
},
fromDate: {
2023-12-01 20:24:38 +00:00
handler (val) {
2023-10-28 10:17:50 +00:00
if (this.dateRange) {
if (!Array.isArray(this.compVal)) {
2023-12-01 20:24:38 +00:00
this.compVal = []
}
this.compVal[0] = this.dateToUTC(val)
2023-10-28 10:17:50 +00:00
} else {
this.compVal = this.dateToUTC(val)
}
},
2023-02-07 12:40:46 +00:00
immediate: false
},
toDate: {
2023-12-01 20:24:38 +00:00
handler (val) {
2023-10-28 10:17:50 +00:00
if (this.dateRange) {
if (!Array.isArray(this.compVal)) {
2023-12-01 20:24:38 +00:00
this.compVal = [null]
}
this.compVal[1] = this.dateToUTC(val)
2023-10-28 10:17:50 +00:00
} else {
this.compVal = null
}
},
2023-02-07 12:40:46 +00:00
immediate: false
2022-09-20 19:59:52 +00:00
}
},
2023-12-01 20:24:38 +00:00
mounted () {
2023-10-28 10:17:50 +00:00
if (this.compVal) {
if (Array.isArray(this.compVal)) {
this.fromDate = this.compVal[0] ?? null
this.toDate = this.compVal[1] ?? null
2023-10-28 10:17:50 +00:00
} else {
this.fromDate = this.dateToLocal(this.compVal)
}
}
2023-10-28 10:17:50 +00:00
this.fixedClasses.input = this.theme.default.input
2022-09-20 19:59:52 +00:00
this.setInputColor()
},
methods: {
/**
* Pressing enter won't submit form
* @param event
* @returns {boolean}
*/
2023-12-01 20:24:38 +00:00
onEnterPress (event) {
2022-09-20 19:59:52 +00:00
event.preventDefault()
return false
},
2023-12-01 20:24:38 +00:00
setInputColor () {
2022-09-20 19:59:52 +00:00
if (this.$refs.datepicker) {
const dateInput = this.$refs.datepicker.$el.getElementsByTagName('input')[0]
dateInput.style.setProperty('--tw-ring-color', this.color)
}
},
2023-12-01 20:24:38 +00:00
dateToUTC (val) {
2023-10-28 10:17:50 +00:00
if (!val) {
return null
}
2023-10-28 10:17:50 +00:00
if (!this.useTime) {
return val
}
return new Date(val).toISOString()
},
2023-12-01 20:24:38 +00:00
dateToLocal (val) {
2023-10-28 10:17:50 +00:00
if (!val) {
return null
}
const dateObj = new Date(val)
let dateStr = dateObj.getFullYear() + '-' +
2023-10-28 10:17:50 +00:00
String(dateObj.getMonth() + 1).padStart(2, '0') + '-' +
String(dateObj.getDate()).padStart(2, '0')
if (this.useTime) {
dateStr += 'T' + String(dateObj.getHours()).padStart(2, '0') + ':' +
2023-12-01 20:24:38 +00:00
String(dateObj.getMinutes()).padStart(2, '0')
}
return dateStr
2022-09-20 19:59:52 +00:00
}
}
}
</script>