Input Date Time Local v1.0
The <e-input-date-time-local> component is a component that can be used for date-time-local input.
Usage
An e-input-date-time-local has attributes that should be provided
<e-input-date-time-local
id=""
value=""
label=""
name=""
placeholder=""
required=""
disabled=""
meta=""
/>
Attributes : e-input-date-time-local extends e-input
| Value | Type | Optional | Default |
|---|---|---|---|
| value | String | yes | new Date().toDateString() |
| meta | EInputMeta_DateTimeLocal | yes | new EInputMeta_DateTimeLocal() |
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-local
| 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' |
Examples
Below a few interactive examples of e-input-date-time-local can be found.
Default
<e-input-date-time-local
id="dateTimeLocalInputWithOptions"
value="-"
/>
internal labelled, label='dateTimeLocalInput with Label'
<e-input-date-time-local
id="dateTimeLocalInputWithLabel"
label="dateTimeLocalInput with Label"
value="-"
/>
separate labelled, label='dateTimeLocalInput with Label'
<div class="input-example-field">
<e-input-label
id="dateTimeLocalInputWithExternalLabel"
value="dateTimeLocalInput with Label"
/>
<e-input-date-time-local
id="dateTimeLocalInputWithExternalLabel"
value="-"
/>
</div>
Source Code
e-input-date-time-local.vue
<script lang="ts" setup>
import { computed, ref, watch } from 'vue';
import { useDateFormat } from '@vueuse/core';
import { size } from 'lodash-es';
import { EInput_DateTimeLocal } from 'types/e-input/interfaces/EInput_DateTimeLocal';
export type Props = EInput_DateTimeLocal;
const props = withDefaults(defineProps<Props>(), {
value: new Date().toString(),
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'
};
}
});
const emit = defineEmits<{
(e: 'blur', event: FocusEvent): void;
(e: 'keyup.enter', event: KeyboardEvent): void;
(e: 'update:validity', value: boolean): void;
(e: 'update:value', value: string): void;
}>();
const input = ref<HTMLInputElement>();
const localValue = ref(new Date(props.value));
const datePattern = ref('YYYY-MM-DDTHH:mm');
const formattedValue = useDateFormat(localValue, datePattern);
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 inputData = computed(() => {
return {
id: props.id,
name: props.name,
inputValue: formattedValue.value,
disabled: dateDisabled.value,
placeholder: props.placeholder,
type: 'datetime-local',
pattern: datePattern.value,
required: props.required,
min: minDate.value,
max: maxDate.value
};
});
const stateClasses = computed(() => {
return {
required: props.required,
disabled: dateDisabled.value
};
});
async function setLocalDate(event: InputEvent) {
const target = event.target as HTMLInputElement;
const newValue = target.value;
const isValid = target.checkValidity();
const dateValue = new Date(target.value);
const yearString = dateValue.getFullYear().toString();
const yearDigits = size(yearString);
const validYearCount = yearDigits >= 4;
if (validYearCount) {
// cap years to 4 digit
dateValue.setFullYear(Number.parseInt(dateValue.getFullYear().toString().substring(0, 4)));
}
emit('update:validity', isValid && validYearCount);
if (isValid && validYearCount) {
updateLocalValue(newValue);
}
emitUpdate();
// TODO: nullable date support
}
function updateLocalValue(newValue: string) {
localValue.value = new Date(newValue);
}
function emitUpdate() {
const dateTimeString = localValue.value.toUTCString();
emit('update:value', dateTimeString);
}
watch(
() => props.value,
(newValue, oldValue) => {
if (Date.parse(newValue) && oldValue !== newValue) {
updateLocalValue(newValue);
}
},
{
immediate: true
}
);
</script>
<template>
<input
:id="inputData.id"
ref="input"
class="e-input-date-time-local"
:class="stateClasses"
:name="inputData.name"
:value="inputData.inputValue"
:disabled="inputData.disabled"
:placeholder="inputData.placeholder"
:type="inputData.type"
:required="inputData.required"
:pattern="inputData.pattern"
:min="inputData.min"
:max="inputData.max"
@input="setLocalDate"
@blur="emit('blur', $event)"
@keyup.enter="emit('keyup.enter', $event)"
/>
</template>
<style scoped lang="scss">
.e-input-date-time-local {
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;
}
}
&.disabled {
.input-container {
label {
cursor: not-allowed;
user-input: none;
}
}
}
}
</style>