question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

<input> minlength numeric attribute not being set on underlying element

See original GitHub issue

Sandbox

When I render <input minlength={8} /> Forgo doesn’t set the minlength attribute on the underlying DOM element.

I’m using ={8} because TypeScript insists the value needs to be a number, but if I do a string anyway the attribute still doesn’t get set.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
spiffytechcommented, Dec 2, 2021

It looks like this is because <input> elements don’t have a .minlength property, and setting the property only affects attributes if that property is specifically supported. I.e., the browser has code that forwards el["classList"] = "abc" to the element’s attributes (like web components require), but el["x-whatever"] = "abc" has no effect on the element’s attributes because the browser doesn’t explicitly forward that property to attributes.

So if we change attachProps() to look like this:

            // This optimization is copied from preact.
            else if (
              typeof value === "string" &&
              (key.startsWith("aria-") || key.startsWith("data-"))
            ) {
              (node as HTMLElement).setAttribute(key, value);
            } else if (key === "onblur") {
              (node as any)[key] = handlerDisabledOnNodeDelete(node, value);
            } else if (Reflect.has(node, key)) {
              (node as any)[key] = value;
            } else {
              (node as any).setAttribute(key, value);
            }

Then the input correctly gets its maxlength attribute set. This change also covers the aria- and data- special cases, so maybe those could be removed, too?

While the maxlength attribute is what I ran into, this reveals that there’s a broader bug that Forgo won’t set attributes like Alpine’s x-data or petite-vue’s v-scope (though I haven’t verified whether those specific examples care about attributes vs properties, and Forgo + Alpine might not make sense but I know sometimes libs work this way). This change looks like it ensure that an element gets all attributes, regardless of whether they’re spec’d or spec-compliant.

Do you have a handy benchmark to see the impact Reflect.has() has on performance? .hasOwnProperty() doesn’t do the trick, since it looks like built-in properties can come from the prototype chain, which .hasOwnProperty() won’t detect.

Edit:

This change would also make class= work, rather than requiring className, which I think is a plus.

Further reading on properties vs attributes, which I’d summarize as saying that it’s a messy situation because DOM elements are interfaced with through a JS object, but there’s an impedance mismatch that gives them subtly different behavior and I’m seeing a lot of conflicting opinions on which one is the preferred access point. But nothing shows up on-screen unless it gets set as an attribute, and properties only sometimes do that.

For reference, it looks like Alpine exclusively uses the attribute methods. Both petite-vue and preact do their checks (petite-vue, preact) using key in el and fall back to setAttribute after some other checks. Adjusting the above code snippet to key in node seems to work correctly, and seems fast enough for those frameworks.

1reaction
jeswincommented, Dec 4, 2021

Excellent bug report and solution. Fixed in v2.1.0.

Related commit: https://github.com/forgojs/forgo/commit/000afc88939eab6a4e852bc65a8a9704a2e61bd5

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why doesn't input minlength check work with initial value?
This is by design. The minlength attribute only validates a field once it has been edited by the user. It doesn't validate the...
Read more >
HTML attribute: minlength - HTML: HyperText Markup Language
The minlength attribute defines the minimum number of characters (as UTF-16 code units) the user can enter into an <input> or <textarea> ....
Read more >
How to Set a Minlength Validation in HTML5 - W3docs
In this snippet, find out what alternative attributes to minlength can be used to set a minlength validation in HTML5. Read our snippet...
Read more >
How to fix: Attribute “minlength” is only allowed when the input ...
This attribute is only allowed on elements of type email , password , search , tel , text , or url . The...
Read more >
How to specify minimum & maximum number of characters ...
To set the minimum character limit in input field, we use <input> minlength attribute. This attribute is used to specify the minimum number...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found