vaadin / web-components

A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
https://vaadin.com/docs/latest/components
462 stars 83 forks source link

[vaadin-text-field] Consider removing `maxlength` attribute from input fields #7982

Open knoobie opened 2 weeks ago

knoobie commented 2 weeks ago

Describe your motivation

I was thinking about applying maxlength from flow side to the fields.. but I stumpled upon the problem that it does not trigger server side validation as expexted and just trims copy paste.. won't let the user input more character than allowed and so on.. creating really bad UX..

More details why it's bad here: https://adamsilver.io/blog/dont-use-the-maxlength-attribute-to-stop-users-from-exceeding-the-limit/

Edit: You could even call it an accessibility problem - see https://www.tempertemper.net/blog/dont-meddle-with-user-input

Describe the solution you'd like

Adding maxlength to a field is announced to screen reader users, but users are not prevented to enter or copy paste more content into the field - the client should allow it and the server side should check and reject it correctly - WITH an error message.

Describe alternatives you've considered

Not using the feature - like always, just relying on StringLengthValidator by flow.

Additional context

No response

web-padawan commented 2 weeks ago

I stumpled upon the problem that it does not trigger server side validation as expected and just trims copy paste.

Did some research and it sounds like this behavior is kind of controversial, for example:

IMO we shouldn't remove this API due to how it's implemented in browsers. Sounds like we can handle pasted text by preventing the paste event, setting the value programmatically on the <input> and then validating it:

_onPaste(e) {
  if (this.maxlength) {
    const pastedText = e.clipboardData.getData('text');
    if (pastedText.length > this.maxlength) {
      e.preventDefault();
      this.inputElement.value = pastedText;
      this.validate();
    }
  }

  // ... other paste logic
}

The problem is that native checkValidity() returns true and the validity.tooLong is not reported. So we'd need to implement our own validation for maxlength constraint to ensure the components that support it work properly.

knoobie commented 2 weeks ago

it sounds like this behavior is kind of controversial

Can confirm! Feels like a rabbit hole :)

While copy paste is one side of the problem - another (probably) even bigger problem is that I can't type more character into the field. Let say you quickly filling out the form and type 12345 without looking at the field.. press tab.. fill out the rest and you never realized that the field skipped 5 because it just ignored everything you have typed after the first 4 character with maxlength=4. Yes, Users "should" check what is submitted.. but that's not always the case.

With proper error handling (at least server side); 12345 stays in the field and validation is triggered to fail making the problem obvious for user.