summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikael Grankvist <mgrankvi@vaadin.com>2015-03-20 08:07:51 +0200
committerMarkus Koivisto <markus@vaadin.com>2015-04-15 11:53:35 +0300
commit0e1953be8f49c906c288416a3971519cea987713 (patch)
treea03fff30db4b0088a8f52b0591c959772889816a
parent583750936967e2eb2b35d48a8ea2519f351db1de (diff)
downloadvaadin-framework-0e1953be8f49c906c288416a3971519cea987713.tar.gz
vaadin-framework-0e1953be8f49c906c288416a3971519cea987713.zip
Grid header should render "the same" after changes to header (#17131)
Change-Id: I2a16ffbd59bf4863eb6a7bea8d4b590a693af637
-rw-r--r--client/src/com/vaadin/client/widgets/Grid.java82
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChange.java183
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChangeTest.java156
3 files changed, 403 insertions, 18 deletions
diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java
index 4b27e17e37..3aaac14f10 100644
--- a/client/src/com/vaadin/client/widgets/Grid.java
+++ b/client/src/com/vaadin/client/widgets/Grid.java
@@ -2178,14 +2178,33 @@ public class Grid<T> extends ResizeComposite implements
public final class SelectionColumn extends Column<Boolean, T> {
private boolean initDone = false;
+ private boolean selected = false;
SelectionColumn(final Renderer<Boolean> selectColumnRenderer) {
super(selectColumnRenderer);
}
void initDone() {
+ addSelectAllToDefaultHeader();
+
+ setWidth(-1);
+
+ setEditable(false);
+
+ initDone = true;
+ }
+
+ protected void addSelectAllToDefaultHeader() {
if (getSelectionModel() instanceof SelectionModel.Multi
&& header.getDefaultRow() != null) {
+ // If selection cell already contains a widget do not
+ // create a new CheckBox
+ HeaderCell selectionCell = header.getDefaultRow().getCell(this);
+ if (selectionCell.getType()
+ .equals(GridStaticCellType.WIDGET)
+ && selectionCell.getWidget() instanceof CheckBox) {
+ return;
+ }
/*
* TODO: Currently the select all check box is shown when multi
* selection is in use. This might result in malfunctions if no
@@ -2202,19 +2221,18 @@ public class Grid<T> extends ResizeComposite implements
public void onValueChange(ValueChangeEvent<Boolean> event) {
if (event.getValue()) {
fireEvent(new SelectAllEvent<T>(model));
+ selected = true;
} else {
model.deselectAll();
+ selected = false;
}
}
});
- header.getDefaultRow().getCell(this).setWidget(checkBox);
- }
+ checkBox.setValue(selected);
- setWidth(-1);
-
- setEditable(false);
+ selectionCell.setWidget(checkBox);
- initDone = true;
+ }
}
@Override
@@ -3685,27 +3703,34 @@ public class Grid<T> extends ResizeComposite implements
final StaticSection.StaticCell metadata = staticRow
.getCell(columns.get(cell.getColumn()));
+ boolean updateCellData = true;
// Decorate default row with sorting indicators
if (staticRow instanceof HeaderRow) {
addSortingIndicatorsToHeaderRow((HeaderRow) staticRow, cell);
+
+ if (isHeaderSelectionColumn(row, cell)) {
+ updateCellData = false;
+ }
}
// Assign colspan to cell before rendering
cell.setColSpan(metadata.getColspan());
TableCellElement element = cell.getElement();
- switch (metadata.getType()) {
- case TEXT:
- element.setInnerText(metadata.getText());
- break;
- case HTML:
- element.setInnerHTML(metadata.getHtml());
- break;
- case WIDGET:
- preDetach(row, Arrays.asList(cell));
- element.setInnerHTML("");
- postAttach(row, Arrays.asList(cell));
- break;
+ if (updateCellData) {
+ switch (metadata.getType()) {
+ case TEXT:
+ element.setInnerText(metadata.getText());
+ break;
+ case HTML:
+ element.setInnerHTML(metadata.getHtml());
+ break;
+ case WIDGET:
+ preDetach(row, Arrays.asList(cell));
+ element.setInnerHTML("");
+ postAttach(row, Arrays.asList(cell));
+ break;
+ }
}
setCustomStyleName(element, metadata.getStyleName());
@@ -3765,6 +3790,27 @@ public class Grid<T> extends ResizeComposite implements
@Override
public void preAttach(Row row, Iterable<FlyweightCell> cellsToAttach) {
+ // Add select all checkbox if needed on rebuild.
+ for (FlyweightCell cell : cellsToAttach) {
+ if (isHeaderSelectionColumn(row, cell)) {
+ selectionColumn.addSelectAllToDefaultHeader();
+ }
+ }
+ }
+
+ /**
+ * Check if selectionColumn in the default header row
+ */
+ private boolean isHeaderSelectionColumn(Row row, FlyweightCell cell) {
+ return selectionColumn != null && isDefaultHeaderRow(row)
+ && getColumn(cell.getColumn()).equals(selectionColumn);
+ }
+
+ /**
+ * Row is the default header row.
+ */
+ private boolean isDefaultHeaderRow(Row row) {
+ return section.getRow(row.getRow()).equals(header.getDefaultRow());
}
@Override
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChange.java b/uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChange.java
new file mode 100644
index 0000000000..fbd6a42a38
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChange.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.grid;
+
+import java.io.Serializable;
+
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.HeaderRow;
+import com.vaadin.ui.Grid.SelectionMode;
+import com.vaadin.ui.Grid.SelectionModel;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.renderers.NumberRenderer;
+
+public class GridHeaderFormatChange extends AbstractTestUI {
+
+ private static final long serialVersionUID = -2787771187365766027L;
+
+ private HeaderRow row;
+
+ public class Person implements Serializable {
+ private static final long serialVersionUID = -7995927620756317000L;
+
+ String firstName;
+ String lastName;
+ String streetAddress;
+ Integer zipCode;
+ String city;
+
+ public Person(String firstName, String lastName, String streetAddress,
+ Integer zipCode, String city) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.streetAddress = streetAddress;
+ this.zipCode = zipCode;
+ this.city = city;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getStreetAddress() {
+ return streetAddress;
+ }
+
+ public void setStreetAddress(String streetAddress) {
+ this.streetAddress = streetAddress;
+ }
+
+ public Integer getZipCode() {
+ return zipCode;
+ }
+
+ public void setZipCode(Integer zipCode) {
+ this.zipCode = zipCode;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ BeanItemContainer<Person> datasource = new BeanItemContainer<Person>(
+ Person.class);
+ final Grid grid;
+
+ datasource.addItem(new Person("Rudolph", "Reindeer", "Ruukinkatu 2-4",
+ 20540, "Turku"));
+
+ grid = new Grid(datasource);
+ grid.setWidth("600px");
+ grid.getColumn("zipCode").setRenderer(new NumberRenderer());
+ grid.setColumnOrder("firstName", "lastName", "streetAddress",
+ "zipCode", "city");
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ addComponent(grid);
+
+ Button showHide = new Button("Hide firstName",
+ new Button.ClickListener() {
+ private static final long serialVersionUID = 8107530972693788705L;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ if (grid.getColumn("firstName") != null) {
+ grid.removeColumn("firstName");
+ event.getButton().setCaption("Show firstName");
+ } else {
+ grid.addColumn("firstName");
+ grid.setColumnOrder("firstName", "lastName",
+ "streetAddress", "zipCode", "city");
+
+ event.getButton().setCaption("Hide firstName");
+ }
+ }
+ });
+ showHide.setId("show_hide");
+
+ Button selectionMode = new Button("Set multiselect",
+ new Button.ClickListener() {
+ private static final long serialVersionUID = 8107530972693788705L;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ if (grid.getSelectionModel() instanceof SelectionModel.Single) {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ } else {
+ grid.setSelectionMode(SelectionMode.SINGLE);
+ }
+ }
+ });
+ selectionMode.setId("selection_mode");
+
+ Button join = new Button("Add Join header column",
+ new Button.ClickListener() {
+ private static final long serialVersionUID = -5330801275551280623L;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ if (row == null) {
+ row = grid.prependHeaderRow();
+ if (grid.getColumn("firstName") != null) {
+ row.join("firstName", "lastName").setText(
+ "Full Name");
+ }
+ row.join("streetAddress", "zipCode", "city")
+ .setText("Address");
+ } else {
+ grid.removeHeaderRow(row);
+ row = null;
+ }
+ }
+ });
+ join.setId("join");
+ addComponent(new HorizontalLayout(showHide, selectionMode, join));
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Grid for testing header re-rendering.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 17131;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChangeTest.java b/uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChangeTest.java
new file mode 100644
index 0000000000..0e2a3d6ac6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/grid/GridHeaderFormatChangeTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.grid;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.testbench.parallel.TestCategory;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+@TestCategory("grid")
+public class GridHeaderFormatChangeTest extends MultiBrowserTest {
+
+ @Test
+ public void testHeaderRetainsSelectAllForColumnRemoval() {
+ openTestURL();
+ GridElement grid = $(GridElement.class).first();
+
+ // Assert that we do not have the select all checkbox
+ Assert.assertTrue(
+ "Found input in header even though none should exist.", grid
+ .getHeader().findElements(By.tagName("input"))
+ .isEmpty());
+
+ // Set grid into multiselection mode
+ toggleSelectionMode();
+
+ // Assert that we now have a select all checkbox in the header
+ Assert.assertFalse("Expected one input field in header", grid
+ .getHeader().findElements(By.tagName("input")).isEmpty());
+
+ // Hide the firstName column from the grid.
+ toggleFirstName();
+
+ // Assert that we still have the select all checkbox in the header.
+ Assert.assertFalse("Header was missing checkbox after hiding column",
+ grid.getHeader().findElements(By.tagName("input")).isEmpty());
+
+ // Show the firstName column.
+ toggleFirstName();
+
+ // Assert that we still have the select all checkbox in the header.
+ Assert.assertFalse(
+ "Header was missing checkbox after bringing back column", grid
+ .getHeader().findElements(By.tagName("input"))
+ .isEmpty());
+ }
+
+ @Test
+ public void testHeaderRetainsSelectAllForJoinColumnAdd() {
+ openTestURL();
+ GridElement grid = $(GridElement.class).first();
+
+ // Assert that we do not have the select all checkbox
+ Assert.assertTrue(
+ "Found input in header even though none should exist.", grid
+ .getHeader().findElements(By.tagName("input"))
+ .isEmpty());
+
+ // Set grid into multiselection mode
+ toggleSelectionMode();
+
+ // Assert that we now have a select all checkbox in the header
+ Assert.assertFalse("Expected one input field in header", grid
+ .getHeader().findElements(By.tagName("input")).isEmpty());
+
+ // Add Join columns header
+ toggleJoin();
+
+ // Assert that we still have the select all checkbox in the header.
+ Assert.assertFalse("Header was missing checkbox after hiding column",
+ grid.getHeader().findElements(By.tagName("input")).isEmpty());
+
+ // remove Join Columns header
+ toggleJoin();
+
+ // Assert that we still have the select all checkbox in the header.
+ Assert.assertFalse(
+ "Header was missing checkbox after bringing back column", grid
+ .getHeader().findElements(By.tagName("input"))
+ .isEmpty());
+ }
+
+ @Test
+ public void selectAllShouldKeepState() {
+ openTestURL();
+ GridElement grid = $(GridElement.class).first();
+
+ // Assert that we do not have the select all checkbox
+ Assert.assertTrue(
+ "Found input in header even though none should exist.", grid
+ .getHeader().findElements(By.tagName("input"))
+ .isEmpty());
+
+ // Set grid into multiselection mode
+ toggleSelectionMode();
+
+ // Assert that we now have a select all checkbox in the header
+ Assert.assertFalse("Should not be selected after adding", grid
+ .getHeader().findElement(By.tagName("input")).isSelected());
+
+ grid.getHeader().findElement(By.tagName("input")).click();
+
+ // Assert that checkbox is checked
+ assertSelectAllChecked(
+ "Not selected even though we just clicked selection", grid);
+
+ // Hide the firstName column from the grid.
+ toggleFirstName();
+
+ // Assert that checkbox is still checked
+ assertSelectAllChecked("Selection disappeared after removing column",
+ grid);
+
+ // Show the firstName column.
+ toggleFirstName();
+
+ // Assert that checkbox is still checked
+ assertSelectAllChecked("Selection disappeared after adding column",
+ grid);
+
+ }
+
+ private void assertSelectAllChecked(String message, GridElement grid) {
+ Assert.assertTrue(message,
+ grid.getHeader().findElement(By.tagName("input")).isSelected());
+ }
+
+ private void toggleSelectionMode() {
+ $(ButtonElement.class).id("selection_mode").click();
+ }
+
+ private void toggleFirstName() {
+ $(ButtonElement.class).id("show_hide").click();
+ }
+
+ private void toggleJoin() {
+ $(ButtonElement.class).id("join").click();
+ }
+}