Input Date Time v1.0
The <e-input-date-time> component is a component that can be used for datetime inputs.
Usage
An e-input-date-time has attributes that must be provided
<e-input-date-time
id=""
value=""
label=""
name=""
placeholder=""
required=""
disabled=""
meta=""
/>
Attributes : e-input-date-time extends e-input
| Value | Type | Optional | Default |
|---|---|---|---|
| value | String | yes | new Date().toDateString() |
| meta | EInputMeta_DateTime | yes | new EInputMeta_DateTime() |
Attributes : e-input
| Value | Type | Optional | Default |
|---|---|---|---|
| id | String | yes | '' |
| value | String | yes | '' |
| label | String | yes | '' |
| name | String | yes | '' |
| placeholder | String | yes | '' |
| required | Boolean | yes | false |
| disabled | Boolean | yes | false |
| meta | EInputMeta | yes | { disabled: false } |
Attributes : e-input-meta_date-time
| Value | Type | Optional | Default |
|---|---|---|---|
| disabled | Boolean | yes | false |
| dateDisabled | Boolean | yes | false |
| timeDisabled | Boolean | yes | false |
| requireTime | Boolean | yes | false |
| minDate | RawDateString | yes | '1970-01-01' |
| maxDate | RawDateString | yes | '9999-12-31' |
| minTime | HourMinuteTimeString | yes | '00:00' |
| maxTime | HourMinuteTimeString | yes | '23:59' |
Examples
Below a few interactive examples of e-input-date-time can be found.
Default
<e-input-date-time
id="dateTimeInputWithOptions"
value="-"
/>
internal labelled, label='dateTimeInput with Label'
<e-input-date-time
id="dateTimeInputWithLabel"
label="dateTimeInput with Label"
value="-"
/>
separate labelled, label='dateTimeInput with Label'
<div class="input-example-field">
<e-input-label
id="dateTimeInputWithExternalLabel"
value="dateTimeInput with Label"
/>
<e-input-date-time
id="dateTimeInputWithExternalLabel"
value="-"
/>
</div>
Source Code
e-input-date-time.vue
<script lang="ts" setup>
import { computed, ref, watch } from 'vue';
import { useDateFormat } from '@vueuse/core';
import { EInput_DateTime } from 'types/e-input/interfaces/EInput_DateTime';
export type Props = EInput_DateTime;
const props = withDefaults(defineProps<Props>(), {
value: new Date().toDateString(),
name: '',
label: '',
id: '',
placeholder: '',
required: false,
disabled: false,
meta: () => {
return {
disabled: false,
dateDisabled: false,
timeDisabled: false,
requireTime: false,
minDate: '1970-01-01',
maxDate: '9999-12-31',
minTime: '00:00',
maxTime: '23:59'
};
}
});
const emit = defineEmits<{
(e: 'blur', event: FocusEvent): void;
(e: 'keyup.enter', event: KeyboardEvent): void;
(e: 'update:value', value: string): void;
}>();
const dateInput = ref<HTMLInputElement>();
const timeInput = ref<HTMLInputElement>();
const localValue = ref(new Date(props.value));
const datePattern = ref('YYYY-MM-DD');
const timePattern = ref('HH:mm');
const localDate = useDateFormat(localValue, datePattern);
const localTime = useDateFormat(localValue, timePattern);
const isDisabled = computed(() => props.disabled ?? props.meta?.disabled);
const dateDisabled = computed(() => isDisabled.value ?? props.meta?.dateDisabled);
const minDate = computed(() => props.meta?.minDate || '1970-01-01');
const maxDate = computed(() => props.meta?.maxDate || '9999-12-31');
const dateInputData = computed(() => {
return {
id: props.id,
name: `${props.name}-date`,
inputValue: localDate.value,
disabled: dateDisabled.value,
placeholder: props.placeholder,
type: 'date',
pattern: datePattern.value,
required: props.required,
min: minDate.value,
max: maxDate.value
};
});
const timeDisabled = computed(() => isDisabled.value ?? props.meta?.timeDisabled);
const timeRequired = computed(() => props.meta?.requireTime || false);
const minTime = computed(() => props.meta?.minTime || '00:00');
const maxTime = computed(() => props.meta?.maxTime || '23:59');
const timeInputData = computed(() => {
return {
id: `${props.id}-time`,
name: `${props.name}-time`,
inputValue: localTime.value,
disabled: timeDisabled.value,
placeholder: props.placeholder,
type: 'time',
required: timeRequired.value,
pattern: timePattern.value,
min: minTime.value,
max: maxTime.value
};
});
const stateClasses = computed(() => {
return {
required: props.required,
disabled: isDisabled.value
};
});
function setLocalDate(event: InputEvent) {
const target = event.target as HTMLInputElement;
const isValid = target.checkValidity();
if (isValid) {
localValue.value.setFullYear(
target.valueAsDate.getFullYear(),
target.valueAsDate.getMonth(),
target.valueAsDate.getDate()
);
emitUpdate();
}
// TODO: nullable date support
}
function setLocalTime(event: InputEvent) {
const target = event.target as HTMLInputElement;
const isValid = timeInput.value.checkValidity();
if (isValid) {
localValue.value.setHours(target.valueAsDate.getHours(), target.valueAsDate.getMinutes(), 0);
emitUpdate();
}
}
function updateLocalValue(newValue: string) {
localValue.value = new Date(newValue);
}
function emitUpdate() {
const dateTimeString = localValue.value.toString();
emit('update:value', dateTimeString);
}
watch(
() => props.value,
(newValue, oldValue) => {
if (Date.parse(newValue) && oldValue !== newValue) {
updateLocalValue(newValue);
}
},
{
immediate: true
}
);
</script>
<template>
<div
class="e-input-date-time"
:class="stateClasses"
>
<input
:id="dateInputData.id"
ref="dateInput"
class="e-input-date"
:name="dateInputData.name"
:value="dateInputData.inputValue"
:disabled="dateInputData.disabled"
:placeholder="dateInputData.placeholder"
:type="dateInputData.type"
:required="dateInputData.required"
:pattern="dateInputData.pattern"
:min="dateInputData.min"
:max="dateInputData.max"
@input="setLocalDate"
@blur="emit('blur', $event)"
@keyup.enter="emit('keyup.enter', $event)"
/>
<input
:id="timeInputData.id"
ref="timeInput"
class="e-input-time"
:name="timeInputData.name"
:value="timeInputData.inputValue"
:disabled="timeInputData.disabled"
:placeholder="timeInputData.placeholder"
:type="timeInputData.type"
:required="timeInputData.required"
:min="timeInputData.min"
:max="timeInputData.max"
@input="setLocalTime"
@blur="emit('blur', $event)"
@keyup.enter="emit('keyup.enter', $event)"
/>
</div>
</template>
<style scoped lang="scss">
.e-input-date-time {
display: flex;
flex-direction: row;
color: var(--e-body-font-color);
gap: 10px;
input {
background-color: var(--e-input-background);
border: none;
border-radius: 15px;
color: var(--e-body-font-color);
display: flex;
flex: 1 1 auto;
flex-direction: row;
font: normal normal normal 16px/20px var(--e-body-font-family);
gap: 10px;
height: 50px;
padding: 15px;
&::placeholder {
color: var(--e-gray-300);
}
&:focus {
background-color: var(--e-input-focus-background);
}
&:not(:disabled) {
cursor: pointer;
::-webkit-calendar-picker-indicator {
cursor: pointer;
}
}
&:user-invalid,
&:out-of-range {
color: var(--e-red);
}
&:disabled {
color: var(--e-disabled);
::-webkit-calendar-picker-indicator {
cursor: not-allowed;
color: var(--e-disabled);
//TODO: task#11629 replace with e-icon for state?
}
}
}
&[required] {
+ label::after {
content: '*';
padding-left: 2px;
color: var(--e-required);
font-weight: bold;
}
}
}
</style>