Browse Source

Changed grid sidebar to overlay (#18698)

Previously grid sidebar could be partially hidden by
"overflow: hidden" of an ancestor component.
Now it's in an overlay and the hierarchy doesn't affect it.
Grid tests were also updated for new DOM structure.

Change-Id: Ic5fb125d9c097be0f0141c121dfe74d30e650dd0
tags/7.6.0.beta2
mtzukanov 8 years ago
parent
commit
baa8da38ad

+ 4
- 0
WebContent/VAADIN/themes/base/grid/grid.scss View File

@@ -100,6 +100,10 @@ $v-grid-details-border-bottom-stripe: 1px solid darken($v-grid-row-background-co
padding: 0;
z-index: 5;

&.#{$primaryStyleName}-sidebar-popup {
right: auto;
}

.#{$primaryStyleName}-sidebar-button {
background: transparent;
border: none;

+ 42
- 34
client/src/com/vaadin/client/widgets/Grid.java View File

@@ -54,6 +54,8 @@ import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyEvent;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
@@ -71,6 +73,7 @@ import com.google.gwt.user.client.ui.HasEnabled;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
@@ -85,6 +88,7 @@ import com.vaadin.client.renderers.Renderer;
import com.vaadin.client.renderers.WidgetRenderer;
import com.vaadin.client.ui.FocusUtil;
import com.vaadin.client.ui.SubPartAware;
import com.vaadin.client.ui.VOverlay;
import com.vaadin.client.ui.dd.DragAndDropHandler;
import com.vaadin.client.ui.dd.DragAndDropHandler.DragAndDropCallback;
import com.vaadin.client.ui.dd.DragHandle;
@@ -3579,25 +3583,7 @@ public class Grid<T> extends ResizeComposite implements

private final Grid<?> grid;

private NativePreviewHandler clickOutsideToCloseHandler = new NativePreviewHandler() {

@Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getTypeInt() != Event.ONMOUSEDOWN) {
return;
}

// Click outside the panel
EventTarget clickTarget = event.getNativeEvent()
.getEventTarget();
if (!rootContainer.getElement().isOrHasChild(
Element.as(clickTarget))) {
close();
}
}
};

private HandlerRegistration clickOutsideToCloseHandlerRegistration;
private VOverlay overlay;

private Sidebar(Grid<?> grid) {
this.grid = grid;
@@ -3624,6 +3610,8 @@ public class Grid<T> extends ResizeComposite implements
}
};

createOverlay();

menuBar = new MenuBar(true) {

@Override
@@ -3683,6 +3671,25 @@ public class Grid<T> extends ResizeComposite implements
menuBar.addDomHandler(keyDownHandler, KeyDownEvent.getType());
}

/**
* Creates and initializes the overlay.
*/
private void createOverlay() {
overlay = GWT.create(VOverlay.class);
overlay.setAutoHideEnabled(true);
overlay.setOwner(grid);
overlay.addStyleDependentName("popup");
overlay.add(content);
overlay.addAutoHidePartner(rootContainer.getElement());
overlay.addCloseHandler(new CloseHandler<PopupPanel>() {
@Override
public void onClose(CloseEvent<PopupPanel> event) {
removeStyleName("open");
addStyleName("closed");
}
});
}

/**
* Opens the sidebar if not yet opened. Opening the sidebar has no
* effect if it is empty.
@@ -3691,9 +3698,7 @@ public class Grid<T> extends ResizeComposite implements
if (!isOpen() && isInDOM()) {
addStyleName("open");
removeStyleName("closed");
rootContainer.add(content);
clickOutsideToCloseHandlerRegistration = Event
.addNativePreviewHandler(clickOutsideToCloseHandler);
overlay.showRelativeTo(rootContainer);
}
}

@@ -3701,17 +3706,7 @@ public class Grid<T> extends ResizeComposite implements
* Closes the sidebar if not yet closed.
*/
public void close() {
if (isOpen()) {
removeStyleName("open");
addStyleName("closed");
content.removeFromParent();
// adjust open button to header height when closed
setHeightToHeaderCellHeight();
if (clickOutsideToCloseHandlerRegistration != null) {
clickOutsideToCloseHandlerRegistration.removeHandler();
clickOutsideToCloseHandlerRegistration = null;
}
}
overlay.hide();
}

/**
@@ -3720,12 +3715,13 @@ public class Grid<T> extends ResizeComposite implements
* @return <code>true</code> if open, <code>false</code> if not
*/
public boolean isOpen() {
return content != null && content.getParent() == rootContainer;
return overlay != null && overlay.isShowing();
}

