Skip to content

Commit dd3c8e0

Browse files
vaadin-botjcgueriaud1sissbruecker
authored
feat: control manually when CustomField updates value (#7771) (#7829)
* Add disableUpdateValueOnChange to the CustomField * Add disableUpdateValueOnChange to the CustomField * Fix Sonar issues * Fix Sonar issues * feat: Add manualValueChangeTriggering in the CustomField * improve naming, javadoc * replace IT with unit test --------- Co-authored-by: Jean-Christophe Gueriaud <51313578+jcgueriaud1@users.noreply.github.com> Co-authored-by: Sascha Ißbrücker <sissbruecker@vaadin.com>
1 parent 7d16f15 commit dd3c8e0

File tree

2 files changed

+118
-2
lines changed

2 files changed

+118
-2
lines changed

vaadin-custom-field-flow-parent/vaadin-custom-field-flow/src/main/java/com/vaadin/flow/component/customfield/CustomField.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,30 @@ public CustomField() {
7171
* @see AbstractField#AbstractField(Object)
7272
*/
7373
public CustomField(T defaultValue) {
74+
this(defaultValue, false);
75+
}
76+
77+
/**
78+
* Constructs a new custom field.
79+
*
80+
* @param defaultValue
81+
* The initial value for the field. Will also be used by
82+
* {@link #getEmptyValue()}.
83+
* @param manualValueUpdate
84+
* when {@code true} the component does not automatically update
85+
* its value when one of the contained fields changes. This
86+
* allows controlling manually when the value is updated, which
87+
* can be done by calling {@link #updateValue()}. {@code false}
88+
* by default.
89+
*
90+
* @see AbstractField#AbstractField(Object)
91+
*/
92+
public CustomField(T defaultValue, boolean manualValueUpdate) {
7493
super(defaultValue);
75-
// Force a value update when the change event generated
76-
getElement().addEventListener("change", e -> this.updateValue());
94+
if (!manualValueUpdate) {
95+
// Automatically update the value when a contained field changes
96+
getElement().addEventListener("change", e -> this.updateValue());
97+
}
7798
getElement().setProperty("manualValidation", true);
7899
}
79100

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2000-2025 Vaadin Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.vaadin.flow.component.customfield;
17+
18+
import org.junit.Assert;
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
22+
import com.vaadin.flow.dom.DomEvent;
23+
24+
import elemental.json.Json;
25+
26+
public class ManualValueUpdateTest {
27+
28+
private IncrementingCustomField automaticField;
29+
private IncrementingCustomField manualField;
30+
31+
@Before
32+
public void setup() {
33+
automaticField = new IncrementingCustomField(false);
34+
manualField = new IncrementingCustomField(true);
35+
}
36+
37+
@Test
38+
public void automaticValueUpdate_changeEventUpdatesValue() {
39+
Assert.assertEquals(Integer.valueOf(0), automaticField.getValue());
40+
41+
fireChangeEvent(automaticField);
42+
Assert.assertEquals(Integer.valueOf(1), automaticField.getValue());
43+
44+
fireChangeEvent(automaticField);
45+
Assert.assertEquals(Integer.valueOf(2), automaticField.getValue());
46+
}
47+
48+
@Test
49+
public void manualValueUpdate_changeEventDoesNotUpdateValue() {
50+
Assert.assertEquals(Integer.valueOf(0), manualField.getValue());
51+
52+
fireChangeEvent(manualField);
53+
Assert.assertEquals(Integer.valueOf(0), manualField.getValue());
54+
55+
fireChangeEvent(manualField);
56+
Assert.assertEquals(Integer.valueOf(0), manualField.getValue());
57+
}
58+
59+
@Test
60+
public void manualValueUpdate_manuallyUpdateValue() {
61+
Assert.assertEquals(Integer.valueOf(0), manualField.getValue());
62+
63+
manualField.updateValue();
64+
Assert.assertEquals(Integer.valueOf(1), manualField.getValue());
65+
66+
manualField.updateValue();
67+
Assert.assertEquals(Integer.valueOf(2), manualField.getValue());
68+
}
69+
70+
private void fireChangeEvent(CustomField<?> field) {
71+
DomEvent changeEvent = new DomEvent(field.getElement(), "change",
72+
Json.createObject());
73+
field.getElement().getNode().getFeature(
74+
com.vaadin.flow.internal.nodefeature.ElementListenerMap.class)
75+
.fireEvent(changeEvent);
76+
}
77+
78+
private static class IncrementingCustomField extends CustomField<Integer> {
79+
private int counter = 0;
80+
81+
public IncrementingCustomField(boolean manualValueUpdate) {
82+
super(0, manualValueUpdate);
83+
}
84+
85+
@Override
86+
protected Integer generateModelValue() {
87+
return ++counter;
88+
}
89+
90+
@Override
91+
protected void setPresentationValue(Integer newPresentationValue) {
92+
// Not needed for this test
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)