]> source.dussan.org Git - vaadin-framework.git/commitdiff
Grid's columns hidable with toggles in the sidebar (#17023)
authorPekka Hyvönen <pekka@vaadin.com>
Wed, 18 Mar 2015 12:37:56 +0000 (14:37 +0200)
committerHenrik Paul <henrik@vaadin.com>
Wed, 18 Mar 2015 15:25:59 +0000 (15:25 +0000)
There is know issue with hidden columns and reordering columns.

Change-Id: If308c84aed5dd23c2c00cb38ed6bba41c6f1a28e

client/src/com/vaadin/client/widgets/Grid.java
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java

index e84ea7d1f52a3de5f796ba4423ef60198ebc1050..0238d4a1a07d884a9e3abe4c2ee5438e85bfb4a1 100644 (file)
@@ -66,6 +66,7 @@ import com.google.gwt.user.client.ui.HasEnabled;
 import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
 import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.ResizeComposite;
+import com.google.gwt.user.client.ui.ToggleButton;
 import com.google.gwt.user.client.ui.VerticalPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.client.BrowserInfo;
@@ -2791,6 +2792,11 @@ public class Grid<T> extends ResizeComposite implements
     /**
      * Sidebar displaying toggles for hidable columns and additional custom
      * widgets.
+     * <p>
+     * The button for opening the sidebar is automatically visible inside the
+     * grid, if it contains any column hiding options or custom widgets. The
+     * column hiding toggles and custom widgets become visible once the sidebar
+     * has been opened.
      * 
      * @since
      */
@@ -2808,13 +2814,23 @@ public class Grid<T> extends ResizeComposite implements
             }
         };
 
+        /**
+         * Contains all the widgets which should be shown once the sidebar is
+         * opened
+         */
+        private final List<Widget> widgets = new ArrayList<Widget>();
+
         private final VerticalPanel rootContainer;
 
         private final VButton openCloseButton;
 
+        private final Grid<?> grid;
+
         private boolean open;
 
-        public Sidebar() {
+        public Sidebar(Grid<?> grid) {
+            this.grid = grid;
+
             rootContainer = new VerticalPanel();
             initWidget(rootContainer);
 
@@ -2838,6 +2854,9 @@ public class Grid<T> extends ResizeComposite implements
             if (!open) {
                 addStyleName("opened");
                 open = true;
+                for (Widget w : widgets) {
+                    rootContainer.add(w);
+                }
             }
         }
 
@@ -2850,6 +2869,8 @@ public class Grid<T> extends ResizeComposite implements
             if (open) {
                 removeStyleName("opened");
                 open = false;
+                rootContainer.clear();
+                rootContainer.add(openCloseButton);
             }
         }
 
@@ -2866,12 +2887,158 @@ public class Grid<T> extends ResizeComposite implements
             return open;
         }
 
+        /**
+         * Adds or moves the given widget to the end of the sidebar.
+         * 
+         * @param widget
+         *            the widget to add or move
+         */
+        public void add(Widget widget) {
+            widgets.remove(widget);
+            widgets.add(widget);
+            if (open) {
+                rootContainer.add(widget);
+            }
+            updateVisibility();
+        }
+
+        /**
+         * Removes the given widget from the sidebar.
+         * 
+         * @param widget
+         *            the widget to remove
+         */
+        public void remove(Widget widget) {
+            widgets.remove(widget);
+            if (open) {
+                rootContainer.remove(widget);
+            }
+            updateVisibility();
+        }
+
+        /**
+         * Inserts given widget to the given index inside the sidebar. If the
+         * widget is already in the sidebar, then it is moved to the new index.
+         * <p>
+         * See
+         * {@link VerticalPanel#insert(com.google.gwt.user.client.ui.IsWidget, int)}
+         * for further details.
+         * 
+         * @param widget
+         *            the widget to insert
+         * @param beforeIndex
+         *            0-based index position for the widget.
+         */
+        public void insert(Widget widget, int beforeIndex) {
+            widgets.remove(widget);
+            widgets.add(beforeIndex, widget);
+            if (open) {
+                // the first widget in the container is always the open button
+                rootContainer.insert(widget, beforeIndex + 1);
+            }
+            updateVisibility();
+        }
+
         @Override
         public void setStylePrimaryName(String styleName) {
             super.setStylePrimaryName(styleName);
             openCloseButton.setStylePrimaryName(styleName + "-button");
         }
 
