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

feat: add i18n error message support for TextField #6343

Merged
merged 11 commits into from
Jul 19, 2024

Conversation

vursen
Copy link
Contributor

@vursen vursen commented Jun 3, 2024

Description

The PR introduces TextFieldI18n with methods for setting error messages and updates the TextField's validation logic to show these error messages when validation fails.

Note

It's still possible to use the setErrorMessage method to configure a single static error message. This error message will be displayed for all constraints and will take priority over any i18n error messages that are also set. However, when more than one error message is needed, i18n should be used or manual validation mode should be enabled.

Depends on

Part of #4618

Type of change

  • Feature

@vursen vursen changed the title feat: add support for error messages with TextFieldI18n feat: support error messages with TextFieldI18n Jun 3, 2024
@vursen vursen changed the title feat: support error messages with TextFieldI18n feat: support setting error messages with TextFieldI18n Jun 3, 2024
@vursen vursen force-pushed the feat/text-field/error-messages branch from 7b20ca4 to 7361585 Compare June 3, 2024 14:15
@vursen vursen changed the title feat: support setting error messages with TextFieldI18n feat!: support setting error messages with TextFieldI18n Jun 3, 2024
@vursen vursen force-pushed the feat/text-field/error-messages branch 2 times, most recently from 24eb2a5 to 1f71052 Compare June 3, 2024 19:25
*
* @return the error message or {@code null} if not set
* @see TextField#isRequiredIndicatorVisible()
* @see TextField#setRequiredIndicatorVisible(boolean)
Copy link
Contributor Author

@vursen vursen Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Should we mention isRequired() and setRequired(boolean) here as well?

@vursen vursen force-pushed the feat/text-field/error-messages branch 5 times, most recently from 96bb60e to 3f8e7d5 Compare June 7, 2024 13:18
@vursen vursen marked this pull request as ready for review June 10, 2024 06:40

ValidationResult maxLengthResult = ValidationUtil
.validateMaxLengthConstraint(getMaxLengthErrorMessage(), value,
hasMaxLength() ? getMaxLength() : null);
Copy link
Contributor Author

@vursen vursen Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: getMaxLength() returns 0 if the maxLength property is null. I added this check to ensure the max length is only considered when the user has explicitly set it with setMinLength(int minLength).

}
}

ValidationResult maxLengthResult = ValidationUtil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would make sense to reuse validateMaxConstraint?

ValidationResult maxLengthResult = ValidationUtil.validateMaxConstraint(
                getMaxLengthErrorMessage(), value.length(),
                hasMaxLength() ? getMaxLength() : null);

Copy link
Contributor Author

@vursen vursen Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I didn’t think about that. Thanks. I personally don't have a strong opinion on which way is better.

To keep it consistent, I guess we should also use validateMinConstraint for minLength. If we use it, we will need to add a check outside the validator to see if the value is an empty string to not run the validator then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong preference for either approach so this isn't a blocker for the PR

Copy link

sonarcloud bot commented Jun 10, 2024

Quality Gate Passed Quality Gate passed

Issues
1 New issue
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

@vursen vursen requested review from sissbruecker and DiegoCardoso and removed request for yuriy-fix and DiegoCardoso July 11, 2024 08:17
@vursen vursen force-pushed the feat/text-field/error-messages branch from 50091ff to 5911e46 Compare July 11, 2024 11:38
checkRequired => validateRequiredConstraint

add unit test

polish

run formatter

docs: improve grid empty state documentation (#6351)

add more unit tests

wip
@vursen vursen force-pushed the feat/text-field/error-messages branch from 5911e46 to 9b255ba Compare July 11, 2024 11:51
Comment on lines 389 to 407
private String getRequiredErrorMessage() {
return Optional.ofNullable(i18n)
.map(TextFieldI18n::getRequiredErrorMessage).orElse("");
}

private String getMinLengthErrorMessage() {
return Optional.ofNullable(i18n)
.map(TextFieldI18n::getMinLengthErrorMessage).orElse("");
}

private String getMaxLengthErrorMessage() {
return Optional.ofNullable(i18n)
.map(TextFieldI18n::getMaxLengthErrorMessage).orElse("");
}

private String getPatternErrorMessage() {
return Optional.ofNullable(i18n)
.map(TextFieldI18n::getPatternErrorMessage).orElse("");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use the same approach as suggested in #6365 (comment)

Copy link
Contributor Author

@vursen vursen Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, updated.

@vursen
Copy link
Contributor Author

vursen commented Jul 17, 2024

During our internal discussion, we discovered a way to keep error messages that are set with setErrorMessage. They now take priority over i18n error messages, which allows developers to continue using the old familiar method, setting a single error message for all constraints. I've updated the PR and also removed the breaking change mark.

@vursen vursen changed the title feat!: support setting error messages with TextFieldI18n feat: support setting error messages with TextFieldI18n Jul 17, 2024
@vursen vursen requested a review from DiegoCardoso July 17, 2024 13:25
@vursen vursen requested review from sissbruecker and removed request for sissbruecker July 18, 2024 08:43

private boolean manualValidationEnabled = false;

private String customErrorMessage;
private String constraintErrorMessage;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about extracting this somehow? There could be a class that:

  • Manages custom + constraint error message states
  • Updates the effective error message property on the component when either is set

It wouldn't do a whole lot, but it looks like you have to replicate the logic quite a few times for different components. There's also checkValidity which is always the same though that one needs to access more stuff from the component. Anyway, maybe something to think about, we can also do this after updating all components and then see if there is something that works for all of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting extracting this only for text fields or for all field components?

Copy link
Contributor Author

@vursen vursen Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could have something like ErrorMessageController:

class ErrorMessageController {
  private Component component;

  public ErrorMessageController(Component component) {
    this.component = component;
  }

  public void setCustomErrorMessage() {
    ...
    this.updateErrorMessageProperty();    
  }

  public void setConstraintErrorMessage() {
    ...
    this.updateErrorMessageProperty();
  }

  private void updateErrorMessageProperty() {
    this.component.getElement().setProperty("errorMessage");
  }
}

Copy link
Contributor Author

@vursen vursen Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also checkValidity which is always the same though that one needs to access more stuff from the component.

I discussed this with @yuriy-fix some time ago, and we concluded that it would currently complicate things especially since the whole i18n would need to be passed to that helper class or the class would need to provide an API to abstract itself from i18n. We agreed to revisit this in the future when we get to implementing error message providers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, something like what you suggested with the controller. It seems like that would be applicable to all components, but not sure. But since there are other potential opportunities for code reuse, let's maybe finish changing the components first, and then see what we can extract as common logic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed 👍

Copy link

sonarcloud bot commented Jul 18, 2024

@vursen vursen changed the title feat: support setting error messages with TextFieldI18n feat: add i18n error message support for TextField Jul 19, 2024
@vursen vursen merged commit a7a723f into main Jul 19, 2024
5 checks passed
@vursen vursen deleted the feat/text-field/error-messages branch July 19, 2024 05:52
@vaadin-bot
Copy link
Collaborator

This ticket/PR has been released with Vaadin 24.5.0.alpha6 and is also targeting the upcoming stable 24.5.0 version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants