aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebContent/VAADIN/themes/base/grid/grid.scss7
-rw-r--r--client/src/com/vaadin/client/ui/grid/EditorRow.java97
-rw-r--r--client/src/com/vaadin/client/ui/grid/EditorRowHandler.java24
-rw-r--r--client/src/com/vaadin/client/ui/grid/GridConnector.java12
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorRowClientTest.java34
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java52
6 files changed, 217 insertions, 9 deletions
diff --git a/WebContent/VAADIN/themes/base/grid/grid.scss b/WebContent/VAADIN/themes/base/grid/grid.scss
index de38b8c1ff..69b293e26e 100644
--- a/WebContent/VAADIN/themes/base/grid/grid.scss
+++ b/WebContent/VAADIN/themes/base/grid/grid.scss
@@ -39,12 +39,19 @@
.#{$primaryStyleName}-editor-row {
position: absolute;
+ overflow-y: visible;
background: #EEE;
box-shadow: 0 0 5px;
& > div {
position: absolute;
+ box-sizing: border-box;
border: 1px solid #CCC;
}
+
+ .v-editor-row-save,
+ .v-editor-row-cancel {
+ position: absolute;
+ }
}
}
diff --git a/client/src/com/vaadin/client/ui/grid/EditorRow.java b/client/src/com/vaadin/client/ui/grid/EditorRow.java
index ddef7c3dc7..a748af172f 100644
--- a/client/src/com/vaadin/client/ui/grid/EditorRow.java
+++ b/client/src/com/vaadin/client/ui/grid/EditorRow.java
@@ -24,9 +24,12 @@ import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableRowElement;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.grid.EditorRowHandler.EditorRowRequest;
import com.vaadin.client.ui.grid.EditorRowHandler.EditorRowRequest.RequestCallback;
@@ -79,8 +82,9 @@ public class EditorRow<T> {
* the index of the row to be edited
*
* @throws IllegalStateException
- * if this editor row is not enabled or if it is already in edit
- * mode
+ * if this editor row is not enabled
+ * @throws IllegalStateException
+ * if this editor row is already in edit mode
*/
public void editRow(int rowIndex) {
if (!enabled) {
@@ -104,9 +108,12 @@ public class EditorRow<T> {
}
/**
- * Cancels the currently active edit and hides the editor.
+ * Cancels the currently active edit and hides the editor. Any changes that
+ * are not {@link #commit() committed} are lost.
*
* @throws IllegalStateException
+ * if this editor row is not enabled
+ * @throws IllegalStateException
* if this editor row is not in edit mode
*/
public void cancel() {
@@ -125,6 +132,56 @@ public class EditorRow<T> {
}
/**
+ * Commits any unsaved changes to the data source.
+ *
+ * @throws IllegalStateException
+ * if this editor row is not enabled
+ * @throws IllegalStateException
+ * if this editor row is not in edit mode
+ */
+ public void commit() {
+ if (!enabled) {
+ throw new IllegalStateException(
+ "Cannot commit: EditorRow is not enabled");
+ }
+ if (state != State.ACTIVE) {
+ throw new IllegalStateException(
+ "Cannot commit: EditorRow is not in edit mode");
+ }
+
+ state = State.COMMITTING;
+
+ handler.commit(new EditorRowRequest(rowIndex, new RequestCallback() {
+ @Override
+ public void onResponse(EditorRowRequest request) {
+ if (state == State.COMMITTING) {
+ state = State.ACTIVE;
+ }
+ }
+ }));
+ }
+
+ /**
+ * Reloads row values from the data source, discarding any unsaved changes.
+ *
+ * @throws IllegalStateException
+ * if this editor row is not enabled
+ * @throws IllegalStateException
+ * if this editor row is not in edit mode
+ */
+ public void discard() {
+ if (!enabled) {
+ throw new IllegalStateException(
+ "Cannot discard: EditorRow is not enabled");
+ }
+ if (state != State.ACTIVE) {
+ throw new IllegalStateException(
+ "Cannot discard: EditorRow is not in edit mode");
+ }
+ handler.discard(new EditorRowRequest(rowIndex, null));
+ }
+
+ /**
* Returns the handler responsible for binding data and editor widgets to
* this editor row.
*
@@ -263,10 +320,35 @@ public class EditorRow<T> {
Widget editor = getHandler().getWidget(column);
if (editor != null) {
editorWidgets.add(editor);
- cell.appendChild(editor.getElement());
- Grid.setParent(editor, grid);
+ attachWidget(editor, cell);
}
}
+
+ Button save = new Button();
+ save.setText("Save");
+ save.setStyleName("v-editor-row-save");
+ save.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ // TODO should have a mechanism for handling failed commits
+ commit();
+ cancel();
+ }
+ });
+ setBounds(save.getElement(), 0, tr.getOffsetHeight() + 5, 50, 25);
+ attachWidget(save, editorOverlay);
+
+ Button cancel = new Button();
+ cancel.setText("Cancel");
+ cancel.setStyleName("v-editor-row-cancel");
+ cancel.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ cancel();
+ }
+ });
+ setBounds(cancel.getElement(), 55, tr.getOffsetHeight() + 5, 50, 25);
+ attachWidget(cancel, editorOverlay);
}
protected void hideOverlay() {
@@ -305,6 +387,11 @@ public class EditorRow<T> {
return cell;
}
+ private void attachWidget(Widget w, Element parent) {
+ parent.appendChild(w.getElement());
+ Grid.setParent(w, grid);
+ }
+
private static void setBounds(Element e, int left, int top, int width,
int height) {
Style style = e.getStyle();
diff --git a/client/src/com/vaadin/client/ui/grid/EditorRowHandler.java b/client/src/com/vaadin/client/ui/grid/EditorRowHandler.java
index ba3d0b9cd2..d2d1e61efb 100644
--- a/client/src/com/vaadin/client/ui/grid/EditorRowHandler.java
+++ b/client/src/com/vaadin/client/ui/grid/EditorRowHandler.java
@@ -34,6 +34,8 @@ public interface EditorRowHandler<T> {
* A request class for handling asynchronous data binding. The request is
* callback-based to facilitate usage with remote or otherwise asynchronous
* data sources.
+ * <p>
+ * TODO Should have a mechanism for signaling a failed request to the caller
*/
public static class EditorRowRequest {
@@ -112,6 +114,28 @@ public interface EditorRowHandler<T> {
public void cancel(EditorRowRequest request);
/**
+ * Commits changes in the currently active edit to the data source. Called
+ * by the editor row when changes are saved.
+ *
+ * @param request
+ * the commit request
+ */
+ public void commit(EditorRowRequest request);
+
+ /**
+ * Discards any unsaved changes and reloads editor content from the data
+ * source.
+ * <p>
+ * Implementation note: This method may simply call
+ * {@link #bind(EditorRowRequest) bind} if no other processing needs to be
+ * done.
+ *
+ * @param request
+ * the discard request
+ */
+ public void discard(EditorRowRequest request);
+
+ /**
* Returns a widget instance that is used to edit the values in the given
* column. A null return value means the column is not editable.
*
diff --git a/client/src/com/vaadin/client/ui/grid/GridConnector.java b/client/src/com/vaadin/client/ui/grid/GridConnector.java
index 7c0a2da96d..050f312d7e 100644
--- a/client/src/com/vaadin/client/ui/grid/GridConnector.java
+++ b/client/src/com/vaadin/client/ui/grid/GridConnector.java
@@ -233,6 +233,18 @@ public class GridConnector extends AbstractHasComponentsConnector {
currentRequest.invokeCallback();
currentRequest = null;
}
+
+ @Override
+ public void commit(EditorRowRequest request) {
+ // TODO no-op until Vaadin comms implemented
+ request.invokeCallback();
+ }
+
+ @Override
+ public void discard(EditorRowRequest request) {
+ // TODO no-op until Vaadin comms implemented
+ request.invokeCallback();
+ }
}
/**
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorRowClientTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorRowClientTest.java
index a37bf41072..4c64eac6e5 100644
--- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorRowClientTest.java
+++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorRowClientTest.java
@@ -89,7 +89,7 @@ public class GridEditorRowClientTest extends GridBasicClientFeaturesTest {
@Test
public void testWidgetBinding() throws Exception {
- selectMenuPath("Component", "State", "Editor row", "Edit row 100");
+ selectMenuPath("Component", "Editor row", "Edit row 100");
WebElement editorRow = getEditorRow();
List<WebElement> widgets = editorRow.findElements(By
@@ -119,4 +119,36 @@ public class GridEditorRowClientTest extends GridBasicClientFeaturesTest {
assertFalse("normal column cell shoul've had contents", selectorDivs
.get(1).getAttribute("innerHTML").isEmpty());
}
+
+ @Test
+ public void testCommit() {
+ selectMenuPath("Component", "Editor row", "Edit row 100");
+
+ List<WebElement> widgets = getEditorRow().findElements(
+ By.className("gwt-TextBox"));
+
+ widgets.get(0).sendKeys(" changed");
+
+ WebElement saveButton = getEditorRow().findElement(
+ By.className("v-editor-row-save"));
+
+ saveButton.click();
+
+ assertEquals("(100, 0) changed", getGridElement().getCell(100, 0)
+ .getText());
+ }
+
+ @Test
+ public void testDiscard() {
+ selectMenuPath("Component", "Editor row", "Edit row 100");
+
+ List<WebElement> widgets = getEditorRow().findElements(
+ By.className("gwt-TextBox"));
+
+ widgets.get(0).sendKeys(" changed");
+
+ selectMenuPath("Component", "Editor row", "Discard");
+
+ assertEquals("(100, 0)", getGridElement().getCell(100, 0).getText());
+ }
}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
index 5b69df1fb7..d5d276c7db 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Random;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
@@ -96,9 +97,8 @@ public class GridBasicClientFeaturesWidget extends
boolean hasSelectionColumn = !(grid.getSelectionModel() instanceof None);
for (int i = 0; i < rowData.size(); i++) {
- int gridColumnIndex = hasSelectionColumn ? i + 1 : i;
- GridColumn<?, List<Data>> col = grid.getColumn(gridColumnIndex);
- getWidget(col).setText(rowData.get(i).value.toString());
+ int columnIndex = hasSelectionColumn ? i + 1 : i;
+ getWidget(columnIndex).setText(rowData.get(i).value.toString());
}
request.invokeCallback();
@@ -111,6 +111,33 @@ public class GridBasicClientFeaturesWidget extends
}
@Override
+ public void commit(EditorRowRequest request) {
+ log.setText("Row " + request.getRowIndex() + " edit committed");
+ List<Data> rowData = ds.getRow(request.getRowIndex());
+
+ int i = 0;
+ for (; i < COLUMNS - MANUALLY_FORMATTED_COLUMNS; i++) {
+ rowData.get(i).value = getWidget(i).getText();
+ }
+
+ rowData.get(i).value = Integer.valueOf(getWidget(i++).getText());
+ rowData.get(i).value = new Date(getWidget(i++).getText());
+ rowData.get(i).value = getWidget(i++).getText();
+ rowData.get(i).value = Integer.valueOf(getWidget(i++).getText());
+ rowData.get(i).value = Integer.valueOf(getWidget(i++).getText());
+
+ // notify data source of changes
+ ds.asList().set(request.getRowIndex(), rowData);
+
+ request.invokeCallback();
+ }
+
+ @Override
+ public void discard(EditorRowRequest request) {
+ bind(request);
+ }
+
+ @Override
public TextBox getWidget(GridColumn<?, List<Data>> column) {
if (grid.getColumns().indexOf(column) == 0
&& !(grid.getSelectionModel() instanceof None)) {
@@ -120,10 +147,15 @@ public class GridBasicClientFeaturesWidget extends
TextBox w = widgets.get(column);
if (w == null) {
w = new TextBox();
+ w.getElement().getStyle().setMargin(0, Unit.PX);
widgets.put(column, w);
}
return w;
}
+
+ private TextBox getWidget(int i) {
+ return getWidget(grid.getColumn(i));
+ }
}
private static final int MANUALLY_FORMATTED_COLUMNS = 5;
@@ -704,6 +736,20 @@ public class GridBasicClientFeaturesWidget extends
}
}, "Component", "Editor row");
+ addMenuCommand("Commit", new ScheduledCommand() {
+ @Override
+ public void execute() {
+ grid.getEditorRow().commit();
+ }
+ }, "Component", "Editor row");
+
+ addMenuCommand("Discard", new ScheduledCommand() {
+ @Override
+ public void execute() {
+ grid.getEditorRow().discard();
+ }
+ }, "Component", "Editor row");
+
addMenuCommand("Cancel edit", new ScheduledCommand() {
@Override
public void execute() {