+        private void updateVisibility() {
+            final boolean hasWidgets = widgets.size() > 0;
+            final boolean isVisible = getParent() != null;
+            if (isVisible && !hasWidgets) {
+                getElement().removeFromParent();
+                removeFromParent();
+            } else if (!isVisible && hasWidgets) {
+                grid.getElement().appendChild(getElement());
+                Grid.setParent(this, grid);
+            }
+        }
+
+    }
+
+    /**
+     * UI and functionality related to hiding columns with toggles in the
+     * sidebar.
+     */
+    private final class ColumnHider extends VerticalPanel {
+
+        ColumnHider() {
+            setStyleName("column-hiding-panel");
+        }
+
+        /** Map from columns to their hiding toggles, component might change */
+        private HashMap<Column<?, T>, ToggleButton> columnToHidingToggleMap = new HashMap<Grid.Column<?, T>, ToggleButton>();
+
+        private void updateColumnHidable(final Column<?, T> column) {
+            if (column.isHidable()) {
+                ToggleButton cb = columnToHidingToggleMap.get(column);
+                if (cb == null) {
+                    cb = createToggle(column);
+                }
+                updateToggleValue(cb, column.isHidden());
+            } else if (columnToHidingToggleMap.containsValue(column)) {
+                ((Widget) columnToHidingToggleMap.remove(column))
+                        .removeFromParent();
+            }
+            updateTogglesOrder();
+            updatePanelVisibility();
+        }
+
+        private ToggleButton createToggle(final Column<?, T> column) {
+            ToggleButton toggle = new ToggleButton(column.headerCaption);
+            toggle.addStyleName("column-hiding-toggle");
+            toggle.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
+
+                @Override
+                public void onValueChange(ValueChangeEvent<Boolean> event) {
+                    column.setHidden(!event.getValue(), true);
+                }
+            });
+            columnToHidingToggleMap.put(column, toggle);
+            return toggle;
+        }
+
+        private void updateTogglesOrder() {
+            clear();
+            for (Column<?, T> c : getColumns()) {
+                if (c.isHidable()) {
+                    add(columnToHidingToggleMap.get(c));
+                }
+            }
+        }
+
+        private void updatePanelVisibility() {
+            final boolean columnHidable = getWidgetCount() > 0;
+            // parent for the panel might be null sidebar is not open
+            final boolean columnTogglesPanelIsVisible = sidebar.widgets
+                    .contains(this);
+
+            if (columnHidable && !columnTogglesPanelIsVisible) {
+                sidebar.insert(this, 0);
+            } else if (!columnHidable && columnTogglesPanelIsVisible) {
+                sidebar.remove(this);
+            }
+        }
+
+        private void updateToggleValue(Column<?, T> column) {
+            if (column.isHidable()) {
+                updateToggleValue(columnToHidingToggleMap.get(column),
+                        column.isHidden());
+            } // else we can just ignore
+        }
+
+        private void updateToggleValue(ToggleButton hasValue, boolean hidden) {
+            hasValue.setValue(!hidden, false);
+            hasValue.setStyleName("hidden", hidden);
+        }
+
+        private void updateColumnHidingToggleCaption(Column<?, T> column) {
+            columnToHidingToggleMap.get(column).setText(column.headerCaption);
+        }
+
     }
 
     /**
@@ -2883,7 +3050,7 @@ public class Grid<T> extends ResizeComposite implements
 
     private final Footer footer = GWT.create(Footer.class);
 
-    private final Sidebar sidebar = GWT.create(Sidebar.class);
+    private final Sidebar sidebar = new Sidebar(this);
 
     /**
      * List of columns in the grid. Order defines the visible order.
@@ -2963,6 +3130,8 @@ public class Grid<T> extends ResizeComposite implements
 
     private boolean columnReorderingAllowed;
 
+    private ColumnHider columnHider = new ColumnHider();
+
     private DragAndDropHandler dndHandler = new DragAndDropHandler();
 
     private AutoScroller autoScroller = new AutoScroller(this);
@@ -3589,6 +3758,9 @@ public class Grid<T> extends ResizeComposite implements
             HeaderRow row = grid.getHeader().getDefaultRow();
             if (row != null) {
                 row.getCell(this).setText(headerCaption);
+                if (isHidable()) {
+                    grid.columnHider.updateColumnHidingToggleCaption(this);
+                }
             }
         }
 
@@ -3756,6 +3928,10 @@ public class Grid<T> extends ResizeComposite implements
          *            to show
          */
         public void setHidden(boolean hidden) {
+            setHidden(hidden, false);
+        }
+
+        private void setHidden(boolean hidden, boolean userOriginated) {
             if (this.hidden != hidden) {
                 if (hidden) {
                     grid.escalator.getColumnConfiguration().removeColumns(
@@ -3766,9 +3942,10 @@ public class Grid<T> extends ResizeComposite implements
                     grid.escalator.getColumnConfiguration().insertColumns(
                             grid.getVisibleColumns().indexOf(this), 1);
                 }
+                grid.columnHider.updateToggleValue(this);
                 scheduleColumnWidthRecalculator();
                 this.grid.fireEvent(new ColumnVisibilityChangeEvent<T>(this,
-                        hidden, false));
+                        hidden, userOriginated));
             }
         }
 
