material-web icon indicating copy to clipboard operation
material-web copied to clipboard

Validator do not allow customError

Open christophe-g opened this issue 1 year ago • 2 comments

What is affected?

Accessibility, Component

Description

A validator using setCustomValidity as below will never cause an invalid event to be dispatched.

export class MyValidator extends Validator<any>{
  private checkboxControl?: HTMLInputElement;

  protected override computeValidity(state) {
    if (!this.checkboxControl) {
      this.checkboxControl = document.createElement('input');
      this.checkboxControl.type = 'checkbox';
    }
    this.checkboxControl.setCustomValidity('Get rid of me');
    
    console.warn('I should be invalid', this.checkboxControl.validity)
    return {
      validity: this.checkboxControl.validity,
      validationMessage: this.checkboxControl.validationMessage,
    };
  }

This is due to the Safari workaround here, causing the customError flag to always be false.

Otherwise new validators are great

Reproduction

https://lit.dev/playground/#gist=2fecd21c77070203e5472131ffc9b199

Workaround

Force an error on another flag, but this is not really nice:

 protected override computeValidity(state: RecordState) {
    if (!this.selectControl) {
      // Lazily create the platform select
      this.selectControl = document.createElement('input');
    }
    let customError = '';
    if(state.currentDuration > state.maxDuration) {
      customError = 'Recording is too long';
    }
    if(customError) {
      // we force an error because validator [syncValidation] has a bug
      // with customError
      this.selectControl.value = '';
      this.selectControl.required = true;  
      this.selectControl.setCustomValidity(customError);
    } else {
      this.selectControl.value = state.value;
      this.selectControl.required = state.required;
    }
    return {
      validity: this.selectControl.validity,
      validationMessage: customError || this.selectControl.validationMessage,
      // validationMessage: this.selectControl.validationMessage,
    };
  }

Is this a regression?

No or unsure. This never worked, or I haven't tried before.

Affected versions

Failing in v1.1.1

Browser/OS/Node environment

Latest chrome on linux

christophe-g avatar Dec 15 '23 10:12 christophe-g

I think this could be supported by changing this line in the constraint validation mixin to also check the Validator's computed custom error:

const customError = !!this[privateCustomValidationMessage] || validity.customError;

Calling myControl.setCustomValidity('user-set error') would then override any custom errors the control set for itself.

Want to send in a PR?

asyncliz avatar Dec 15 '23 17:12 asyncliz

Want to send in a PR?

Yep, Will send one early next week.

christophe-g avatar Dec 15 '23 17:12 christophe-g