From 29cdc9873442b8051066810e866bcc2b3f010a59 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 12 Sep 2016 22:29:25 +0300 Subject: Add context event support to new Grid Change-Id: I21c5bb95feb3dbab1b543943adc0584aa8eec87b --- .../client/connectors/grid/GridConnector.java | 26 +++++- server/src/main/java/com/vaadin/ui/Grid.java | 92 +++++++++++++++++++++- .../tests/contextclick/GridContextClick.java | 75 +++++++++++------- .../com/vaadin/tests/util/PersonContainer.java | 20 +++-- .../tests/contextclick/GridContextClickTest.java | 17 ++-- 5 files changed, 188 insertions(+), 42 deletions(-) diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java index e2d2172166..58a5ea8262 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Optional; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.EventTarget; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.shared.HandlerRegistration; import com.vaadin.client.ComponentConnector; @@ -32,10 +33,12 @@ import com.vaadin.client.DeferredWorker; import com.vaadin.client.HasComponentsConnector; import com.vaadin.client.MouseEventDetailsBuilder; import com.vaadin.client.TooltipInfo; +import com.vaadin.client.WidgetUtil; import com.vaadin.client.connectors.AbstractListingConnector; import com.vaadin.client.data.DataSource; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.client.widget.grid.CellReference; +import com.vaadin.client.widget.grid.EventCellReference; import com.vaadin.client.widget.grid.events.BodyClickHandler; import com.vaadin.client.widget.grid.events.BodyDoubleClickHandler; import com.vaadin.client.widget.grid.events.GridClickEvent; @@ -46,12 +49,14 @@ import com.vaadin.client.widget.grid.sort.SortEvent; import com.vaadin.client.widget.grid.sort.SortOrder; import com.vaadin.client.widgets.Grid; import com.vaadin.client.widgets.Grid.Column; +import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.data.DataCommunicatorConstants; import com.vaadin.shared.data.selection.SelectionModel; import com.vaadin.shared.data.selection.SelectionServerRpc; import com.vaadin.shared.data.sort.SortDirection; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.grid.GridConstants; +import com.vaadin.shared.ui.grid.GridConstants.Section; import com.vaadin.shared.ui.grid.GridServerRpc; import com.vaadin.shared.ui.grid.GridState; @@ -269,7 +274,6 @@ public class GridConnector sortDirections.toArray(new SortDirection[0]), event.isUserOriginated()); } - /* HasComponentsConnector */ @Override @@ -350,4 +354,24 @@ public class GridConnector return null; } } + + @Override + protected void sendContextClickEvent(MouseEventDetails details, + EventTarget eventTarget) { + + EventCellReference eventCell = getWidget().getEventCell(); + + Section section = eventCell.getSection(); + String rowKey = null; + if (eventCell.isBody() && eventCell.getRow() != null) { + rowKey = getRowKey(eventCell.getRow()); + } + + String columnId = getColumnId(eventCell.getColumn()); + + getRpcProxy(GridServerRpc.class).contextClick(eventCell.getRowIndex(), + rowKey, columnId, section, details); + + WidgetUtil.clearTextSelection(); + } } diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index 705a9ca890..d776906afd 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -35,6 +35,7 @@ import java.util.function.Function; import java.util.stream.Stream; import com.vaadin.event.ConnectorEvent; +import com.vaadin.event.ContextClickEvent; import com.vaadin.event.EventListener; import com.vaadin.server.KeyMapper; import com.vaadin.server.data.SortOrder; @@ -157,6 +158,90 @@ public class Grid extends AbstractSingleSelect implements HasComponents { public void accept(ItemClick event); } + /** + * ContextClickEvent for the Grid Component. + * + * @param + * the grid bean type + */ + public static class GridContextClickEvent extends ContextClickEvent { + + private final T item; + private final int rowIndex; + private final Column column; + private final Section section; + + /** + * Creates a new context click event. + * + * @param source + * the grid where the context click occurred + * @param mouseEventDetails + * details about mouse position + * @param section + * the section of the grid which was clicked + * @param rowIndex + * the index of the row which was clicked + * @param item + * the item which was clicked + * @param column + * the column which was clicked + */ + public GridContextClickEvent(Grid source, + MouseEventDetails mouseEventDetails, Section section, + int rowIndex, T item, Column column) { + super(source, mouseEventDetails); + this.item = item; + this.section = section; + this.column = column; + this.rowIndex = rowIndex; + } + + /** + * Returns the item of context clicked row. + * + * @return item of clicked row; null if header or footer + */ + public T getItem() { + return item; + } + + /** + * Returns the clicked column. + * + * @return the clicked column + */ + public Column getColumn() { + return column; + } + + /** + * Return the clicked section of Grid. + * + * @return section of grid + */ + public Section getSection() { + return section; + } + + /** + * Returns the clicked row index. + *

+ * Header and Footer rows for index can be fetched with + * {@link Grid#getHeaderRow(int)} and {@link Grid#getFooterRow(int)}. + * + * @return row index in section + */ + public int getRowIndex() { + return rowIndex; + } + + @Override + public Grid getComponent() { + return (Grid) super.getComponent(); + } + } + /** * A callback interface for generating style names for an item. * @@ -281,7 +366,12 @@ public class Grid extends AbstractSingleSelect implements HasComponents { @Override public void contextClick(int rowIndex, String rowKey, String columnId, Section section, MouseEventDetails details) { - // TODO Auto-generated method stub + T item = null; + if (rowKey != null) { + item = getDataCommunicator().getKeyMapper().get(rowKey); + } + fireEvent(new GridContextClickEvent(Grid.this, details, section, + rowIndex, item, getColumn(columnId))); } @Override diff --git a/uitest/src/main/java/com/vaadin/tests/contextclick/GridContextClick.java b/uitest/src/main/java/com/vaadin/tests/contextclick/GridContextClick.java index 22c0331059..e5d33ab17a 100644 --- a/uitest/src/main/java/com/vaadin/tests/contextclick/GridContextClick.java +++ b/uitest/src/main/java/com/vaadin/tests/contextclick/GridContextClick.java @@ -15,27 +15,44 @@ */ package com.vaadin.tests.contextclick; +import java.util.Collections; + +import com.vaadin.shared.ui.grid.GridConstants.Section; +import com.vaadin.tests.util.Person; import com.vaadin.tests.util.PersonContainer; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.GridContextClickEvent; import com.vaadin.ui.HorizontalLayout; -import com.vaadin.v7.data.Item; -import com.vaadin.v7.shared.ui.grid.GridConstants.Section; -import com.vaadin.v7.ui.Grid; -import com.vaadin.v7.ui.Grid.GridContextClickEvent; -public class GridContextClick - extends AbstractContextClickUI { +public class GridContextClick extends + AbstractContextClickUI, GridContextClickEvent> { @Override - protected Grid createTestComponent() { - Grid grid = new Grid(PersonContainer.createWithTestData()); - grid.setFooterVisible(true); - grid.appendFooterRow(); + protected Grid createTestComponent() { + Grid grid = new Grid<>(); + grid.setItems(PersonContainer.createTestData()); + grid.addColumn("Address", + person -> String.valueOf(person.getAddress())); + grid.addColumn("Email", person -> String.valueOf(person.getEmail())); + grid.addColumn("First Name", + person -> String.valueOf(person.getFirstName())); + grid.addColumn("Last Name", + person -> String.valueOf(person.getLastName())); + grid.addColumn("Phone Number", + person -> String.valueOf(person.getPhoneNumber())); + grid.addColumn("Street Address", person -> String + .valueOf(person.getAddress().getStreetAddress())); + grid.addColumn("City", + person -> String.valueOf(person.getAddress().getCity())); + + // grid.setFooterVisible(true); + // grid.appendFooterRow(); - grid.setColumnOrder("address", "email", "firstName", "lastName", - "phoneNumber", "address.streetAddress", "address.postalCode", - "address.city"); + // grid.setColumnOrder("address", "email", "firstName", "lastName", + // "phoneNumber", "address.streetAddress", "address.postalCode", + // "address.city"); grid.setWidth("100%"); grid.setHeight("400px"); @@ -44,23 +61,27 @@ public class GridContextClick } @Override - protected void handleContextClickEvent(GridContextClickEvent event) { + protected void handleContextClickEvent( + GridContextClickEvent event) { String value = ""; - Object propertyId = event.getPropertyId(); - if (event.getItemId() != null) { - Item item = event.getComponent().getContainerDataSource() - .getItem(event.getItemId()); - value += item.getItemProperty("firstName").getValue(); - value += " " + item.getItemProperty("lastName").getValue(); + Person person = event.getItem(); + if (event.getItem() != null) { + value = person.getFirstName() + " " + person.getLastName(); } else if (event.getSection() == Section.HEADER) { - value = event.getComponent().getHeaderRow(event.getRowIndex()) - .getCell(propertyId).getText(); + value = event.getColumn().getCaption(); } else if (event.getSection() == Section.FOOTER) { - value = event.getComponent().getFooterRow(event.getRowIndex()) - .getCell(propertyId).getText(); + value = event.getColumn().getCaption(); + } + + if (event.getColumn() != null) { + log("ContextClickEvent value: " + value + ", column: " + + event.getColumn().getCaption() + ", section: " + + event.getSection()); + } else { + log("ContextClickEvent value: " + value + ", section: " + + event.getSection()); + } - log("ContextClickEvent value: " + value + ", propertyId: " + propertyId - + ", section: " + event.getSection()); } @Override @@ -71,7 +92,7 @@ public class GridContextClick @Override public void buttonClick(ClickEvent event) { - testComponent.getContainerDataSource().removeAllItems(); + testComponent.setItems(Collections.emptyList()); } })); return controls; diff --git a/uitest/src/main/java/com/vaadin/tests/util/PersonContainer.java b/uitest/src/main/java/com/vaadin/tests/util/PersonContainer.java index cb7c3c28a5..caedc9f299 100644 --- a/uitest/src/main/java/com/vaadin/tests/util/PersonContainer.java +++ b/uitest/src/main/java/com/vaadin/tests/util/PersonContainer.java @@ -1,6 +1,8 @@ package com.vaadin.tests.util; import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.Random; import com.vaadin.v7.data.util.BeanItemContainer; @@ -36,9 +38,18 @@ public class PersonContainer extends BeanItemContainer } public static PersonContainer createWithTestData(int size) { - PersonContainer c = null; + PersonContainer c = new PersonContainer(); + c.addAll(createTestData(size)); + return c; + } + + public static Collection createTestData() { + return createTestData(100); + } + + public static Collection createTestData(int size) { Random r = new Random(0); - c = new PersonContainer(); + ArrayList testData = new ArrayList<>(); for (int i = 0; i < size; i++) { Person p = new Person(); p.setFirstName(TestDataGenerator.getFirstName(r)); @@ -51,10 +62,9 @@ public class PersonContainer extends BeanItemContainer p.getAddress().setPostalCode(TestDataGenerator.getPostalCode(r)); p.getAddress() .setStreetAddress(TestDataGenerator.getStreetAddress(r)); - c.addItem(p); + testData.add(p); } - - return c; + return testData; } } diff --git a/uitest/src/test/java/com/vaadin/tests/contextclick/GridContextClickTest.java b/uitest/src/test/java/com/vaadin/tests/contextclick/GridContextClickTest.java index fa5d6d7e2b..e26060f3ae 100644 --- a/uitest/src/test/java/com/vaadin/tests/contextclick/GridContextClickTest.java +++ b/uitest/src/test/java/com/vaadin/tests/contextclick/GridContextClickTest.java @@ -17,6 +17,7 @@ package com.vaadin.tests.contextclick; import static org.junit.Assert.assertEquals; +import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.WebElement; @@ -32,13 +33,13 @@ public class GridContextClickTest extends AbstractContextClickTest { contextClick($(GridElement.class).first().getCell(0, 0)); assertEquals( - "1. ContextClickEvent value: Lisa Schneider, propertyId: address, section: BODY", + "1. ContextClickEvent value: Lisa Schneider, column: Address, section: BODY", getLogRow(0)); contextClick($(GridElement.class).first().getCell(0, 3)); assertEquals( - "2. ContextClickEvent value: Lisa Schneider, propertyId: lastName, section: BODY", + "2. ContextClickEvent value: Lisa Schneider, column: Last Name, section: BODY", getLogRow(0)); } @@ -49,30 +50,31 @@ public class GridContextClickTest extends AbstractContextClickTest { contextClick($(GridElement.class).first().getHeaderCell(0, 0)); assertEquals( - "1. ContextClickEvent value: Address, propertyId: address, section: HEADER", + "1. ContextClickEvent value: Address, column: Address, section: HEADER", getLogRow(0)); contextClick($(GridElement.class).first().getHeaderCell(0, 3)); assertEquals( - "2. ContextClickEvent value: Last Name, propertyId: lastName, section: HEADER", + "2. ContextClickEvent value: Last Name, column: Last Name, section: HEADER", getLogRow(0)); } @Test + @Ignore("Footer is not currently implemented in grid") public void testFooterContextClickWithTypedListener() { addOrRemoveTypedListener(); contextClick($(GridElement.class).first().getFooterCell(0, 0)); assertEquals( - "1. ContextClickEvent value: , propertyId: address, section: FOOTER", + "1. ContextClickEvent value: , column: Address, section: FOOTER", getLogRow(0)); contextClick($(GridElement.class).first().getFooterCell(0, 3)); assertEquals( - "2. ContextClickEvent value: , propertyId: lastName, section: FOOTER", + "2. ContextClickEvent value: , column: Last Name, section: FOOTER", getLogRow(0)); } @@ -84,8 +86,7 @@ public class GridContextClickTest extends AbstractContextClickTest { contextClick($(GridElement.class).first(), 100, 100); - assertEquals( - "1. ContextClickEvent value: , propertyId: null, section: BODY", + assertEquals("1. ContextClickEvent value: , section: BODY", getLogRow(0)); } -- cgit v1.2.3