@@ -3796,8 +3973,10 @@ public class Grid<T> extends ResizeComposite implements
          *            <code>false</code> if not
          */
         public void setHidable(boolean hidable) {
-            this.hidable = hidable;
-            grid.updateSideBarVisibility();
+            if (this.hidable != hidable) {
+                this.hidable = hidable;
+                grid.columnHider.updateColumnHidable(this);
+            }
         }
 
         /**
@@ -6686,6 +6865,8 @@ public class Grid<T> extends ResizeComposite implements
             row.calculateColspans();
         }
 
+        columnHider.updateTogglesOrder();
+
         fireEvent(new ColumnReorderEvent<T>());
     }
 
@@ -7039,51 +7220,17 @@ public class Grid<T> extends ResizeComposite implements
         autoColumnWidthsRecalculator.schedule();
     }
 
-    /**
-     * Setter for displaying the grid's {@link Sidebar}. The sidebar is visible
-     * automatically when there are {@link Column#setHidable(boolean) hidable
-     * columns}.
-     * <p>
-     * Setting the sidebar visible doens't open it - it only shows the button
-     * for opening it. For opening and closing the sidebar use
-     * {@link Sidebar#open()} and {@link Sidebar#close()}.
-     * 
-     * @since
-     * @param visible
-     *            <code>true</code> for showing the sidebar, <code>false</code>
-     *            for removing it
-     */
-    public void setSidebarVisible(boolean visible) {
-        if ((sidebar.getParent() != null) != visible) {
-            if (visible) {
-                getElement().appendChild(sidebar.getElement());
-                setParent(sidebar, this);
-            } else {
-                sidebar.getElement().removeFromParent();
-                sidebar.removeFromParent();
-            }
-        }
-    }
-
     /**
      * Returns the sidebar for this grid.
+     * <p>
+     * The grid's sidebar shows the column hiding options for those columns that
+     * have been set as {@link Column#setHidable(boolean) hidable}.
      * 
      * @since
-     * @return
+     * @return the sidebar widget for this grid
      */
     public Sidebar getSidebar() {
         return sidebar;
     }
 
-    private void updateSideBarVisibility() {
-        boolean visible = false;
-        for (Column<?, T> c : getColumns()) {
-            if (c.isHidable()) {
-                visible = true;
-                break;
-            }
-        }
-        setSidebarVisible(visible);
-    }
-
 }
index 8b4eb0e26720916f69721e7975a4c9bb6752d7e4..90b572cffe8ba4b17e5d6aa082f31b210dea025f 100644 (file)
@@ -98,4 +98,9 @@ public abstract class GridBasicClientFeaturesTest extends GridBasicFeaturesTest
             assertColumnHeader("HEADER (0," + indices[i] + ")", headers.get(i));
         }
     }
+
+    protected void toggleColumnReorder() {
+        selectMenuPath("Component", "State", "Column Reordering");
+    }
+
 }
index ba4468da2c0fc12bf243b77d17aa5ce316062abd..87af43af12e15bf74d39c2630295a984e8701665 100644 (file)
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
 import java.util.List;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
@@ -43,12 +44,12 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
         selectMenuPath("Component", "State", "Width", "1000px");
         assertColumnHeaderOrder(0, 1, 2, 3, 4, 5, 6);
 
