*/
package com.vaadin.client.ui.grid;
+import java.util.ArrayList;
+import java.util.List;
+
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.grid.Escalator.AbstractRowContainer;
import com.vaadin.client.ui.grid.ScrollbarBundle.Direction;
import com.vaadin.shared.ui.grid.ScrollDestination;
INACTIVE, ACTIVATING, ACTIVE, COMMITTING
}
+ private Grid<T> grid;
+
+ private EditorRowHandler<T> handler;
+
private DivElement editorOverlay = DivElement.as(DOM.createDiv());
- private Grid<T> grid;
+ private List<Widget> editorWidgets = new ArrayList<Widget>();
private boolean enabled = false;
private State state = State.INACTIVE;
state = State.INACTIVE;
}
+ /**
+ * Returns the handler responsible for binding data and editor widgets to
+ * this editor row.
+ *
+ * @return the editor row handler or null if not set
+ */
+ public EditorRowHandler<T> getHandler() {
+ return handler;
+ }
+
+ /**
+ * Sets the handler responsible for binding data and editor widgets to this
+ * editor row.
+ *
+ * @param rowHandler
+ * the new editor row handler
+ *
+ * @throws IllegalStateException
+ * if this editor row is currently in edit mode
+ */
+ public void setHandler(EditorRowHandler<T> rowHandler) {
+ if (state != State.INACTIVE) {
+ throw new IllegalStateException(
+ "Cannot set EditorRowHandler: EditorRow is currently in edit mode");
+ }
+ this.handler = rowHandler;
+ }
+
public boolean isEnabled() {
return enabled;
}
*
* @throws IllegalStateException
* if in edit mode and trying to disable
+ * @throws IllegalStateException
+ * if the editor row handler is not set
*/
public void setEnabled(boolean enabled) {
if (enabled == false && state != State.INACTIVE) {
throw new IllegalStateException(
"Cannot disable: EditorRow is in edit mode");
+ } else if (enabled == true && getHandler() == null) {
+ throw new IllegalStateException(
+ "Cannot enable: EditorRowHandler not set");
}
this.enabled = enabled;
}
setBounds(editorOverlay, tr.getOffsetLeft(), rowTop + bodyTop
- wrapperTop, tr.getOffsetWidth(), tr.getOffsetHeight());
+ tableWrapper.appendChild(editorOverlay);
+
for (int i = 0; i < tr.getCells().getLength(); i++) {
Element cell = createCell(tr.getCells().getItem(i));
+
editorOverlay.appendChild(cell);
- }
- tableWrapper.appendChild(editorOverlay);
+ Widget editor = getHandler().getWidget(
+ grid.getColumnFromVisibleIndex(i));
+ if (editor != null) {
+ editorWidgets.add(editor);
+ cell.appendChild(editor.getElement());
+ Grid.setParent(editor, grid);
+ }
+ }
}
protected void hideOverlay() {
+ for (Widget w : editorWidgets) {
+ Grid.setParent(w, null);
+ }
+ editorWidgets.clear();
+
+ editorOverlay.removeAllChildren();
editorOverlay.removeFromParent();
}
--- /dev/null
+/*
+ * 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.client.ui.grid;
+
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * An interface for binding widgets and data to the editor row.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface EditorRowHandler<T> {
+
+ /**
+ * Returns the widget instance that is used to edit the values in the given
+ * column. A null return value means the column is not editable.
+ *
+ * @param column
+ * the column whose values should be edited
+ * @return the editor widget for the column or null if the column is not
+ * editable
+ */
+ public Widget getWidget(GridColumn<?, T> column);
+}
}
}
- private int findVisibleColumnIndex(GridColumn<?, T> column) {
+ protected int findVisibleColumnIndex(GridColumn<?, T> column) {
int idx = 0;
for (GridColumn<?, T> c : columns) {
if (c == column) {
return -1;
}
- private GridColumn<?, T> getColumnFromVisibleIndex(int index) {
+ protected GridColumn<?, T> getColumnFromVisibleIndex(int index) {
int idx = -1;
for (GridColumn<?, T> c : columns) {
if (c.isVisible()) {
* @param parent
* The parent to set
*/
- private static native final void setParent(Widget widget, Widget parent)
+ static native final void setParent(Widget widget, Widget parent)
/*-{
widget.@com.google.gwt.user.client.ui.Widget::setParent(Lcom/google/gwt/user/client/ui/Widget;)(parent);
}-*/;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.data.DataSource.RowHandle;
import com.vaadin.client.data.RpcDataSourceConnector.RpcDataSource;
+import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.AbstractHasComponentsConnector;
import com.vaadin.client.ui.grid.GridHeader.HeaderRow;
import com.vaadin.client.ui.grid.GridStaticSection.StaticCell;
private AbstractRendererConnector<Object> rendererConnector;
+ private AbstractFieldConnector editorConnector;
+
public CustomGridColumn(String id,
AbstractRendererConnector<Object> rendererConnector) {
super(rendererConnector.getRenderer());
return rendererConnector;
}
+ private AbstractFieldConnector getEditorConnector() {
+ return editorConnector;
+ }
+
+ private void setEditorConnector(AbstractFieldConnector editorConnector) {
+ this.editorConnector = editorConnector;
+ }
+
private int resolveCurrentIndexFromState() {
List<GridColumnState> columns = getState().columns;
int numColumns = columns.size();
}
}
+ private class CustomEditorRowHandler implements
+ EditorRowHandler<JSONObject> {
+
+ @Override
+ public Widget getWidget(GridColumn<?, JSONObject> column) {
+ assert column != null;
+ AbstractFieldConnector c = ((CustomGridColumn) column)
+ .getEditorConnector();
+ return c != null ? c.getWidget() : null;
+ }
+ }
+
/**
* Maps a generated column id to a grid column instance
*/
}
}
});
+
+ getWidget().getEditorRow().setHandler(new CustomEditorRowHandler());
}
@Override
getWidgetColumnIndex(columnIndex));
GridColumnState columnState = getState().columns.get(columnIndex);
- updateColumnFromState(column, columnState);
assert column instanceof CustomGridColumn : "column at index "
+ columnIndex + " is not a "
+ CustomGridColumn.class.getSimpleName() + ", but a "
+ column.getClass().getSimpleName();
+ updateColumnFromState((CustomGridColumn) column, columnState);
+
if (columnState.rendererConnector != ((CustomGridColumn) column)
.getRendererConnector()) {
throw new UnsupportedOperationException(
* @param state
* The state to get the data from
*/
- private static void updateColumnFromState(GridColumn<?, JSONObject> column,
+ private static void updateColumnFromState(CustomGridColumn column,
GridColumnState state) {
column.setVisible(state.visible);
column.setWidth(state.width);
column.setSortable(state.sortable);
+ column.setEditorConnector((AbstractFieldConnector) state.editorConnector);
}
/**
*/
public int width = 100;
+ /**
+ * The connector for the renderer used to render the cells in this column.
+ */
public Connector rendererConnector;
+ /**
+ * The connector for the field used to edit cells in this column when the
+ * editor row is active.
+ */
+ public Connector editorConnector;
+
/**
* Are sorting indicators shown for a column. Default is false.
*/
*/
package com.vaadin.tests.components.grid.basicfeatures.client;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import java.util.List;
+
import org.junit.Before;
import org.junit.Test;
+import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest;
+import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures;
public class GridEditorRowClientTest extends GridBasicClientFeaturesTest {
new Actions(getDriver()).sendKeys(Keys.ENTER).perform();
assertNull(getEditorRow());
}
+
+ @Test
+ public void testWidgetBinding() throws Exception {
+ selectMenuPath("Component", "State", "Editor row", "Edit row 100");
+ WebElement editorRow = getEditorRow();
+
+ List<WebElement> widgets = editorRow.findElements(By
+ .className("gwt-TextBox"));
+
+ assertEquals(GridBasicFeatures.COLUMNS, widgets.size());
+
+ for (int i = 0; i < GridBasicFeatures.COLUMNS; ++i) {
+ assertEquals("Column " + i, widgets.get(i).getAttribute("value"));
+ }
+ }
}
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.VLabel;
import com.vaadin.client.ui.grid.Cell;
+import com.vaadin.client.ui.grid.EditorRowHandler;
import com.vaadin.client.ui.grid.FlyweightCell;
import com.vaadin.client.ui.grid.Grid;
import com.vaadin.client.ui.grid.Grid.AbstractGridKeyEvent;
grid.getElement().setId("testComponent");
grid.setDataSource(ds);
grid.setSelectionMode(SelectionMode.NONE);
+ grid.getEditorRow().setHandler(new EditorRowHandler<List<Data>>() {
+ @Override
+ public Widget getWidget(GridColumn<?, List<Data>> column) {
+ TextBox tb = new TextBox();
+ tb.setText("Column " + grid.getColumns().indexOf(column));
+ return tb;
+ }
+ });
sorter = new ListSorter<List<Data>>(grid);