diff --git a/WebContent/VAADIN/themes/base/grid/grid.scss b/WebContent/VAADIN/themes/base/grid/grid.scss index 20f84788854..eb6e0112ada 100644 --- a/WebContent/VAADIN/themes/base/grid/grid.scss +++ b/WebContent/VAADIN/themes/base/grid/grid.scss @@ -52,6 +52,8 @@ $v-grid-editor-background-color: $v-grid-row-background-color !default; .#{$primaryStyleName}-tablewrapper { border: $v-grid-border; } + + // Column drag and drop elements .#{$primaryStyleName} .header-drag-table { border-spacing: 0; @@ -76,6 +78,31 @@ $v-grid-editor-background-color: $v-grid-row-background-color !default; } } } + + // Sidebar + + .#{$primaryStyleName}-sidebar { + position: absolute; + top: 1px; + right : 0; + + background-color: $v-grid-header-background-color; + border-left: $v-grid-header-border; + border-bottom: $v-grid-header-border; + z-index: 5; + + .#{$primaryStyleName}-sidebar-button { + height: $v-grid-header-row-height; + + &:after { + content: "\f0c9"; + font-family: FontAwesome, sans-serif; + font-size: $v-grid-header-font-size; + line-height: $v-grid-header-row-height; + padding: 0 $v-grid-cell-padding-horizontal; + } + } + } // Common cell styles diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index f7744d52ae4..e84ea7d1f52 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -61,9 +61,12 @@ import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.Composite; 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.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.BrowserInfo; import com.vaadin.client.DeferredWorker; @@ -74,6 +77,7 @@ import com.vaadin.client.renderers.Renderer; import com.vaadin.client.renderers.WidgetRenderer; import com.vaadin.client.ui.SubPartAware; +import com.vaadin.client.ui.VButton; import com.vaadin.client.ui.dd.DragAndDropHandler; import com.vaadin.client.ui.dd.DragAndDropHandler.DragAndDropCallback; import com.vaadin.client.widget.escalator.Cell; @@ -2784,6 +2788,92 @@ public boolean isScheduled() { } } + /** + * Sidebar displaying toggles for hidable columns and additional custom + * widgets. + * + * @since + */ + public static class Sidebar extends Composite { + + private final ClickHandler openCloseButtonHandler = new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + if (!open) { + open(); + } else { + close(); + } + } + }; + + private final VerticalPanel rootContainer; + + private final VButton openCloseButton; + + private boolean open; + + public Sidebar() { + rootContainer = new VerticalPanel(); + initWidget(rootContainer); + + openCloseButton = new VButton(); + openCloseButton.addClickHandler(openCloseButtonHandler); + + rootContainer.add(openCloseButton); + rootContainer + .setCellHorizontalAlignment( + openCloseButton, + HorizontalAlignmentConstant + .endOf(com.google.gwt.i18n.client.HasDirection.Direction.LTR)); + } + + /** + * Opens the sidebar if not yet opened. + * + * @since + */ + public void open() { + if (!open) { + addStyleName("opened"); + open = true; + } + } + + /** + * Closes the sidebar if not yet closed. + * + * @since + */ + public void close() { + if (open) { + removeStyleName("opened"); + open = false; + } + } + + /** + * Returns whether the sidebar is open or not. + *
+ * Note: The sidebar can be in "open state" but not actually
+ * visible inside grid. See {@link #isVisibleInGrid()}.
+ *
+ * @since
+ * @return true
if open, false
if not
+ */
+ public boolean isOpen() {
+ return open;
+ }
+
+ @Override
+ public void setStylePrimaryName(String styleName) {
+ super.setStylePrimaryName(styleName);
+ openCloseButton.setStylePrimaryName(styleName + "-button");
+ }
+
+ }
+
/**
* Escalator used internally by grid to render the rows
*/
@@ -2793,6 +2883,8 @@ public boolean isScheduled() {
private final Footer footer = GWT.create(Footer.class);
+ private final Sidebar sidebar = GWT.create(Sidebar.class);
+
/**
* List of columns in the grid. Order defines the visible order.
*/
@@ -3385,7 +3477,7 @@ public void render(RendererCellReference cell, Object data) {
private boolean hidden = false;
- private boolean hideable = false;
+ private boolean hidable = false;
private String headerCaption = "";
@@ -3699,13 +3791,13 @@ public boolean isHidden() {
* programmatically using {@link #setHidden(boolean)}.
*
* @since
- * @param hideable
+ * @param hidable
* true
if the user can hide this column,
* false
if not
*/
- public void setHideable(boolean hideable) {
- this.hideable = hideable;
- // TODO update whether sidebar/popup can be opened
+ public void setHidable(boolean hidable) {
+ this.hidable = hidable;
+ grid.updateSideBarVisibility();
}
/**
@@ -3719,8 +3811,8 @@ public void setHideable(boolean hideable) {
* @return true
if the user can hide the column,
* false
if not
*/
- public boolean isHideable() {
- return hideable;
+ public boolean isHidable() {
+ return hidable;
}
@Override
@@ -4444,6 +4536,7 @@ public void setStylePrimaryName(String style) {
super.setStylePrimaryName(style);
escalator.setStylePrimaryName(style);
editor.setStylePrimaryName(style);
+ sidebar.setStylePrimaryName(style + "-sidebar");
String rowStyle = getStylePrimaryName() + "-row";
rowHasDataStyleName = rowStyle + "-has-data";
@@ -6945,4 +7038,52 @@ public void resetSizesFromDom() {
public void recalculateColumnWidths() {
autoColumnWidthsRecalculator.schedule();
}
+
+ /**
+ * Setter for displaying the grid's {@link Sidebar}. The sidebar is visible
+ * automatically when there are {@link Column#setHidable(boolean) hidable
+ * columns}.
+ *
+ * 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
+ * true
for showing the sidebar, false
+ * 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.
+ *
+ * @since
+ * @return
+ */
+ public Sidebar getSidebar() {
+ return sidebar;
+ }
+
+ private void updateSideBarVisibility() {
+ boolean visible = false;
+ for (Column, T> c : getColumns()) {
+ if (c.isHidable()) {
+ visible = true;
+ break;
+ }
+ }
+ setSidebarVisible(visible);
+ }
+
}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java
index 6d38c25fb61..ba4468da2c0 100644
--- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java
+++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java
@@ -16,7 +16,12 @@
package com.vaadin.tests.components.grid.basicfeatures;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
@@ -127,6 +132,85 @@ public void testColumnHiding_onVisibilityChange_triggersClientSideEvent() {
assertEquals(false, hidden);
}
+ @Test
+ public void testColumnHidability_onTriggerColumnHidability_showsSidebarButton() {
+ WebElement sidebar = getSidebar();
+ assertNull(sidebar);
+
+ toggleHidableColumn(0);
+
+ sidebar = getSidebar();
+ assertNotNull(sidebar);
+ }
+
+ @Test
+ public void testColumnHidability_triggeringColumnHidabilityWithSeveralColumns_showsAndHidesSiderbarButton() {
+ verifySidebarNotVisible();
+
+ toggleHidableColumn(3);
+ toggleHidableColumn(4);
+
+ verifySidebarVisible();
+
+ toggleHidableColumn(3);
+
+ verifySidebarVisible();
+
+ toggleHidableColumn(4);
+
+ verifySidebarNotVisible();
+ }
+
+ @Test
+ public void testColumnHidability_clickingSidebarButton_opensClosesSidebar() {
+ toggleHidableColumn(0);
+ verifySidebarClosed();
+
+ getSidebarOpenButton().click();
+
+ verifySidebarOpened();
+
+ getSidebarOpenButton().click();
+
+ verifySidebarClosed();
+ }
+
+ private void verifySidebarOpened() {
+ WebElement sidebar = getSidebar();
+ assertTrue(sidebar.getAttribute("class").contains("opened"));
+ }
+
+ private void verifySidebarClosed() {
+ WebElement sidebar = getSidebar();
+ assertFalse(sidebar.getAttribute("class").contains("opened"));
+ }
+
+ private void verifySidebarNotVisible() {
+ WebElement sidebar = getSidebar();
+ assertNull(sidebar);
+ }
+
+ private void verifySidebarVisible() {
+ WebElement sidebar = getSidebar();
+ assertNotNull(sidebar);
+ }
+
+ private WebElement getSidebar() {
+ List