-        toggleHideColumn(0);
+        toggleHideColumnAPI(0);
         assertColumnHeaderOrder(1, 2, 3, 4, 5, 6);
 
-        toggleHideColumn(1);
-        toggleHideColumn(2);
-        toggleHideColumn(3);
+        toggleHideColumnAPI(1);
+        toggleHideColumnAPI(2);
+        toggleHideColumnAPI(3);
         assertColumnHeaderOrder(4, 5, 6, 7, 8);
     }
 
@@ -57,19 +58,19 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
         selectMenuPath("Component", "State", "Width", "1000px");
         assertColumnHeaderOrder(0, 1, 2, 3, 4, 5, 6);
 
-        toggleHideColumn(0);
+        toggleHideColumnAPI(0);
         assertColumnHeaderOrder(1, 2, 3, 4, 5, 6);
 
-        toggleHideColumn(0);
+        toggleHideColumnAPI(0);
         assertColumnHeaderOrder(0, 1, 2, 3, 4, 5, 6);
 
-        toggleHideColumn(1);
-        toggleHideColumn(2);
-        toggleHideColumn(3);
+        toggleHideColumnAPI(1);
+        toggleHideColumnAPI(2);
+        toggleHideColumnAPI(3);
         assertColumnHeaderOrder(0, 4, 5, 6, 7, 8);
 
-        toggleHideColumn(1);
-        toggleHideColumn(2);
+        toggleHideColumnAPI(1);
+        toggleHideColumnAPI(2);
         assertColumnHeaderOrder(0, 1, 2, 4, 5, 6);
     }
 
@@ -78,26 +79,26 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
         selectMenuPath("Component", "State", "Width", "1000px");
         assertColumnHeaderOrder(0, 1, 2, 3, 4, 5, 6);
 
-        toggleHideColumn(2);
+        toggleHideColumnAPI(2);
         assertColumnHeaderOrder(0, 1, 3, 4, 5, 6);
 
-        toggleHideColumn(2);
+        toggleHideColumnAPI(2);
         assertColumnHeaderOrder(0, 1, 2, 3, 4, 5, 6);
 
-        toggleHideColumn(2);
+        toggleHideColumnAPI(2);
         assertColumnHeaderOrder(0, 1, 3, 4, 5, 6);
 
-        toggleHideColumn(2);
+        toggleHideColumnAPI(2);
         assertColumnHeaderOrder(0, 1, 2, 3, 4, 5, 6);
     }
 
     @Test
