Skip to content

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

@Pickachu

Description

@Pickachu

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.

// The above hooks handle imperatively submitting the form, but not
// declaratively submitting the form. This happens when:
// 1. A non-custom element `<button type="submit">` is clicked.
// 2. Enter is pressed on a non-custom element text editable `<input>`.
form.addEventListener(
'submit',
() => {
// This submit was from `form.requestSubmit()`, which already calls the
// listener.
if (isNextSubmitFromHook) {
return;
}
onControlValid();
},
{
signal: cleanup,
},
);

Since submitter is already defined here, via element internals

// form.requestSubmit(submitter) does not work with form associated custom
// elements. This patches the dispatched submit event to add the correct
// `submitter`.
// See https://github.com/WICG/webcomponents/issues/814
form.addEventListener(
'submit',
(submitEvent) => {
Object.defineProperty(submitEvent, 'submitter', {
configurable: true,
enumerable: true,
get: () => submitter,
});
},
{capture: true, once: true},
);

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions