I'm stuck with the following question: how can I determine if an input date field is inpletely submitted? For example, if I send 12/09/aaaa
as a value, the value actually sent is null
, which is the same value I obtain if I send gg/mm/aaaa
, i.e. the empty value. Is there a way to discriminate via JS between the two cases? (Actually, I'm using Vue.js but I think it's not so important.)
I'm stuck with the following question: how can I determine if an input date field is inpletely submitted? For example, if I send 12/09/aaaa
as a value, the value actually sent is null
, which is the same value I obtain if I send gg/mm/aaaa
, i.e. the empty value. Is there a way to discriminate via JS between the two cases? (Actually, I'm using Vue.js but I think it's not so important.)
4 Answers
Reset to default 5tl;dr: No, not natively
Problem
This happens because the native HTML date input must either be empty or have a valid date according to the spec:
4.10.5.1.7 Date state (type=date)
[...] User agents must not allow the user to set the value to a non-empty string that is not a valid date string. [...]
The
value
attribute, if specified and not empty, must have a value that is a valid date string.The value sanitization algorithm is as follows: If the value of the element is not a valid date string, then set it to the empty string instead.
– reference
This means, when the input is partially filled, no matter what form or input event is triggered (submit
, change
, etc) the value of the input will be an empty string.
Solution
Checking the input's validity state
Input elements have a property named validity
to describe the validity state of the input value. In theory, you could check the badInput
or valid
properties on the input's validity state object; if badInput: true
or valid: false
is present while the value is an empty string, you could infer the input has been partially pleted. In practice, however, Safari seems to return badInput: false
and valid: true
even with a partially filled date input. See the table below:
initial (no input) | partial (e.g. 01/mm/yyyy) | |
---|---|---|
Chrome (tested on 116.0.5845.140) |
{ |
{ |
Firefox (tested on 116.0.2) |
{ |
{ |
Safari (tested on 16.6) |
{ |
{ |
This test can be run with the snippet below:
const input = document.getElementById("input");
function log({ type, target: { validity, value, }}) {
console.log({ type, validity, value });
}
log({ type: "load", target: input });
input.addEventListener("blur", log);
input.addEventListener("change", log);
<input id="input" type="date" />
Building your own custom date input
As a result, I think it's remended to build your own custom input (or use a library). This would give you full and consistent control on how partial inputs are returned and validated.
You could regex, in this case, to validate if the provided input is a valid date format.
You could use the following regex
/^\d{2}\/\d{2}\/\d{4}$/
mentioned in the answer regular expression to validate datetime format (MM/DD/YYYY)
You could use (str).match(regex) in JS to use this feature.
I have shared an approach to use, regex can be updated based on use cases.
let date = new Date('12/09/aaaa');
date == 'Invalid Date' //This will return true in date is not valid
While it wont tell you explicitly the date field is 'inplete', a useful property for a requirement like this is input.validity
Hot to get inplete datetime-local input values
there is one helpfull property you can use input.validity that will provide you with badInput customError patternMismatch rangeOverflow rangeUnderflow stepMismatch tooLong typeMismatch valid
https://developer.mozilla/en-US/docs/Web/API/ValidityState