Change-Id: I21c5bb95feb3dbab1b543943adc0584aa8eec87btags/8.0.0.alpha2
@@ -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<JsonObject> 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(); | |||
} | |||
} |
@@ -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<T> extends AbstractSingleSelect<T> implements HasComponents { | |||
public void accept(ItemClick<T> event); | |||
} | |||
/** | |||
* ContextClickEvent for the Grid Component. | |||
* | |||
* @param <T> | |||
* the grid bean type | |||
*/ | |||
public static class GridContextClickEvent<T> 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<T> 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; <code>null</code> 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. | |||
* <p> | |||
* 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<T> getComponent() { | |||
return (Grid<T>) super.getComponent(); | |||
} | |||
} | |||
/** | |||
* A callback interface for generating style names for an item. | |||
* | |||
@@ -281,7 +366,12 @@ public class Grid<T> extends AbstractSingleSelect<T> 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<T>(Grid.this, details, section, | |||
rowIndex, item, getColumn(columnId))); | |||
} | |||
@Override |
@@ -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<Grid, GridContextClickEvent> { | |||
public class GridContextClick extends | |||
AbstractContextClickUI<Grid<Person>, GridContextClickEvent<Person>> { | |||
@Override | |||
protected Grid createTestComponent() { | |||
Grid grid = new Grid(PersonContainer.createWithTestData()); | |||
grid.setFooterVisible(true); | |||
grid.appendFooterRow(); | |||
protected Grid<Person> createTestComponent() { | |||
Grid<Person> 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<Person> 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; |
@@ -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<Person> | |||
} | |||
public static PersonContainer createWithTestData(int size) { | |||
PersonContainer c = null; | |||
PersonContainer c = new PersonContainer(); | |||
c.addAll(createTestData(size)); | |||
return c; | |||
} | |||
public static Collection<Person> createTestData() { | |||
return createTestData(100); | |||
} | |||
public static Collection<Person> createTestData(int size) { | |||
Random r = new Random(0); | |||
c = new PersonContainer(); | |||
ArrayList<Person> 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<Person> | |||
p.getAddress().setPostalCode(TestDataGenerator.getPostalCode(r)); | |||
p.getAddress() | |||
.setStreetAddress(TestDataGenerator.getStreetAddress(r)); | |||
c.addItem(p); | |||
testData.add(p); | |||
} | |||
return c; | |||
return testData; | |||
} | |||
} |
@@ -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)); | |||
} |