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

md-button: form validation not prevented by use of formnovalidate

Open Pickachu opened this issue 10 months ago • 1 comments

What is affected?

Component

Description

As per spec the form submission attribute formnovalidate should prevent constraint validation.

It appears that this code, does not take into account submitter attributes.

https://github.com/material-components/material-web/blob/919fe12badcfee4dcd72c390c0869dd8f996b51c/labs/behaviors/on-report-validity.ts#L298-L316

Since submitter is already defined here, via element internals https://github.com/material-components/material-web/blob/919fe12badcfee4dcd72c390c0869dd8f996b51c/internal/controller/form-submitter.ts#L110-L124

A fix seems possible by checking the submitter attribute and ignoring validation:

      // This submit was from `form.requestSubmit()`, which already calls the
      // listener.
      if (isNextSubmitFromHook) {
        return;
      }
    
      // Ignore validity check as configured by form submission attribute 
      if (event.submitter.hasAttribute('formnovalidate')) {
        return;
      }

      onControlValid();

I am not sufficient familiar with the spec, so i don't know what should happen to fields that already have constraint validation checked/visible? should them be reset or untouched? Intuitively it seems they should remain in the same state.

For curiosity, my use case is very similar to the one presented on the spec (submit the cancelation of a form):

<form action="editor.cgi" method="post">
 <p><label>Name: <input required name=fn></label></p>
 <p><label>Essay: <textarea required name=essay></textarea></label></p>
 <p><input type=submit name=submit value="Submit essay"></p>
 <p><input type=submit formnovalidate name=save value="Save essay"></p>
 <p><input type=submit formnovalidate name=cancel value="Cancel"></p>
</form>

Reproduction

Two native forms, one with a button[formnovalidate] and other with a md-outlined-button[formnovalidate]. One submits, other (wrongly) validates):

https://lit.dev/playground/#project=W3sibmFtZSI6Im1hdGVyaWFsLWltcG9...

Workaround

I have not found a workaround yet.

Is this a regression?

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

Affected versions

Failing in @material/web@npm:2.0.0

Browser/OS/Node environment

Browser: Chrome 133.0.6943.142 (Official Build) (arm64)

Pickachu avatar Mar 06 '25 00:03 Pickachu

I don't think the issue is with on-report-validity, but with how form-submitter is calling requestSubmit(), which triggers validation. We can see this in your demo by replacing the MWC text field with an <input required>. Validation is still incorrectly triggered on the input element when MWC's button is clicked.

The underlying blocker is https://github.com/WICG/webcomponents/issues/814, which stops us from calling form.requestSubmit(submitter), which should be reading the submitter's attributes and not trigger validation upon seeing formnovalidate.

asyncliz avatar Mar 06 '25 01:03 asyncliz