WebReflection/uhtml

Cannot set property list of #<HTMLInputElement> which has only a getter

Closed this issue · 10 comments

I'm trying v4 for my project.

I need to set the list attribute on an input. v4 of uhtml is producing the error Cannot set property list of #<HTMLInputElement> which has only a getter.

I'm guessing the name in Element test succeeds because it has a getter but the direct set fails because there is no setter.

My theory is wrong but if I remove the list=${listid} from my template I don't get that error.

Here is a minimal example.

import { render, html } from "uhtml";

function main() {
  const listname = "alist";
  render(document.body, html`<input list=${listname} />`);
}

main();

v3 had purposely the .list=${...} disambiguation but that's honestly an edge case to me ... however, as I want v4 to be as surprise-free as possible, I might as well use getownPropertyDescriptor once in the template to be parsed and, if that's either a writable or an accessor with a getter, pass the value through, otherwise use the getter only thing that side-effects on properties changes ... that being said: what is list if I might ask? First time I hear of such attribute for inputs, and if it's something new I am not excluding there's a bug in the current specs unless it's yet another dataset like indirection, thanks!

The list attribute of input is the way you link the input to the associated
datalist element.

nowhere in the specs or MDN states that this is a read-only attribute and I don't understand why that should be the case (imagining interchangeable datalists arouund) ... but there are cases that attribute is accepted (a few types) but unaccepted in other cases ... your minimal example doesn't have a datalist usable around neither, so it might be incomplete ... can you please find any explicit statement in the specs this should be a get only accessor?

I can see that myself by doing Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'list') but I can't find a reason for this to be acceptable, as most accessors in DOM allow set too ... this is weird, although I am planning to fix it.

Sorry, I should have included a datalist. Here is a more complete example below.

I agree it is strange that it should be read-only. It behaves the same in Firefox and Chrome. I can't find a statement that should only have a getter.

import { render, html } from "uhtml";

function main() {
  const listname = "alist";
  render(
    document.body,
    html`
      <datalist id="alist">
        <option value="Chocolate"></option>
        <option value="Coconut"></option>
        <option value="Mint"></option>
        <option value="Strawberry"></option>
        <option value="Vanilla"></option>
      </datalist>
      <input list=${listname} />
    `,
  );
}

main();

I see people complaining about it as recently 7 months ago and as long as 10 years ago.

Found it! https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement

list Read only
Returns the element pointed to by the [list](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#list) 
attribute. The property may be null if no HTML element is found in the same tree.

Fixed with latest

Thanks. Working now.