]> source.dussan.org Git - vaadin-framework.git/commitdiff
Allow setting style names for header and footer cells (#7225)
authorArtur Signell <artur@vaadin.com>
Wed, 26 Nov 2014 21:02:23 +0000 (23:02 +0200)
committerArtur Signell <artur@vaadin.com>
Mon, 1 Dec 2014 13:11:00 +0000 (13:11 +0000)
Change-Id: Ieb8f5b36466a2d579e9c82f16613f6bc8952c831

client/src/com/vaadin/client/ui/grid/Grid.java
client/src/com/vaadin/client/ui/grid/GridConnector.java
client/src/com/vaadin/client/ui/grid/GridStaticSection.java
server/src/com/vaadin/ui/Grid.java
shared/src/com/vaadin/shared/ui/grid/GridStaticSectionState.java
uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNames.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java [new file with mode: 0644]

index 851d11bd86af560f5d8ee8b5c30ed538f8724213..c0edfd9eb88cd94b1f0ae9a02405f6d45d938bc0 100644 (file)
@@ -88,6 +88,7 @@ import com.vaadin.shared.ui.grid.Range;
 import com.vaadin.shared.ui.grid.ScrollDestination;
 import com.vaadin.shared.ui.grid.SortDirection;
 import com.vaadin.shared.ui.grid.SortEventOriginator;
+import com.vaadin.shared.util.SharedUtil;
 
 /**
  * A data grid view that supports columns and lazy loading of data rows from a
@@ -1338,6 +1339,7 @@ public class Grid<T> extends ResizeComposite implements
 
         private GridStaticSection<?> section;
         private RowContainer container;
+        private static final String CUSTOM_STYLE_PROPERTY_NAME = "customStyle";
 
         public StaticSectionUpdater(GridStaticSection<?> section,
                 RowContainer container) {
@@ -1364,19 +1366,34 @@ public class Grid<T> extends ResizeComposite implements
                 // Assign colspan to cell before rendering
                 cell.setColSpan(metadata.getColspan());
 
+                TableCellElement element = cell.getElement();
                 switch (metadata.getType()) {
                 case TEXT:
-                    cell.getElement().setInnerText(metadata.getText());
+                    element.setInnerText(metadata.getText());
                     break;
                 case HTML:
-                    cell.getElement().setInnerHTML(metadata.getHtml());
+                    element.setInnerHTML(metadata.getHtml());
                     break;
                 case WIDGET:
                     preDetach(row, Arrays.asList(cell));
-                    cell.getElement().setInnerHTML("");
+                    element.setInnerHTML("");
                     postAttach(row, Arrays.asList(cell));
                     break;
                 }
+                String oldStyleName = element
+                        .getPropertyString(CUSTOM_STYLE_PROPERTY_NAME);
+                String newStyleName = metadata.getStyleName();
+
+                if (!SharedUtil.equals(oldStyleName, newStyleName)) {
+                    if (oldStyleName != null) {
+                        element.removeClassName(oldStyleName);
+                    }
+                    if (newStyleName != null) {
+                        element.addClassName(newStyleName);
+                    }
+                    element.setPropertyString(CUSTOM_STYLE_PROPERTY_NAME,
+                            newStyleName);
+                }
 
                 cellFocusHandler.updateFocusedCellStyle(cell, container);
             }
index 00acf94de38f7d4a62f39df32ae4489aadfc3981..feb46af0c11947b0b2d9d69cf08093389c5db1f1 100644 (file)
@@ -526,6 +526,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements
             throw new IllegalStateException("unexpected cell type: "
                     + cellState.type);
         }
+        cell.setStyleName(cellState.styleName);
     }
 
     /**
index 79aef4601fcfcee28746c9174ac27f19c8805b8c..a85001f58cc1d57d061ac8181f9cdc0455fde74d 100644 (file)
@@ -49,6 +49,8 @@ abstract class GridStaticSection<ROWTYPE extends GridStaticSection.StaticRow<?>>
 
         private GridStaticCellType type = GridStaticCellType.TEXT;
 
+        private String styleName = null;
+
         /**
          * Sets the text displayed in this cell.
          * 
@@ -176,6 +178,28 @@ abstract class GridStaticSection<ROWTYPE extends GridStaticSection.StaticRow<?>>
         public GridStaticCellType getType() {
             return type;
         }
+
+        /**
+         * Returns the custom style name for this cell.
+         * 
+         * @return the style name or null if no style name has been set
+         */
+        public String getStyleName() {
+            return styleName;
+        }
+
+        /**
+         * Sets a custom style name for this cell.
+         * 
+         * @param styleName
+         *            the style name to set or null to not use any style name
+         */
+        public void setStyleName(String styleName) {
+            this.styleName = styleName;
+            section.requestSectionRefresh();
+
+        }
+
     }
 
     /**
index 715190e29378b6bb2f69e4a5e464616c1f0621e4..5afb0038e0fbe0f9b237e16ebe0412526b6a269a 100644 (file)
@@ -470,6 +470,27 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,
                 cellState.type = GridStaticCellType.WIDGET;
                 row.section.markAsDirty();
             }
+
+            /**
+             * Returns the custom style name for this cell.
+             * 
+             * @return the style name or null if no style name has been set
+             */
+            public String getStyleName() {
+                return cellState.styleName;
+            }
+
+            /**
+             * Sets a custom style name for this cell.
+             * 
+             * @param styleName
+             *            the style name to set
+             */
+            public void setStyleName(String styleName) {
+                cellState.styleName = styleName;
+                row.section.markAsDirty();
+            }
+
         }
 
         protected Grid grid;
