3

I'm stuck with the following question: how can I determine if an input date field is incompletely 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.)

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Diogenes
  • 135
  • 4

4 Answers4

4

tl;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 completed. 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)
{
  value: "",
  validity: {
    badInput: false,
    valid: true
  }
{
  value: "",
  validity: {
    badInput: true,
    valid: false
  }
Firefox
(tested on 116.0.2)
{
  value: "",
  validity: {
    badInput: false,
    valid: true
  }
{
  value: "",
  validity: {
    badInput: true,
    valid: false
  }
Safari
(tested on 16.6)
{
  value: "",
  validity: {
    badInput: false,
    valid: true
  }
{
  value: "",
  validity: {
    badInput: false,
    valid: true
  }

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 recommended 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.

Wing
  • 8,438
  • 4
  • 37
  • 46
  • @hcpl: FYI your edit has been significantly changed as I've added details on the option of checking the input's validity state (and why it might not be a good idea). If you wish, you can go into the revision history and post your edit as a standalone answer. – Wing Sep 01 '23 at 13:47
  • no worries, valid info added – hcpl Sep 01 '23 at 17:08
1

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.

Omkar
  • 157
  • 1
  • 9
  • This only shows how to validate a date value, the issue here is that the value is set to an empty string `''` whenever the date entered is invalid because of HTML specifications (see accepted answers for details). – hcpl Aug 29 '23 at 06:24
1

let date = new Date('12/09/aaaa');

date == 'Invalid Date' //This will return true in date is not valid

sojin
  • 2,158
  • 1
  • 10
  • 18
0

While it wont tell you explicitly the date field is 'incomplete', a useful property for a requirement like this is input.validity

Hot to get incomplete 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.org/en-US/docs/Web/API/ValidityState

  • This is likely to be user-agent specific, though. Safari (15.6, haven't tested with a newer version) will happily give you `valid: true` on the ValidityState for a partially-filled date. – Jeremy Frey Nov 28 '22 at 16:26