Skip to content

Commit ae83246

Browse files
fix: do not refresh items on select (#7114)
* fix: do not refresh items on select * Update AbstractGridMultiSelectionModel.java * Update AbstractGridSingleSelectionModel.java * Create SelectItemWithIdenticalIdIT.java * Create SelectItemWithIdenticalIdPage * Create GridSingleSelectionUpdateAndDeselectPage.java * Rename SelectItemWithIdenticalIdPage to SelectItemWithIdenticalIdPage.java * Create GridSingleSelectionUpdateAndDeselectIT.java * add CheckboxElement dependency * formatting * formatting * formatting * formatting * fix typo * add header * add header * eliminate duplicate code * Update GridMultiSelectionColumnPageIT.java Add test * Update gridConnector.js * add missing import * update test page * move comment --------- Co-authored-by: Sascha Ißbrücker <sascha.issbruecker@googlemail.com>
1 parent e240a39 commit ae83246

10 files changed

Lines changed: 364 additions & 14 deletions

File tree

vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@
117117
<version>${project.version}</version>
118118
<scope>test</scope>
119119
</dependency>
120+
<dependency>
121+
<groupId>com.vaadin</groupId>
122+
<artifactId>vaadin-checkbox-testbench</artifactId>
123+
<version>${project.version}</version>
124+
<scope>test</scope>
125+
</dependency>
120126
<dependency>
121127
<groupId>com.vaadin</groupId>
122128
<artifactId>vaadin-select-testbench</artifactId>

vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/main/java/com/vaadin/flow/component/grid/it/GridMultiSelectionColumnPage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
public class GridMultiSelectionColumnPage extends Div {
3232

3333
public static final int ITEM_COUNT = 1000;
34+
35+
static final String IN_MEMORY_GRID_ID = "in-memory-grid";
3436
static final String MULTI_SELECT_GRID_ALL_SELECTED_GRID_ID = "multi-select-grid-all-selected";
3537
static final String MULTI_SELECT_GRID_ONE_NOT_SELECTED_GRID_ID = "multi-select-grid-one-deselected";
3638

@@ -74,7 +76,7 @@ private void createInMemoryGrid() {
7476
grid.setItems(
7577
IntStream.range(0, ITEM_COUNT).mapToObj(Integer::toString));
7678
setUp(grid);
77-
grid.setId("in-memory-grid");
79+
grid.setId(IN_MEMORY_GRID_ID);
7880
add(new H2("In-memory grid"), grid);
7981
}
8082

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* Copyright 2000-2025 Vaadin Ltd.
3+
*
4+
* This program is available under Vaadin Commercial License and Service Terms.
5+
*
6+
* See {@literal <https://vaadin.com/commercial-license-and-service-terms>} for the full
7+
* license.
8+
*/
9+
package com.vaadin.flow.component.grid.it;
10+
11+
import java.util.stream.Stream;
12+
13+
import com.vaadin.flow.component.button.Button;
14+
import com.vaadin.flow.component.grid.Grid;
15+
import com.vaadin.flow.component.html.Div;
16+
import com.vaadin.flow.data.provider.CallbackDataProvider;
17+
import com.vaadin.flow.data.provider.DataProvider;
18+
import com.vaadin.flow.router.Route;
19+
20+
@Route("vaadin-grid/grid-single-selection-update-and-deselect")
21+
public class GridSingleSelectionUpdateAndDeselectPage extends Div {
22+
23+
private Bean bean = new Bean(0, "Foo");
24+
25+
private Bean getBeanClone() {
26+
return new Bean(bean.getId(), bean.getName());
27+
}
28+
29+
public GridSingleSelectionUpdateAndDeselectPage() {
30+
Grid<Bean> grid = new Grid<>(Bean.class);
31+
32+
CallbackDataProvider<Bean, Void> dataProvider = DataProvider
33+
.fromCallbacks(query -> {
34+
query.getLimit();
35+
query.getOffset();
36+
return Stream.of(getBeanClone());
37+
}, query -> {
38+
query.getLimit();
39+
query.getOffset();
40+
Stream<Bean> stream = Stream.of(getBeanClone());
41+
return (int) stream.count();
42+
});
43+
grid.setDataProvider(dataProvider);
44+
45+
grid.select(getBeanClone());
46+
47+
Button button = new Button("Update name", e -> {
48+
bean.setName("Bar");
49+
50+
// The order of these two calls is important. Do not change.
51+
// See https://github.com/vaadin/flow-components/issues/3229
52+
grid.getDataProvider().refreshAll();
53+
grid.select(null);
54+
});
55+
button.setId("update-name");
56+
57+
add(grid, button);
58+
}
59+
60+
public static class Bean {
61+
private final int id;
62+
private String name;
63+
64+
public Bean(int id, String name) {
65+
this.id = id;
66+
this.name = name;
67+
}
68+
69+
public int getId() {
70+
return id;
71+
}
72+
73+
public String getName() {
74+
return name;
75+
}
76+
77+
public void setName(String name) {
78+
this.name = name;
79+
}
80+
81+
@Override
82+
public int hashCode() {
83+
return id;
84+
}
85+
86+
@Override
87+
public boolean equals(Object obj) {
88+
if (obj instanceof Bean) {
89+
Bean other = (Bean) obj;
90+
return id == other.id;
91+
}
92+
return false;
93+
}
94+
}
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Copyright 2000-2024 Vaadin Ltd.
3+
*
4+
* This program is available under Vaadin Commercial License and Service Terms.
5+
*
6+
* See {@literal <https://vaadin.com/commercial-license-and-service-terms>} for the full
7+
* license.
8+
*/
9+
package com.vaadin.flow.component.grid.it;
10+
11+
import java.util.Arrays;
12+
import java.util.Objects;
13+
14+
import com.vaadin.flow.component.button.Button;
15+
import com.vaadin.flow.component.checkbox.Checkbox;
16+
import com.vaadin.flow.component.grid.Grid;
17+
import com.vaadin.flow.component.html.Div;
18+
import com.vaadin.flow.router.Route;
19+
20+
@Route("vaadin-grid/select-item-with-identical-id")
21+
public class SelectItemWithIdenticalIdPage extends Div {
22+
23+
public SelectItemWithIdenticalIdPage() {
24+
Grid<Item> grid = new Grid<>();
25+
grid.addColumn(Item::getDisplayValue).setHeader("Display value");
26+
grid.setItems(Arrays.asList(new Item("1", "1"), new Item("2", "2")));
27+
28+
Checkbox useMultiSelectCheckbox = new Checkbox("Use multi-select",
29+
event -> grid
30+
.setSelectionMode(Boolean.TRUE.equals(event.getValue())
31+
? Grid.SelectionMode.MULTI
32+
: Grid.SelectionMode.SINGLE));
33+
useMultiSelectCheckbox.setId("use-multi-select-checkbox");
34+
35+
Button selectItem2Button = new Button("Select item 2",
36+
e -> grid.select(new Item("2", "INVALID")));
37+
selectItem2Button.setId("select-item-2-button");
38+
39+
Button deselectItem1Button = new Button("Deselect item 1",
40+
e -> grid.deselect(new Item("1", "INVALID")));
41+
deselectItem1Button.setId("deselect-item-1-button");
42+
43+
Button addGridWithPreselectionButton = new Button("Add grid", e -> {
44+
grid.select(new Item("1", "INVALID"));
45+
e.getSource().setVisible(false);
46+
add(grid);
47+
});
48+
addGridWithPreselectionButton
49+
.setId("add-grid-with-preselection-button");
50+
51+
add(useMultiSelectCheckbox, addGridWithPreselectionButton,
52+
selectItem2Button, deselectItem1Button);
53+
}
54+
55+
private class Item {
56+
57+
private String id;
58+
59+
private String displayValue;
60+
61+
public Item(String id, String displayValue) {
62+
this.id = id;
63+
this.displayValue = displayValue;
64+
}
65+
66+
public String getId() {
67+
return id;
68+
}
69+
70+
public String getDisplayValue() {
71+
return displayValue;
72+
}
73+
74+
@Override
75+
public boolean equals(Object o) {
76+
if (this == o) {
77+
return true;
78+
}
79+
if (o == null || getClass() != o.getClass()) {
80+
return false;
81+
}
82+
Item item = (Item) o;
83+
return id.equals(item.id);
84+
}
85+
86+
@Override
87+
public int hashCode() {
88+
return Objects.hash(id);
89+
}
90+
}
91+
}

vaadin-grid-flow-parent/vaadin-grid-flow-integration-tests/src/test/java/com/vaadin/flow/component/grid/it/GridMultiSelectionColumnPageIT.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.openqa.selenium.WebElement;
1616
import org.openqa.selenium.interactions.Actions;
1717

18+
import com.vaadin.flow.component.checkbox.testbench.CheckboxElement;
1819
import com.vaadin.flow.component.grid.testbench.GridElement;
1920
import com.vaadin.flow.testutil.TestPath;
2021
import com.vaadin.testbench.TestBenchElement;
@@ -45,6 +46,26 @@ public void selectAllCheckbox_visibility() {
4546
selectAllCheckbox.getAttribute("focus-target"));
4647
}
4748

49+
@Test
50+
public void selectItem_selectAll_deselectAll_itemIsNotSelected() {
51+
open();
52+
GridElement grid = $(GridElement.class)
53+
.id(GridMultiSelectionColumnPage.IN_MEMORY_GRID_ID);
54+
CheckboxElement selectAllCheckbox = grid.$(CheckboxElement.class)
55+
.id(SELECT_ALL_CHECKBOX_ID);
56+
CheckboxElement selectItemCheckbox = grid.$(CheckboxElement.class)
57+
.get(1);
58+
// Select an item
59+
selectItemCheckbox.click();
60+
Assert.assertTrue(selectItemCheckbox.isChecked());
61+
// Select all
62+
selectAllCheckbox.click();
63+
Assert.assertTrue(selectItemCheckbox.isChecked());
64+
// Deselect all
65+
selectAllCheckbox.click();
66+
Assert.assertFalse(selectItemCheckbox.isChecked());
67+
}
68+
4869
@Test
4970
public void selectAllCheckbox_state() {
5071
open();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Copyright 2000-2025 Vaadin Ltd.
3+
*
4+
* This program is available under Vaadin Commercial License and Service Terms.
5+
*
6+
* See {@literal <https://vaadin.com/commercial-license-and-service-terms>} for the full
7+
* license.
8+
*/
9+
package com.vaadin.flow.component.grid.it;
10+
11+
import org.junit.Assert;
12+
import org.junit.Before;
13+
import org.junit.Test;
14+
15+
import com.vaadin.flow.component.grid.testbench.GridElement;
16+
import com.vaadin.flow.testutil.TestPath;
17+
import com.vaadin.tests.AbstractComponentIT;
18+
19+
@TestPath("vaadin-grid/grid-single-selection-update-and-deselect")
20+
public class GridSingleSelectionUpdateAndDeselectIT
21+
extends AbstractComponentIT {
22+
23+
@Before
24+
public void init() {
25+
open();
26+
}
27+
28+
@Test
29+
public void shouldHaveCorrectValueAfterUpdateAndDeselect() {
30+
// Click the update button
31+
clickElementWithJs("update-name");
32+
GridElement grid = $(GridElement.class).first();
33+
String name = grid.getCell(0, 1).getText();
34+
35+
// Expect the name to be updated
36+
Assert.assertEquals("Bar", name);
37+
}
38+
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* Copyright 2000-2024 Vaadin Ltd.
3+
*
4+
* This program is available under Vaadin Commercial License and Service Terms.
5+
*
6+
* See {@literal <https://vaadin.com/commercial-license-and-service-terms>} for the full
7+
* license.
8+
*/
9+
package com.vaadin.flow.component.grid.it;
10+
11+
import org.junit.Assert;
12+
import org.junit.Before;
13+
import org.junit.Test;
14+
15+
import com.vaadin.flow.component.button.testbench.ButtonElement;
16+
import com.vaadin.flow.component.checkbox.testbench.CheckboxElement;
17+
import com.vaadin.flow.component.grid.testbench.GridElement;
18+
import com.vaadin.flow.testutil.TestPath;
19+
import com.vaadin.tests.AbstractComponentIT;
20+
21+
@TestPath("vaadin-grid/select-item-with-identical-id")
22+
public class SelectItemWithIdenticalIdIT extends AbstractComponentIT {
23+
24+
private ButtonElement addGridWithPreselectionButton;
25+
26+
private ButtonElement selectItem2Button;
27+
28+
private ButtonElement deselectItem1Button;
29+
30+
private CheckboxElement useMultiSelectCheckbox;
31+
32+
@Before
33+
public void init() {
34+
open();
35+
addGridWithPreselectionButton = $(ButtonElement.class)
36+
.id("add-grid-with-preselection-button");
37+
selectItem2Button = $(ButtonElement.class).id("select-item-2-button");
38+
deselectItem1Button = $(ButtonElement.class)
39+
.id("deselect-item-1-button");
40+
useMultiSelectCheckbox = $(CheckboxElement.class).first();
41+
}
42+
43+
@Test
44+
public void addGridWithSelection_itemIsNotUpdated() {
45+
addGridWithPreselectionButton.click();
46+
GridElement grid = $(GridElement.class).waitForFirst();
47+
48+
Assert.assertEquals("1", grid.getCell(0, 0).getText());
49+
}
50+
51+
@Test
52+
public void addGridWithSelection_deselectItem_itemIsNotUpdated() {
53+
addGridWithPreselectionButton.click();
54+
GridElement grid = $(GridElement.class).waitForFirst();
55+
56+
deselectItem1Button.click();
57+
58+
Assert.assertEquals("1", grid.getCell(0, 0).getText());
59+
}
60+
61+
@Test
62+
public void addGridWithSelection_selectAnotherItem_itemIsNotUpdated() {
63+
addGridWithPreselectionButton.click();
64+
GridElement grid = $(GridElement.class).waitForFirst();
65+
66+
selectItem2Button.click();
67+
68+
Assert.assertEquals("2", grid.getCell(1, 0).getText());
69+
}
70+
71+
@Test
72+
public void setMultiSelect_addGridWithSelection_itemIsNotUpdated() {
73+
useMultiSelectCheckbox.setChecked(true);
74+
addGridWithPreselectionButton.click();
75+
GridElement grid = $(GridElement.class).waitForFirst();
76+
77+
Assert.assertEquals("1", grid.getCell(0, 1).getText());
78+
}
79+
80+
@Test
81+
public void setMultiSelect_addGridWithSelection_deselectItem_itemIsNotUpdated() {
82+
useMultiSelectCheckbox.setChecked(true);
83+
addGridWithPreselectionButton.click();
84+
GridElement grid = $(GridElement.class).waitForFirst();
85+
86+
deselectItem1Button.click();
87+
88+
Assert.assertEquals("1", grid.getCell(0, 1).getText());
89+
}
90+
91+
@Test
92+
public void setMultiSelect_addGridWithSelection_selectAnotherItem_itemIsNotUpdated() {
93+
useMultiSelectCheckbox.setChecked(true);
94+
addGridWithPreselectionButton.click();
95+
GridElement grid = $(GridElement.class).waitForFirst();
96+
97+
selectItem2Button.click();
98+
99+
Assert.assertEquals("2", grid.getCell(1, 1).getText());
100+
}
101+
}

0 commit comments

Comments
 (0)