On some browsers, inputs like date, time, datetime-local, number are not implemented and are considered as text inputs.
I made these RegExp to check these input values :
const RegExpYear = '(000[1-9]|00[1-9]\\d|0[1-9]\\d\\d|100\\d|10[1-9]\\d|1[1-9]\\d{2}|[2-9]\\d{3}|[1-9]\\d{4}|1\\d{5}|2[0-6]\\d{4}|27[0-4]\\d{3}|275[0-6]\\d{2}|2757[0-5]\\d|275760)',
      RegExpMonth ='(0[1-9]|1[012])',
      RegExpDay = '(0[1-9]|[12]\\d|3[01])',
      RegExpHour = '(0\\d|1\\d|2[0-4])',
      RegExpMinSec = '(0\\d|[1-5]\\d)',
      RegExpMilli = '(00\\d|0[1-9]\\d|[1-9]\\d{2})',
      patternWeek = new RegExp('^'+RegExpYear+'-W(([1-4][0-9])|(5[0-3])|0[1-9])$'),
      patternMonth = new RegExp('^'+RegExpYear + '-' + RegExpMonth + '$'),
      patternDateTimeLocal = new RegExp('^' + RegExpYear + '-' + RegExpMonth + '-' + RegExpDay + 'T' + RegExpHour + ':' + RegExpMinSec + '(?::' + RegExpMinSec + ')?(?:\.' + RegExpMilli + ')?$'),
      patternDate = new RegExp('^' + RegExpYear + '-' + RegExpMonth + '-' + RegExpDay + '$'),
      patternTime = new RegExp('^' + RegExpHour + ':' + RegExpMinSec + '(?::' + RegExpMinSec + ')?(?:\.' + RegExpMilli + ')?$'),
      patternNumber = new RegExp('^-?\d+\.?(\d+)?([eE][+-]?\d+)?$');
document.querySelectorAll('[type=datetime-local], [type=date], [type=time], [type=month], [type=week], [type=number]').forEach(function(a){
  let type = a.type,
      attrtype = a.attributes.getNamedItem('type').value,
      pattern;
  if (type !== attrtype) {
    switch(attrtype) {
      case 'number' : pattern = patternNumber; break;
      case 'week' : pattern = patternWeek; break;
      case 'month' : pattern = patternMonth; break;
      case 'datetime-local' : pattern = patternDateTimeLocal; break;
      case 'date' : pattern = patternDate; break;
      case 'time' : pattern = patternTime; break;
    }
    a.addEventListener('input',function(e){
      let test = pattern.test(this.value);
      if (test) {
        a.classList.add('valid')
        a.classList.remove('invalid')
      } else {
        a.classList.add('invalid')
        a.classList.remove('valid')
      }
    });
  }
});
This way I can style the wrong entries but can't prevent form submit.
Is it possible to add a constraint that passes through the ValidityState property ?
 
    