From 7eb9588359c28ed484bcaeb729fc54675601671a Mon Sep 17 00:00:00 2001 From: Anna Koskinen Date: Mon, 8 Mar 2021 13:18:11 +0200 Subject: Fix updating Grid's item set when details rows are open. (#12231) - Old details should close. - New details should open. - If some row has details in both old and new item set, the details row contents should get updated. - Updating details row contents should not break the positioning of the rows and details below. Fixes #12211 --- .../connectors/grid/DetailsManagerConnector.java | 1 + .../client/widget/escalator/RowContainer.java | 10 +++++++ .../java/com/vaadin/client/widgets/Escalator.java | 32 ++++++++++++++++++++-- .../main/java/com/vaadin/client/widgets/Grid.java | 11 ++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) (limited to 'client/src') diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/DetailsManagerConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/DetailsManagerConnector.java index f605329fd9..7e7389e65d 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/DetailsManagerConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/DetailsManagerConnector.java @@ -702,6 +702,7 @@ public class DetailsManagerConnector extends AbstractExtensionConnector { // updated, replace reference indexToDetailConnectorId.put(rowIndex, id); newOrUpdatedDetails = true; + getWidget().resetVisibleDetails(rowIndex); } } else { // new Details content, listeners will get attached to the connector diff --git a/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java b/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java index 1b05eeb488..fc82bd87d7 100644 --- a/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java +++ b/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java @@ -85,6 +85,16 @@ public interface RowContainer { */ boolean spacerExists(int rowIndex); + /** + * Updates the spacer corresponding with the given rowIndex to currently + * provided contents. + * + * @since + * @param rowIndex + * the row index for the spacer in need of updating + */ + void resetSpacer(int rowIndex); + /** * Sets a new spacer updater. *

diff --git a/client/src/main/java/com/vaadin/client/widgets/Escalator.java b/client/src/main/java/com/vaadin/client/widgets/Escalator.java index 31b439a6d8..f48177fa84 100644 --- a/client/src/main/java/com/vaadin/client/widgets/Escalator.java +++ b/client/src/main/java/com/vaadin/client/widgets/Escalator.java @@ -4964,6 +4964,11 @@ public class Escalator extends Widget return spacerContainer.spacerExists(rowIndex); } + @Override + public void resetSpacer(int rowIndex) { + spacerContainer.resetSpacer(rowIndex); + } + @Override public void setSpacerUpdater(SpacerUpdater spacerUpdater) throws IllegalArgumentException { @@ -6111,8 +6116,10 @@ public class Escalator extends Widget root.getStyle().setHeight(height + defaultCellBorderBottomSize, Unit.PX); - // move the visible spacers getRow row onwards. - shiftSpacerPositionsAfterRow(getRow(), heightDiff); + if (!delayRepositioning) { + // move the visible spacers getRow row onwards. + shiftSpacerPositionsAfterRow(getRow(), heightDiff); + } /* * If we're growing, we'll adjust the scroll size first, then @@ -6178,7 +6185,7 @@ public class Escalator extends Widget tBodyScrollTop + moveDiff); verticalScrollbar.setScrollPosByDelta(moveDiff); - } else { + } else if (!delayRepositioning) { body.shiftRowPositions(getRow(), heightDiff); } @@ -6336,6 +6343,8 @@ public class Escalator extends Widget /** Width of the spacers' decos. Calculated once then cached. */ private double spacerDecoWidth = 0.0D; + private boolean delayRepositioning = false; + public void setSpacer(int rowIndex, double height) throws IllegalArgumentException { @@ -6376,6 +6385,23 @@ public class Escalator extends Widget return false; } + void resetSpacer(int rowIndex) { + if (spacerExists(rowIndex)) { + delayRepositioning = true; + double oldHeight = getSpacer(rowIndex).getHeight(); + removeSpacer(rowIndex); + // real height will be determined later + insertNewSpacer(rowIndex, 0); + // reposition content below this point to match lack of height, + // otherwise later repositioning will fail + if (oldHeight > 0) { + shiftSpacerPositionsAfterRow(rowIndex, -oldHeight); + body.shiftRowPositions(rowIndex, -oldHeight); + } + delayRepositioning = false; + } + } + @SuppressWarnings("boxing") void scrollToSpacer(int spacerIndex, ScrollDestination destination, int padding) { diff --git a/client/src/main/java/com/vaadin/client/widgets/Grid.java b/client/src/main/java/com/vaadin/client/widgets/Grid.java index 792fcc98b0..d2b3860ef6 100755 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -9661,6 +9661,17 @@ public class Grid extends ResizeComposite implements HasSelectionHandlers, return visibleDetails.contains(Integer.valueOf(rowIndex)); } + /** + * Reset the details row with current contents. + * + * @since + * @param rowIndex + * the index of the row for which details should be reset + */ + public void resetVisibleDetails(int rowIndex) { + escalator.getBody().resetSpacer(rowIndex); + } + /** * Update details row height. * -- cgit v1.2.3