From 7851a3d2cd964e28af6b4a352ae3ee6b9fe21ad3 Mon Sep 17 00:00:00 2001 From: Serhii Kulykov Date: Mon, 30 Sep 2024 13:29:49 +0300 Subject: [PATCH] fix: apply initially set custom field value to inputs (#7882) --- .../src/vaadin-custom-field-mixin.js | 33 +++++++++++++++---- .../custom-field/test/custom-field.common.js | 21 ++++++++++++ .../custom-field-lazy-inputs.test.js | 24 ++++++++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 test/integration/custom-field-lazy-inputs.test.js diff --git a/packages/custom-field/src/vaadin-custom-field-mixin.js b/packages/custom-field/src/vaadin-custom-field-mixin.js index cf2fb328a8..fd40af1360 100644 --- a/packages/custom-field/src/vaadin-custom-field-mixin.js +++ b/packages/custom-field/src/vaadin-custom-field-mixin.js @@ -65,6 +65,7 @@ export const CustomFieldMixin = (superClass) => inputs: { type: Array, readOnly: true, + observer: '__inputsChanged', }, /** @@ -249,7 +250,20 @@ export const CustomFieldMixin = (superClass) => /** @private */ __setInputsFromSlot() { this._setInputs(this.__getInputsFromSlot()); - this.__setValue(); + } + + /** @private */ + __inputsChanged(inputs, oldInputs) { + if (inputs.length === 0) { + return; + } + + // When inputs are first initialized, apply value set with property. + if (this.value && this.value !== '\t' && (!oldInputs || oldInputs.length === 0)) { + this.__applyInputsValue(this.value); + } else { + this.__setValue(); + } } /** @private */ @@ -265,18 +279,25 @@ export const CustomFieldMixin = (superClass) => return; } + this.__applyInputsValue(value); + + if (oldValue !== undefined) { + this.validate(); + } + } + + /** @private */ + __applyInputsValue(value) { const parseFn = this.parseValue || defaultParseValue; const valuesArray = parseFn.apply(this, [value]); + if (!valuesArray || valuesArray.length === 0) { console.warn('Value parser has not provided values array'); return; } - this.inputs.forEach((input, id) => { - input.value = valuesArray[id]; + this.inputs.forEach((input, idx) => { + input.value = valuesArray[idx]; }); - if (oldValue !== undefined) { - this.validate(); - } } }; diff --git a/packages/custom-field/test/custom-field.common.js b/packages/custom-field/test/custom-field.common.js index bebce41e2d..fa2e2ab19e 100644 --- a/packages/custom-field/test/custom-field.common.js +++ b/packages/custom-field/test/custom-field.common.js @@ -79,6 +79,27 @@ describe('custom field', () => { }); }); + describe('value set with attribute', () => { + beforeEach(async () => { + customField = fixtureSync(` + + + + + `); + await nextRender(); + }); + + it('should not reset value set using attribute', () => { + expect(customField.value).to.equal('01\t25'); + }); + + it('should apply value set using attribute to inputs', () => { + expect(customField.inputs[0].value).to.equal('01'); + expect(customField.inputs[1].value).to.equal('25'); + }); + }); + describe('aria-required', () => { it('should toggle aria-required attribute on required property change', async () => { customField.required = true; diff --git a/test/integration/custom-field-lazy-inputs.test.js b/test/integration/custom-field-lazy-inputs.test.js new file mode 100644 index 0000000000..03b2e694ac --- /dev/null +++ b/test/integration/custom-field-lazy-inputs.test.js @@ -0,0 +1,24 @@ +import { expect } from '@vaadin/chai-plugins'; +import { fixtureSync } from '@vaadin/testing-helpers'; +import '@vaadin/custom-field'; + +describe('custom-field inputs', () => { + let customField; + + beforeEach(async () => { + customField = fixtureSync(` + + + + + `); + + // Ensure lazy custom element upgrade for slotted inputs. + await import('@vaadin/integer-field'); + }); + + it('should apply value set using attribute to inputs', () => { + expect(customField.inputs[0].value).to.equal('01'); + expect(customField.inputs[1].value).to.equal('25'); + }); +});