@Override
public void setStylePrimaryName(String styleName) {
super.setStylePrimaryName(styleName);
overlay.setStylePrimaryName(styleName);
content.setStylePrimaryName(styleName + "-content");
openCloseButton.setStylePrimaryName(styleName + "-button");
if (isOpen()) {
@@ -3737,6 +3733,18 @@ public class Grid<T> extends ResizeComposite implements
}
}

@Override
public void addStyleName(String style) {
super.addStyleName(style);
overlay.addStyleName(style);
}

@Override
public void removeStyleName(String style) {
super.removeStyleName(style);
overlay.removeStyleName(style);
}

private void setHeightToHeaderCellHeight() {
RowContainer header = grid.escalator.getHeader();
if (header.getRowCount() == 0

+ 60
- 0
uitest/src/com/vaadin/tests/components/grid/GridInGridLayout.java View File

@@ -0,0 +1,60 @@
/*
* 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.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.Grid;
import com.vaadin.ui.VerticalLayout;

public class GridInGridLayout extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
final CssLayout cssLayout = new CssLayout();
cssLayout.setWidth("100%");
layout.setHeight("320px");
layout.setMargin(true);
addComponent(cssLayout);
cssLayout.addComponent(layout);

final Grid grid = new Grid();
grid.setSizeFull();
for (int i = 0; i < 20; i++) {
Grid.Column column = grid.addColumn("" + i);
column.setHidable(true);
column.setEditable(true);
}
grid.setEditorEnabled(true);
grid.setColumnReorderingAllowed(true);
for (int i = 0; i < 300; i++) {
grid.addRow("Foo", "Bar", "far", "bar", "bar", "Foo", "Bar", "Bar",
"bar", "bar", "Foo", "Bar", "Bar", "bar", "bar", "Foo",
"Bar", "Bar", "bar", "bar");

}
layout.addComponent(grid);
grid.setHeight("300px");
grid.setWidth("400px");
}

@Override
protected Integer getTicketNumber() {
return 18698;
}
}

+ 4
- 1
uitest/src/com/vaadin/tests/components/grid/GridInitiallyHiddenColumnsTest.java View File

@@ -50,6 +50,8 @@ public class GridInitiallyHiddenColumnsTest extends SingleBrowserTest {

}

// TODO: as to the getX methods reuse ones from GridBasicFeaturesTest?

protected WebElement getSidebarOpenButton(GridElement grid) {
List<WebElement> elements = grid.findElements(By
.className("v-grid-sidebar-button"));
@@ -73,7 +75,8 @@ public class GridInitiallyHiddenColumnsTest extends SingleBrowserTest {
}

protected WebElement getSidebar(GridElement grid) {
List<WebElement> elements = findElements(By.className("v-grid-sidebar"));
List<WebElement> elements = findElements(By
.className("v-grid-sidebar-popup"));
return elements.isEmpty() ? null : elements.get(0);
}


+ 14
- 3
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java View File

@@ -217,8 +217,19 @@ public abstract class GridBasicFeaturesTest extends MultiBrowserTest {
.contains("focused"));
}

protected WebElement getSidebar() {
List<WebElement> elements = findElements(By.className("v-grid-sidebar"));
protected WebElement getSidebarPopup() {
List<WebElement> elements = findElements(By
.className("v-grid-sidebar-popup"));
if (elements.isEmpty()) {
getSidebarOpenButton().click();
elements = findElements(By.className("v-grid-sidebar-popup"));
}
return elements.isEmpty() ? null : elements.get(0);
}

protected WebElement getSidebarPopupIfPresent() {
List<WebElement> elements = findElements(By
.className("v-grid-sidebar-popup"));
return elements.isEmpty() ? null : elements.get(0);
}

@@ -233,7 +244,7 @@ public abstract class GridBasicFeaturesTest extends MultiBrowserTest {
* index, or null if not found.
*/
protected WebElement getColumnHidingToggle(int columnIndex) {
WebElement sidebar = getSidebar();
WebElement sidebar = getSidebarPopup();
List<WebElement> elements = sidebar.findElements(By
.className("column-hiding-toggle"));
for (WebElement e : elements) {

+ 10
- 23
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java View File

@@ -188,12 +188,12 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {

@Test
public void testColumnHidability_onTriggerColumnHidability_showsSidebarButton() {
WebElement sidebar = getSidebar();
WebElement sidebar = getSidebarOpenButton();
assertNull(sidebar);

toggleHidableColumnAPI(0);

sidebar = getSidebar();
sidebar = getSidebarOpenButton();
assertNotNull(sidebar);
}

@@ -998,7 +998,7 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
}

private void verifyColumnHidingTogglesOrder(int... indices) {
WebElement sidebar = getSidebar();
WebElement sidebar = getSidebarPopup();
List<WebElement> elements = sidebar.findElements(By
.className("column-hiding-toggle"));
for (int i = 0; i < indices.length; i++) {
@@ -1015,45 +1015,32 @@ public class GridColumnHidingTest extends GridBasicClientFeaturesTest {
}

private void verifySidebarOpened() {
WebElement sidebar = getSidebar();
assertTrue(sidebar.getAttribute("class").contains("open"));
WebElement sidebar = getSidebarPopupIfPresent();
assertNotNull(sidebar);
}

private void verifySidebarClosed() {
WebElement sidebar = getSidebar();
assertFalse(sidebar.getAttribute("class").contains("open"));
WebElement sidebar = getSidebarPopupIfPresent();
assertNull(sidebar);
}

private void verifySidebarNotVisible() {
WebElement sidebar = getSidebar();
WebElement sidebar = getSidebarOpenButton();
assertNull(sidebar);
}

private void verifySidebarVisible() {
WebElement sidebar = getSidebar();
WebElement sidebar = getSidebarOpenButton();
assertNotNull(sidebar);
}

@Override
protected WebElement getSidebar() {
List<WebElement> elements = findElements(By.className("v-grid-sidebar"));
return elements.isEmpty() ? null : elements.get(0);
}

@Override
protected WebElement getSidebarOpenButton() {
List<WebElement> elements = findElements(By
.className("v-grid-sidebar-button"));
return elements.isEmpty() ? null : elements.get(0);
}

/**
* Returns the toggle inside the sidebar for hiding the column at the given
* index, or null if not found.
*/
@Override
protected WebElement getColumnHidingToggle(int columnIndex) {
WebElement sidebar = getSidebar();
WebElement sidebar = getSidebarPopup();
List<WebElement> elements = sidebar.findElements(By
.className("column-hiding-toggle"));
for (WebElement e : elements) {

+ 9
- 14
uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridSidebarContentTest.java View File

@@ -30,24 +30,23 @@ public class GridSidebarContentTest extends GridBasicClientFeaturesTest {
@Test
public void testSidebarWithHidableColumn() {
openTestURL();
CustomGridElement gridElement = getGridElement();

Assert.assertEquals("Sidebar should not be initially present", 0,
countBySelector(".v-grid-sidebar"));
countBySelector(".v-grid-sidebar-button"));

selectMenuPath("Component", "Columns", "Column 0", "Hidable");

gridElement.findElement(By.className("v-grid-sidebar-button")).click();
getSidebarOpenButton().click();

WebElement toggle = gridElement.findElement(By
.className("column-hiding-toggle"));
WebElement toggle = getSidebarPopup().findElement(
By.className("column-hiding-toggle"));

Assert.assertEquals("Column 0 should be togglable", "Header (0,0)",
toggle.getText());

selectMenuPath("Component", "Columns", "Column 0", "Hidable");
Assert.assertEquals("Sidebar should disappear without toggable column",
0, countBySelector(".v-grid-sidebar"));
0, countBySelector(".v-grid-sidebar-button"));

}

@@ -60,8 +59,8 @@ public class GridSidebarContentTest extends GridBasicClientFeaturesTest {

gridElement.findElement(By.className("v-grid-sidebar-button")).click();

WebElement sidebarItem = gridElement.findElement(By
.cssSelector(".v-grid-sidebar-content .gwt-MenuItem"));
WebElement sidebarItem = getSidebarPopup().findElement(
By.cssSelector(".v-grid-sidebar-content .gwt-MenuItem"));

sidebarItem.click();

@@ -84,7 +83,6 @@ public class GridSidebarContentTest extends GridBasicClientFeaturesTest {
@Test
public void testBasicSidebarOrder() {
openTestURL();
CustomGridElement gridElement = getGridElement();

// First add custom content
selectMenuPath("Component", "Sidebar", "Add separator to end");
@@ -101,7 +99,6 @@ public class GridSidebarContentTest extends GridBasicClientFeaturesTest {
@Test
public void testSidebarOrderAbuse() {
openTestURL();
CustomGridElement gridElement = getGridElement();

selectMenuPath("Component", "Columns", "Column 0", "Hidable");
selectMenuPath("Component", "Columns", "Column 1", "Hidable");
@@ -125,7 +122,7 @@ public class GridSidebarContentTest extends GridBasicClientFeaturesTest {
}

private void assertSidebarMenuItems(String... items) {
List<WebElement> menuItems = getGridElement().findElements(
List<WebElement> menuItems = getSidebarPopup().findElements(
By.cssSelector(".v-grid-sidebar-content td"));

Assert.assertEquals("Expected " + items.length + " menu items",
@@ -145,8 +142,6 @@ public class GridSidebarContentTest extends GridBasicClientFeaturesTest {
}

private int countBySelector(String cssSelector) {
return getGridElement().findElements(By.cssSelector(cssSelector))
.size();
return findElements(By.cssSelector(cssSelector)).size();
}

}

Loading…
Cancel
Save