index 5a04bb25586114026773a43eebb2cecf94f0660e..39d84510f6b48fad03a36e5ee81b8e1f29a255fb 100644 (file)
@@ -42,6 +42,8 @@ public class GridStaticSectionState implements Serializable {
         public GridStaticCellType type = GridStaticCellType.TEXT;
 
         public String columnId;
+
+        public String styleName = null;
     }
 
     public static class RowState implements Serializable {
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNames.java b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNames.java
new file mode 100644 (file)
index 0000000..923e964
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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 com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.tests.components.beanitemcontainer.BeanItemContainerGenerator;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.FooterCell;
+import com.vaadin.ui.Grid.FooterRow;
+import com.vaadin.ui.Grid.HeaderCell;
+import com.vaadin.ui.Grid.HeaderRow;
+
+@Theme("valo")
+public class GridHeaderStyleNames extends AbstractTestUIWithLog {
+
+    private HeaderCell ageHeaderCell;
+    private HeaderCell mergedCityCountryCell;
+    private FooterCell ageFooterCell;
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        Grid grid = new Grid();
+        grid.setContainerDataSource(BeanItemContainerGenerator
+                .createContainer(100));
+
+        ageHeaderCell = grid.getDefaultHeaderRow().getCell("age");
+
+        HeaderRow row = grid.prependHeaderRow();
+        mergedCityCountryCell = row.join("city", "country");
+        mergedCityCountryCell.setText("Merged cell");
+        addComponent(grid);
+
+        FooterRow footerRow = grid.appendFooterRow();
+        ageFooterCell = footerRow.getCell("age");
+
+        getPage()
+                .getStyles()
+                .add(".age {background-image: linear-gradient(to bottom,green 2%, #efefef 98%) !important;}");
+        getPage()
+                .getStyles()
+                .add(".valo .v-grid-header .v-grid-cell.city-country {background-image: linear-gradient(to bottom,yellow 2%, #efefef 98%);}");
+        getPage()
+                .getStyles()
+                .add(".valo .v-grid-footer .v-grid-cell.age-footer {background-image: linear-gradient(to bottom,blue 2%, #efefef 98%);}");
+
+        setStyles(true);
+
+        Button b = new Button("Toggle styles");
+        b.addClickListener(new ClickListener() {
+            private boolean stylesOn = true;
+
+            @Override
+            public void buttonClick(ClickEvent event) {
+                setStyles(!stylesOn);
+                stylesOn = !stylesOn;
+            }
+        });
+        addComponent(b);
+    }
+
+    protected void setStyles(boolean set) {
+        if (set) {
+            ageHeaderCell.setStyleName("age");
+            ageFooterCell.setStyleName("age-footer");
+            mergedCityCountryCell.setStyleName("city-country");
+        } else {
+            ageHeaderCell.setStyleName(null);
+            ageFooterCell.setStyleName(null);
+            mergedCityCountryCell.setStyleName(null);
+        }
+
+    }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java
new file mode 100644 (file)
index 0000000..5b3b29d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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.Before;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.tests.annotations.TestCategory;
+import com.vaadin.tests.components.grid.GridElement.GridCellElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+@TestCategory("grid")
+public class GridHeaderStyleNamesTest extends SingleBrowserTest {
+
+    private GridElement grid;
+
+    @Before
+    public void findGridCells() {
+        openTestURL();
+        grid = $(GridElement.class).first();
+    }
+
+    private GridCellElement getMergedHeaderCell() {
+        return grid.getHeaderCell(0, 3);
+    }
+
+    private GridCellElement getAgeFooterCell() {
+        return grid.getFooterCell(0, 2);
+    }
+
+    @Test
+    public void styleNamesCanBeAddedAndRemoved() {
+        ButtonElement toggleStyles = $(ButtonElement.class).caption(
+                "Toggle styles").first();
+
+        assertStylesSet(true);
+        toggleStyles.click();
+        assertStylesSet(false);
+        toggleStyles.click();
+        assertStylesSet(true);
+    }
+
+    private void assertStylesSet(boolean set) {
+        if (set) {
+            assertHasStyleName(
+                    "Footer cell should have the assigned 'age-footer' class name",
+                    getAgeFooterCell(), "age-footer");
+            assertHasStyleName(
+                    "Header cell should have the assigned 'age' class name",
+                    getAgeHeaderCell(), "age");
+            assertHasStyleName(
+                    "The merged header cell should have the assigned 'city-country' class name",
+                    getMergedHeaderCell(), "city-country");
+        } else {
+            assertHasNotStyleName(
+                    "Footer cell should not have the removed 'age-footer' class name",
+                    getAgeFooterCell(), "age-footer");
+            assertHasNotStyleName(
+                    "Header cell should not have the removed 'age' class name",
+                    getAgeHeaderCell(), "age");
+            assertHasNotStyleName(
+                    "Ther merged header cell should not have the removed 'city-country' class name",
+                    getMergedHeaderCell(), "city-country");
+        }
+        assertHasStyleName(
+                "The default v-grid-cell style name should not be removed from the header cell",
+                getAgeHeaderCell(), "v-grid-cell");
+        assertHasStyleName(
+                "The default v-grid-cell style name should not be removed from the footer cell",
+                getAgeFooterCell(), "v-grid-cell");
+        assertHasStyleName(
+                "The default v-grid-cell style name should not be removed from the merged header cell",
+                getMergedHeaderCell(), "v-grid-cell");
+
+    }
+
+    private WebElement getAgeHeaderCell() {
+        return grid.getHeaderCell(1, 2);
+    }
+
+    private void assertHasStyleName(String message, WebElement element,
+            String stylename) {
+        if (!hasCssClass(element, stylename)) {
+            Assert.fail(message);
+        }
+    }
+
+    private void assertHasNotStyleName(String message, WebElement element,
+            String stylename) {
+        if (hasCssClass(element, stylename)) {
+            Assert.fail(message);
+        }
+    }
+
+}