fix: do not show ResultValidator feedback message if input field is empty
This commit is contained in:
parent
780d8a9691
commit
43dd132013
4 changed files with 59 additions and 6 deletions
5
.changeset/tender-otters-shake.md
Normal file
5
.changeset/tender-otters-shake.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/form-core': patch
|
||||
---
|
||||
|
||||
fix: reset the form validators after a form `reset` click or field emptied
|
||||
|
|
@ -23,7 +23,6 @@ To fire a submit from JavaScript, select the `lion-form` element and call `.subm
|
|||
```js preview-story
|
||||
export const formSubmit = () => {
|
||||
loadDefaultFeedbackMessages();
|
||||
|
||||
const submitHandler = ev => {
|
||||
if (ev.target.hasFeedbackFor.includes('error')) {
|
||||
const firstFormElWithError = ev.target.formElements.find(el =>
|
||||
|
|
|
|||
|
|
@ -499,7 +499,7 @@ export const ValidateMixinImplementation = superclass =>
|
|||
|
||||
/**
|
||||
* step b (as explained in `validate()`), called by __finishValidation
|
||||
* @param {{validator:Validator; outcome: boolean|string;}[]} regularValidationResult result of steps 1-3
|
||||
* @param {{validator: Validator;outcome: boolean | string;}[]} regularValidationResult result of steps 1-3
|
||||
* @private
|
||||
*/
|
||||
__executeResultValidators(regularValidationResult) {
|
||||
|
|
@ -510,6 +510,16 @@ export const ValidateMixinImplementation = superclass =>
|
|||
})
|
||||
);
|
||||
|
||||
if (!resultValidators.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// If empty, do not show the ResulValidation message (e.g. Correct!)
|
||||
if (this._isEmpty(this.modelValue)) {
|
||||
this.__prevShownValidationResult = [];
|
||||
return [];
|
||||
}
|
||||
|
||||
// Map everything to Validator[] for backwards compatibility
|
||||
return resultValidators
|
||||
.map(v => ({
|
||||
|
|
@ -537,8 +547,9 @@ export const ValidateMixinImplementation = superclass =>
|
|||
__finishValidation({ source, hasAsync }) {
|
||||
const syncAndAsyncOutcome = [...this.__syncValidationResult, ...this.__asyncValidationResult];
|
||||
// if we have any ResultValidators left, now is the time to run them...
|
||||
const resultOutCome = this.__executeResultValidators(syncAndAsyncOutcome);
|
||||
|
||||
const resultOutCome = /** @type {ValidationResultEntry[]} */ (
|
||||
this.__executeResultValidators(syncAndAsyncOutcome)
|
||||
);
|
||||
this.__validationResult = [...resultOutCome, ...syncAndAsyncOutcome];
|
||||
|
||||
const ctor = /** @type {ValidateHostConstructor} */ (this.constructor);
|
||||
|
|
@ -560,7 +571,6 @@ export const ValidateMixinImplementation = superclass =>
|
|||
this.hasFeedbackFor = [
|
||||
...new Set(this.__validationResult.map(({ validator }) => validator.type)),
|
||||
];
|
||||
|
||||
/** private event that should be listened to by LionFieldSet */
|
||||
this.dispatchEvent(new Event('validate-performed', { bubbles: true }));
|
||||
if (source === 'async' || !hasAsync) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,14 @@ import { localizeTearDown } from '@lion/localize/test-helpers';
|
|||
import { defineCE, expect, fixture, html, unsafeStatic } from '@open-wc/testing';
|
||||
import { getFormControlMembers } from '@lion/form-core/test-helpers';
|
||||
import sinon from 'sinon';
|
||||
import { DefaultSuccess, MinLength, Required, ValidateMixin, Validator } from '../index.js';
|
||||
import {
|
||||
DefaultSuccess,
|
||||
MinLength,
|
||||
MaxLength,
|
||||
Required,
|
||||
ValidateMixin,
|
||||
Validator,
|
||||
} from '../index.js';
|
||||
import { AlwaysInvalid } from '../test-helpers/index.js';
|
||||
|
||||
/**
|
||||
|
|
@ -373,6 +380,38 @@ export function runValidateMixinFeedbackPart() {
|
|||
expect(_feedbackNode.feedbackData?.[0].message).to.equal('This is a success message');
|
||||
});
|
||||
|
||||
it('does not show success message after fixing error an & field is empty', async () => {
|
||||
class ValidateElementCustomTypes extends ValidateMixin(LitElement) {
|
||||
static get validationTypes() {
|
||||
return ['error', 'success'];
|
||||
}
|
||||
}
|
||||
const elTagString = defineCE(ValidateElementCustomTypes);
|
||||
const elTag = unsafeStatic(elTagString);
|
||||
const el = /** @type {ValidateElementCustomTypes} */ (
|
||||
await fixture(html`
|
||||
<${elTag}
|
||||
.submitted=${true}
|
||||
.validators=${[
|
||||
new MaxLength(3, { getMessage: async () => 'Max length is 3!' }),
|
||||
new DefaultSuccess(null, { getMessage: () => 'This is a success message' }),
|
||||
]}
|
||||
>${lightDom}</${elTag}>
|
||||
`)
|
||||
);
|
||||
const { _feedbackNode } = getFormControlMembers(el);
|
||||
|
||||
el.modelValue = 'abcd';
|
||||
await el.updateComplete;
|
||||
await el.feedbackComplete;
|
||||
expect(_feedbackNode.feedbackData?.[0].message).to.equal('Max length is 3!');
|
||||
|
||||
el.modelValue = '';
|
||||
await el.updateComplete;
|
||||
await el.feedbackComplete;
|
||||
expect(_feedbackNode.feedbackData).to.deep.equal([]);
|
||||
});
|
||||
|
||||
describe('Accessibility', () => {
|
||||
it('sets [aria-invalid="true"] to "._inputNode" when there is an error', async () => {
|
||||
const el = /** @type {ValidateElement} */ (
|
||||
|
|
|
|||
Loading…
Reference in a new issue