Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTMLFormElement elements does not contain form-associated CustomElements when name attribute is shared #5891

Open
coemans opened this issue Sep 3, 2020 · 8 comments
Labels
topic: custom elements Relates to custom elements (as defined in DOM and HTML)

Comments

@coemans
Copy link

coemans commented Sep 3, 2020

My first issue here, hopefully according to the guidelines...

I've noticed that the HTMLFormElement elements function does not contain my form associated CustomElements when the name attribute is shared over multiple form-associated (custom) elements.

<form>
    <custom-checkbox name="checkbox1"></custom-checkbox>
    <custom-checkbox name="checkbox2"></custom-checkbox>
    <input type="checkbox" name="checkbox3">
    <input type="checkbox" name="checkbox4">
</form>

When I request the form elements:

document.forms[0].elements['checkbox1']; // works like a charm
document.forms[0].elements['checkbox2']; // works like a charm
document.forms[0].elements['checkbox3']; // works like a charm
document.forms[0].elements['checkbox4']; // works like a charm

So far so good, but when I use the same name on all elements, only the native ones are returned in the HTMLFormControlsCollection.

<form>
    <custom-checkbox name="checkboxes"></custom-checkbox>
    <custom-checkbox name="checkboxes"></custom-checkbox>
    <input type="checkbox" name="checkboxes">
    <input type="checkbox" name="checkboxes">
</form>

When I request the form elements:

document.forms[0].elements['checkboxes'] // returns RadioNodeList(2) [input, input, value: ""]

As you can see the RadioNodeList only contains the 2 native input elements. Is there something missing in my CustomElement described below or did I run into a bug?

export class CustomCheckbox extends HTMLElement {
  static get formAssociated() {
    return true;
  }

  constructor() {
    super();
    this.attachShadow({mode: 'open'});
    this.shadowRoot.innerHTML = `<input type="checkbox"/>`;
    this._internals = this.attachInternals();
  }

  get form() {
    return this._internals.form;
  }

  get name() {
    return this.getAttribute('name');
  }

  get type() {
    return 'checkbox';
  }

  get validity() {
    return this._internals.validity;
  }

  get validationMessage() {
    return this._internals.validationMessage;
  }

  get willValidate() {
    return this._internals.willValidate;
  }

  get checked() {
    return this._inputElement.checked;
  }

  set checked(value) {
    this._inputElement.checked = value;
  }

  get _inputElement() {
    return this.shadowRoot.querySelector('input');
  }
}

customElements.define('custom-checkbox', CustomCheckbox);
@domenic
Copy link
Member

domenic commented Sep 3, 2020

This is working as designed. RadioNodeList is a specific legacy API used for <input type=radio>; it isn't meant to be used for any other element, and certainly not new ones like custom elements.

To get a list of all custom elements with the same name, you can use document.forms[0].querySelectorAll('[name="checkboxes"]').

@domenic
Copy link
Member

domenic commented Sep 3, 2020

Hmm, although I guess maybe per spec this is supposed to work. (Even though I would have rather we disallowed it.) In that case you've probably found a Chromium bug, which I suggest filing at https://crbug.com/new.

@coemans
Copy link
Author

coemans commented Sep 3, 2020

@domenic thanks for your feedback. The native input fields in my example have type checkbox. Why does the document.forms[0].elements['checkboxes'] return a list of radios in the first place and not a list of node elements including the custom ones?

I'll (also) report it as a potential Chromium bug.

@domenic
Copy link
Member

domenic commented Sep 3, 2020

It looks like per spec it's supposed to return a list of all listed elements, including custom elements. I wish we had excluded it though. Legacy features like RadioNodeList should be quarantined and not allowed to interact with new features like custom elements. Oh well.

I'll close this since the spec works in the manner you prefer.

@domenic domenic closed this as completed Sep 3, 2020
@domenic domenic added the topic: custom elements Relates to custom elements (as defined in DOM and HTML) label Sep 3, 2020
@coemans
Copy link
Author

coemans commented Sep 3, 2020

Quoted from the form-element spec:

The elements IDL attribute must return an HTMLFormControlsCollection rooted at the form element's root, whose filter matches listed elements whose form owner is the form element, with the exception of input elements whose type attribute is in the Image Button state, which must, for historical reasons, be excluded from this particular collection.

Listed elements
Denotes elements that are listed in the form.elements and fieldset.elements APIs. These elements also have a form content attribute, and a matching form IDL attribute, that allow authors to specify an explicit form owner.
button, fieldset, input, object, output, select, textarea, form-associated custom elements

In my humble opinion there seems to be a difference between the spec and the behaviour or am I wrong?

@domenic
Copy link
Member

domenic commented Sep 3, 2020

Correct. That's why it's a browser bug, because the browser does not match the spec.

@coemans
Copy link
Author

coemans commented Sep 3, 2020

Crystal clear, I'll report it as a Chromium bug and this issue is indeed correctly closed. Thank you for the surprisingly fast feedback and support.

@annevk
Copy link
Member

annevk commented Sep 7, 2020

@domenic wait, Chrome is the only browser that ships this. Why not change the standard if that's preferable?

@annevk annevk reopened this Sep 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: custom elements Relates to custom elements (as defined in DOM and HTML)
Development

No branches or pull requests

3 participants