-    public void testColumnHiding_onVisibilityChange_triggersClientSideEvent() {
+    public void testColumnHiding_changeVisibilityAPI_triggersClientSideEvent() {
         assertColumnHeaderOrder(0, 1, 2, 3, 4);
         selectMenuPath("Component", "Internals", "Listeners",
                 "Add Column Visibility Change listener");
 
-        toggleHideColumn(2);
+        toggleHideColumnAPI(2);
         assertColumnHeaderOrder(0, 1, 3, 4);
 
         WebElement webElement = findElement(By.id("columnvisibility"));
@@ -115,7 +116,7 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
         assertEquals(false, userOriginated);
         assertEquals(true, hidden);
 
-        toggleHideColumn(2);
+        toggleHideColumnAPI(2);
         assertColumnHeaderOrder(0, 1, 2, 3, 4);
 
         webElement = findElement(By.id("columnvisibility"));
@@ -132,12 +133,55 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
         assertEquals(false, hidden);
     }
 
+    @Test
+    public void testColumnHiding_changeVisibilityToggle_triggersClientSideEvent() {
+        assertColumnHeaderOrder(0, 1, 2, 3, 4);
+        selectMenuPath("Component", "Internals", "Listeners",
+                "Add Column Visibility Change listener");
+
+        toggleHidableColumnAPI(2);
+        clickSidebarOpenButton();
+        getColumnHidingToggle(2).click();
+        assertColumnHeaderOrder(0, 1, 3, 4);
+
+        WebElement webElement = findElement(By.id("columnvisibility"));
+        int counter = Integer.parseInt(webElement.getAttribute("counter"));
+        int columnIndex = Integer.parseInt(webElement
+                .getAttribute("columnindex"));
+        boolean userOriginated = Boolean.parseBoolean(webElement
+                .getAttribute("useroriginated"));
+        boolean hidden = Boolean.parseBoolean(webElement
+                .getAttribute("ishidden"));
+
+        assertNotNull("no event fired", webElement);
+        assertEquals(1, counter);
+        assertEquals(2, columnIndex);
+        assertEquals(true, userOriginated);
+        assertEquals(true, hidden);
+
+        getColumnHidingToggle(2).click();
+        assertColumnHeaderOrder(0, 1, 2, 3, 4);
+
+        webElement = findElement(By.id("columnvisibility"));
+        counter = Integer.parseInt(webElement.getAttribute("counter"));
+        columnIndex = Integer.parseInt(webElement.getAttribute("columnIndex"));
+        userOriginated = Boolean.parseBoolean(webElement
+                .getAttribute("userOriginated"));
+        hidden = Boolean.parseBoolean(webElement.getAttribute("ishidden"));
+
+        assertNotNull("no event fired", webElement);
+        assertEquals(2, counter);
+        assertEquals(2, columnIndex);
+        assertEquals(true, userOriginated);
+        assertEquals(false, hidden);
+    }
+
     @Test
     public void testColumnHidability_onTriggerColumnHidability_showsSidebarButton() {
         WebElement sidebar = getSidebar();
         assertNull(sidebar);
 
-        toggleHidableColumn(0);
+        toggleHidableColumnAPI(0);
 
         sidebar = getSidebar();
         assertNotNull(sidebar);
@@ -147,32 +191,248 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
     public void testColumnHidability_triggeringColumnHidabilityWithSeveralColumns_showsAndHidesSiderbarButton() {
         verifySidebarNotVisible();
 
-        toggleHidableColumn(3);
-        toggleHidableColumn(4);
+        toggleHidableColumnAPI(3);
+        toggleHidableColumnAPI(4);
 
         verifySidebarVisible();
 
-        toggleHidableColumn(3);
+        toggleHidableColumnAPI(3);
 
         verifySidebarVisible();
 
-        toggleHidableColumn(4);
+        toggleHidableColumnAPI(4);
 
         verifySidebarNotVisible();
     }
 
     @Test
     public void testColumnHidability_clickingSidebarButton_opensClosesSidebar() {
-        toggleHidableColumn(0);
+        toggleHidableColumnAPI(0);
         verifySidebarClosed();
 
-        getSidebarOpenButton().click();
+        clickSidebarOpenButton();
 
         verifySidebarOpened();
 
-        getSidebarOpenButton().click();
+        clickSidebarOpenButton();
+
+        verifySidebarClosed();
+    }
+
+    @Test
+    public void testColumnHidability_settingColumnHidable_showsToggleInSidebar() {
+        toggleHidableColumnAPI(0);
+        verifySidebarClosed();
+        clickSidebarOpenButton();
+        verifySidebarOpened();
+
+        verifyColumnHidingOption(0, false);
+    }
+
+    @Test
+    public void testColumnHiding_hidingColumnWithToggle_works() {
+        assertColumnHeaderOrder(0, 1, 2, 3, 4);
+        toggleHidableColumnAPI(0);
+        verifySidebarClosed();
+        clickSidebarOpenButton();
+        verifySidebarOpened();
+        verifyColumnHidingOption(0, false);
+
+        getColumnHidingToggle(0).click();
+        verifyColumnHidingOption(0, true);
+        assertColumnHeaderOrder(1, 2, 3, 4);
+
+        getColumnHidingToggle(0).click();
+        verifyColumnHidingOption(0, false);
+        assertColumnHeaderOrder(0, 1, 2, 3, 4);
+    }
+
+    @Test
+    public void testColumnHiding_updatingHiddenWhileSidebarClosed_updatesToggleValue() {
+        toggleHidableColumnAPI(0);
+        toggleHidableColumnAPI(3);
+        toggleHideColumnAPI(3);
+        assertColumnHeaderOrder(0, 1, 2, 4);
+        verifySidebarClosed();
+
+        clickSidebarOpenButton();
+        verifySidebarOpened();
+        verifyColumnHidingOption(0, false);
+        verifyColumnHidingOption(3, true);
 
+        clickSidebarOpenButton();
         verifySidebarClosed();
+
+        toggleHideColumnAPI(0);
+        toggleHideColumnAPI(3);
+
+        clickSidebarOpenButton();
+        verifySidebarOpened();
+        verifyColumnHidingOption(0, true);
+        verifyColumnHidingOption(3, false);
+
+    }
+
+    @Test
+    public void testColumnHiding_hidingMultipleColumnsWithToggle_hidesColumns() {
+        assertColumnHeaderOrder(0, 1, 2, 3, 4);
+
+        toggleHideColumnAPI(1);
+        toggleHidableColumnAPI(0);
+        toggleHidableColumnAPI(1);
+        toggleHidableColumnAPI(2);
+        toggleHidableColumnAPI(3);
+        toggleHidableColumnAPI(4);
+        verifySidebarClosed();
+        assertColumnHeaderOrder(0, 2, 3, 4);
+
+        clickSidebarOpenButton();
+        verifySidebarOpened();
+        verifyColumnHidingOption(0, false);
+        verifyColumnHidingOption(1, true);
+        verifyColumnHidingOption(2, false);
+        verifyColumnHidingOption(3, false);
+        verifyColumnHidingOption(4, false);
+
+        // must be done in a funny order so that the header indexes won't break
+        // (because of data source uses counter)
+        getColumnHidingToggle(1).click();
+        getColumnHidingToggle(2).click();
+        getColumnHidingToggle(3).click();
+        getColumnHidingToggle(4).click();
+        getColumnHidingToggle(0).click();
+        verifyColumnHidingOption(0, true);
+        verifyColumnHidingOption(1, false);
+        verifyColumnHidingOption(2, true);
+        verifyColumnHidingOption(3, true);
+        verifyColumnHidingOption(4, true);
+
+        assertColumnHeaderOrder(1, 5, 6, 7);
+
+        getColumnHidingToggle(0).click();
+        getColumnHidingToggle(2).click();
+        getColumnHidingToggle(1).click();
+        verifyColumnHidingOption(0, false);
+        verifyColumnHidingOption(1, true);
+        verifyColumnHidingOption(2, false);
+        assertColumnHeaderOrder(0, 2, 5, 6);
+    }
+
+    @Test
+    public void testColumnHidability_changingHidabilityWhenSidebarClosed_addsRemovesToggles() {
+        toggleHideColumnAPI(0);
+        toggleHideColumnAPI(4);
+        assertColumnHeaderOrder(1, 2, 3, 5);
+        toggleHidableColumnAPI(0);
+        toggleHidableColumnAPI(3);
+        toggleHidableColumnAPI(4);
+        verifySidebarClosed();
+
+        clickSidebarOpenButton();
+        verifySidebarOpened();
+        verifyColumnHidingOption(0, true);
+        verifyColumnHidingOption(3, false);
+        verifyColumnHidingOption(4, true);
+
+        clickSidebarOpenButton();
+        verifySidebarClosed();
+
+        toggleHidableColumnAPI(0);
+        toggleHidableColumnAPI(3);
+
+        verifySidebarClosed();
+        clickSidebarOpenButton();
+        verifySidebarOpened();
+        verifyColumnHidingOption(4, true);
+
+        assertNull(getColumnHidingToggle(0));
+        assertNull(getColumnHidingToggle(3));
+    }
+
+    @Test
+    public void testColumnHidability_togglingHidability_placesTogglesInRightOrder() {
+        toggleHidableColumnAPI(3);
+        toggleHidableColumnAPI(2);
+        clickSidebarOpenButton();
+
+        verifyColumnHidingTogglesOrder(2, 3);
+
+        toggleHidableColumnAPI(1);
+        toggleHidableColumnAPI(2);
+        toggleHidableColumnAPI(6);
+        toggleHidableColumnAPI(0);
+
+        verifyColumnHidingTogglesOrder(0, 1, 3, 6);
+
+        clickSidebarOpenButton();
+
+        toggleHidableColumnAPI(2);
+        toggleHidableColumnAPI(4);
+        toggleHidableColumnAPI(7);
+
+        clickSidebarOpenButton();
+
+        verifyColumnHidingTogglesOrder(0, 1, 2, 3, 4, 6, 7);
+    }
+
+    @Test
+    public void testColumnHidability_reorderingColumns_updatesColumnToggleOrder() {
+        selectMenuPath("Component", "State", "Width", "1000px");
+        toggleHidableColumnAPI(0);
+        toggleHidableColumnAPI(1);
+        toggleHidableColumnAPI(3);
+        toggleHidableColumnAPI(4);
+        clickSidebarOpenButton();
+        verifyColumnHidingTogglesOrder(0, 1, 3, 4);
+        clickSidebarOpenButton();
+
+        toggleColumnReorder();
+        dragAndDropColumnHeader(0, 3, 0, 5);
+
+        assertColumnHeaderOrder(3, 0, 1, 2, 4);
+        clickSidebarOpenButton();
+        verifyColumnHidingTogglesOrder(3, 0, 1, 4);
+
+        clickSidebarOpenButton();
+        dragAndDropColumnHeader(0, 1, 3, 100);
+        dragAndDropColumnHeader(0, 4, 0, 5);
+        dragAndDropColumnHeader(0, 3, 0, 5);
+
+        assertColumnHeaderOrder(2, 4, 3, 1, 0);
+        clickSidebarOpenButton();
+        verifyColumnHidingTogglesOrder(4, 3, 1, 0);
+    }
+
+    // know issue, will be fixed in next patch
+    @Test
+    @Ignore
+    public void testColumnHidingAndReorder_reorderingOverHiddenColumns_orderIsKept() {
+        toggleColumnReorder();
+        toggleHideColumnAPI(0);
+        assertColumnHeaderOrder(1, 2, 3, 4, 5);
+
+        dragAndDropColumnHeader(0, 1, 0, 5);
+        assertColumnHeaderOrder(2, 1, 3, 4, 5);
+
+        toggleHideColumnAPI(0);
+        assertColumnHeaderOrder(0, 2, 1, 3, 4, 5);
+    }
+
+    private void verifyColumnHidingTogglesOrder(int... indices) {
+        WebElement sidebar = getSidebar();
+        List<WebElement> elements = sidebar.findElements(By
+                .className("column-hiding-toggle"));
+        for (int i = 0; i < indices.length; i++) {
+            WebElement e = elements.get(i);
+            assertTrue(("Header (0," + indices[i] + ")").equalsIgnoreCase(e
+                    .getText()));
+        }
+    }
+
+    private void verifyColumnHidingOption(int columnIndex, boolean hidden) {
+        WebElement columnHidingToggle = getColumnHidingToggle(columnIndex);
+        assertEquals(hidden,
+                columnHidingToggle.getAttribute("class").contains("hidden"));
     }
 
     private void verifySidebarOpened() {
@@ -206,12 +466,33 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
         return elements.isEmpty() ? null : elements.get(0);
     }
 
-    private void toggleHidableColumn(int columnIndex) {
+    /**
+     * Returns the toggle inside the sidebar for hiding the column at the given
+     * index, or null if not found.
+     */
+    private WebElement getColumnHidingToggle(int columnIndex) {
+        WebElement sidebar = getSidebar();
+        List<WebElement> elements = sidebar.findElements(By
+                .className("column-hiding-toggle"));
+        for (WebElement e : elements) {
+            if (("Header (0," + columnIndex + ")")
+                    .equalsIgnoreCase(e.getText())) {
+                return e;
+            }
+        }
+        return null;
+    }
+
+    private void clickSidebarOpenButton() {
+        getSidebarOpenButton().click();
+    }
+
+    private void toggleHidableColumnAPI(int columnIndex) {
         selectMenuPath("Component", "Columns", "Column " + columnIndex,
                 "Hidable");
     }
 
-    private void toggleHideColumn(int columnIndex) {
+    private void toggleHideColumnAPI(int columnIndex) {
         selectMenuPath("Component", "Columns", "Column " + columnIndex,
                 "Hidden");
     }
index 685c00bbbd4c60ba2ecf942787c7ff0d82231d4a..023c2068257f7b0efd38358f880efdb5e7c7f1e0 100644 (file)
@@ -601,10 +601,6 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest {
         assertColumnHeaderOrder(1, 2, 0, 3, 4);
     }
 
-    private void toggleColumnReorder() {
-        selectMenuPath("Component", "State", "Column Reordering");
-    }
-
     private void toggleSortableColumn(int index) {
         selectMenuPath("Component", "Columns", "Column " + index, "Sortable");
     }