column.setExpandRatio(state.expandRatio);
column.setSortable(state.sortable);
+ column.setEditable(state.editable);
column.setEditorConnector((AbstractFieldConnector) state.editorConnector);
}
/**
* Returns the editor widget associated with the given column. If the
- * editor is not active, returns null.
+ * editor is not active or the column is not
+ * {@link Grid.Column#isEditable() editable}, returns null.
*
* @param column
* the column
- * @return the widget if the editor is open, null otherwise
+ * @return the widget if the editor is open and the column is editable,
+ * null otherwise
*/
protected Widget getWidget(Column<?, T> column) {
return columnToWidget.get(column);
editorOverlay.appendChild(cell);
Column<?, T> column = grid.getColumn(i);
- if (column == grid.selectionColumn) {
- continue;
- }
-
- Widget editor = getHandler().getWidget(column);
- if (editor != null) {
- columnToWidget.put(column, editor);
- attachWidget(editor, cell);
+ if (column.isEditable()) {
+ Widget editor = getHandler().getWidget(column);
+ if (editor != null) {
+ columnToWidget.put(column, editor);
+ attachWidget(editor, cell);
+ }
}
}
}
public final class SelectionColumn extends Column<Boolean, T> {
+
private boolean initDone = false;
SelectionColumn(final Renderer<Boolean> selectColumnRenderer) {
setWidth(-1);
+ setEditable(false);
+
initDone = true;
}
public double getMinimumWidth() {
return -1;
}
+
+ @Override
+ public Column<Boolean, T> setEditable(boolean editable) {
+ if (initDone) {
+ throw new UnsupportedOperationException(
+ "can't set the selection column editable");
+ }
+ super.setEditable(editable);
+ return this;
+ }
+
}
/**
private boolean sortable = false;
+ private boolean editable = true;
+
private String headerCaption = "";
private double minimumWidthPx = GridConstants.DEFAULT_MIN_WIDTH;
return expandRatio;
}
+ /**
+ * Sets whether the values in this column should be editable by the user
+ * when the row editor is active. By default columns are editable.
+ *
+ * @param editable
+ * {@code true} to set this column editable, {@code false}
+ * otherwise
+ * @return this column
+ *
+ * @throws IllegalStateException
+ * if the editor is currently active
+ *
+ * @see Grid#editRow(int)
+ * @see Grid#isEditorActive()
+ */
+ public Column<C, T> setEditable(boolean editable) {
+ if (editable != this.editable && grid.isEditorActive()) {
+ throw new IllegalStateException(
+ "Cannot change column editable status while the editor is active");
+ }
+ this.editable = editable;
+ return this;
+ }
+
+ /**
+ * Returns whether the values in this column are editable by the user
+ * when the row editor is active.
+ *
+ * @return {@code true} if this column is editable, {@code false}
+ * otherwise
+ *
+ * @see #setEditable(boolean)
+ */
+ public boolean isEditable() {
+ return editable;
+ }
+
private void scheduleColumnWidthRecalculator() {
if (grid != null) {
grid.autoColumnWidthsRecalculator.schedule();
editor.editRow(rowIndex);
}
+ /**
+ * Returns whether the editor is currently open on some row.
+ *
+ * @return {@code true} if the editor is active, {@code false} otherwise.
+ */
+ public boolean isEditorActive() {
+ return editor.getState() != State.INACTIVE;
+ }
+
/**
* Saves any unsaved changes in the editor to the data source.
*
}
/**
- * Return the property id for the backing property of this Column
+ * Returns the property id for the backing property of this Column
*
* @return property id
*/
}
/**
- * Should sorting controls be available for the column
+ * Sets whether the column should be sortable by the user. The grid can
+ * be sorted by a sortable column by clicking or tapping the column's
+ * default header. Programmatic sorting using the Grid.sort methods is
+ * not affected by this setting.
*
* @param sortable
- * <code>true</code> if the sorting controls should be
- * visible.
+ * <code>true</code> if the user should be able to sort the
+ * column, false otherwise
* @return the column itself
*/
public Column setSortable(boolean sortable) {
}
/**
- * Are the sorting controls visible in the column header
+ * Returns whether the user is able to sort the grid by this column.
+ *
+ * @return true if the column is sortable by the user, false otherwise
*/
public boolean isSortable() {
return state.sortable;
* and 2, respectively. The column with a <strong>ratio of 0 is exactly
* as wide as its contents requires</strong>. The column with a ratio of
* 1 is as wide as it needs, <strong>plus a third of any excess
- * space</strong>, bceause we have 3 parts total, and this column
- * reservs only one of those. The column with a ratio of 2, is as wide
+ * space</strong>, because we have 3 parts total, and this column
+ * reserves only one of those. The column with a ratio of 2, is as wide
* as it needs to be, <strong>plus two thirds</strong> of the excess
* width.
*
}
/**
- * Gets the column's expand ratio.
+ * Returns the column's expand ratio.
*
* @return the column's expand ratio
* @see #setExpandRatio(int)
}
/**
- * Gets the minimum width for this column.
+ * Return the minimum width for this column.
*
* @return the minimum width for this column
* @see #setMinimumWidth(double)
}
/**
- * Gets the maximum width for this column.
+ * Returns the maximum width for this column.
*
* @return the maximum width for this column
* @see #setMaximumWidth(double)
public double getMaximumWidth() {
return getState().maxWidth;
}
+
+ /**
+ * Sets whether the properties corresponding to this column should be
+ * editable when the item editor is active. By default columns are
+ * editable.
+ * <p>
+ * Values in non-editable columns are currently not displayed when the
+ * editor is active, but this will probably change in the future. They
+ * are not automatically assigned an editor field and, if one is
+ * manually assigned, it is not used. Columns that cannot (or should
+ * not) be edited even in principle should be set non-editable.
+ *
+ * @param editable
+ * {@code true} if this column should be editable,
+ * {@code false} otherwise
+ * @return this column
+ *
+ * @throws IllegalStateException
+ * if the editor is currently active
+ *
+ * @see Grid#editItem(Object)
+ * @see Grid#isEditorActive()
+ */
+ public Column setEditable(boolean editable) {
+ checkColumnIsAttached();
+ if (grid.isEditorActive()) {
+ throw new IllegalStateException(
+ "Cannot change column editable status while the editor is active");
+ }
+ getState().editable = editable;
+ grid.markAsDirty();
+ return this;
+ }
+
+ /**
+ * Returns whether the properties corresponding to this column should be
+ * editable when the item editor is active.
+ *
+ * @return {@code true} if this column is editable, {@code false}
+ * otherwise
+ *
+ * @see Grid#editItem(Object)
+ * @see #setEditable(boolean)
+ */
+
+ public boolean isEditable() {
+ return getState().editable;
+ }
+
+ /**
+ * Sets the field component used to edit the properties in this column
+ * when the item editor is active. Please refer to
+ * {@link Grid#setEditorField(Object, Field)} for more information.
+ *
+ * @param editor
+ * the editor field, cannot be null
+ * @return this column
+ */
+ public Column setEditorField(Field<?> editor) {
+ grid.setEditorField(getPropertyId(), editor);
+ return this;
+ }
+
+ /**
+ * Returns the editor field used to edit the properties in this column
+ * when the item editor is active. Please refer to
+ * {@link Grid#getEditorField(Object)} for more information.
+ *
+ * @return the editor field or null if this column is not editable
+ */
+ public Field<?> getEditorField() {
+ return grid.getEditorField(getPropertyId());
+ }
}
/**
/**
* Gets the field component that represents a property in the item editor.
+ * Returns null if the corresponding column is not
+ * {@link Column#isEditable() editable}.
* <p>
* When {@link #editItem(Object) editItem} is called, fields are
* automatically created and bound for any unbound properties.
*
* @param propertyId
* the property id of the property for which to find the field
- * @return the bound field, never null
+ * @return the bound field or null if the respective column is not editable
*
* @throws IllegalArgumentException
* if there is no column for the provided property id
public Field<?> getEditorField(Object propertyId) {
checkColumnExists(propertyId);
+ if (!getColumn(propertyId).isEditable()) {
+ return null;
+ }
+
Field<?> editor = editorFieldGroup.getField(propertyId);
if (editor == null) {
editor = editorFieldGroup.buildAndBind(propertyId);
}
/**
- * Opens the editor interface for the provided item.
+ * Opens the editor interface for the provided item. Scrolls the Grid to
+ * bring the item to view if it is not already visible.
*
* @param itemId
* the id of the item to edit
editorFieldGroup.setItemDataSource(item);
for (Column column : getColumns()) {
- Object propertyId = column.getPropertyId();
-
- Field<?> editor = getEditorField(propertyId);
-
- getColumn(propertyId).getState().editorConnector = editor;
+ column.getState().editorConnector = getEditorField(column
+ .getPropertyId());
}
}
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.TextField;
public class GridColumns {
noSortColumn.setSortable(true);
}
+ @Test
+ public void testColumnsEditableByDefault() {
+ for (Column c : grid.getColumns()) {
+ assertTrue(c + " should be editable", c.isEditable());
+ }
+ }
+
+ @Test
+ public void testPropertyAndColumnEditorFieldsMatch() {
+ grid.setEditorField("column1", new TextField());
+ assertSame(grid.getEditorField("column1"), grid.getColumn("column1")
+ .getEditorField());
+
+ grid.getColumn("column2").setEditorField(new TextField());
+ assertSame(grid.getEditorField("column2"), grid.getColumn("column2")
+ .getEditorField());
+ }
+
+ @Test
+ public void testUneditableColumnHasNoField() {
+ Column col = grid.getColumn("column1");
+
+ col.setEditable(false);
+
+ assertFalse("Column should be uneditable", col.isEditable());
+ assertNull("Uneditable column should not be auto-assigned a Field",
+ col.getEditorField());
+ }
+
private GridColumnState getColumnState(Object propertyId) {
String columnId = columnIdMapper.key(propertyId);
for (GridColumnState columnState : state.columns) {
*/
public Connector rendererConnector;
+ /**
+ * Whether the values in this column are editable when the editor interface
+ * is active.
+ */
+ public boolean editable = true;
+
/**
* The connector for the field used to edit cells in this column when the
* editor interface is active.
* Gets the editor field for column in given index.
*
* @param colIndex
- * column index
+ * the column index
* @return the editor field for given location
+ *
+ * @throws NoSuchElementException
+ * if {@code isEditable(colIndex) == false}
*/
public TestBenchElement getField(int colIndex) {
return grid.getSubPart("#editor[" + colIndex + "]");
}
+ /**
+ * Gets whether the column with the given index is editable, that is,
+ * has an associated editor field.
+ *
+ * @param colIndex
+ * the column index
+ * @return {@code true} if the column has an editor field, {@code false}
+ * otherwise
+ */
+ public boolean isEditable(int colIndex) {
+ return grid
+ .isElementPresent(By.vaadin("#editor[" + colIndex + "]"));
+ }
+
/**
* Saves the fields of this editor.
* <p>
public static final String CELL_STYLE_GENERATOR_SPECIAL = "Special for 1/4 Column 1";
private static final int MANUALLY_FORMATTED_COLUMNS = 5;
public static final int COLUMNS = 12;
+ public static final int EDITABLE_COLUMNS = COLUMNS - 1;
public static final int ROWS = 1000;
private int containerDelay = 0;
grid.setSelectionMode(SelectionMode.NONE);
- grid.getEditorField(getColumnProperty(3)).setReadOnly(true);
+ grid.getEditorField(getColumnProperty(2)).setReadOnly(true);
+ grid.getColumn(getColumnProperty(3)).setEditable(false);
createGridActions();
List<WebElement> widgets = editor.findElements(By
.className("gwt-TextBox"));
- assertEquals(GridBasicFeatures.COLUMNS, widgets.size());
+ assertEquals(GridBasicFeatures.EDITABLE_COLUMNS, widgets.size());
assertEquals("(100, 0)", widgets.get(0).getAttribute("value"));
assertEquals("(100, 1)", widgets.get(1).getAttribute("value"));
assertEquals("(100, 2)", widgets.get(2).getAttribute("value"));
- assertEquals("100", widgets.get(7).getAttribute("value"));
- assertEquals("<b>100</b>", widgets.get(9).getAttribute("value"));
+ assertEquals("100", widgets.get(6).getAttribute("value"));
+ assertEquals("<b>100</b>", widgets.get(8).getAttribute("value"));
}
@Test
.getText());
}
+ public void testUneditableColumn() {
+ selectMenuPath("Component", "Editor", "Edit row 5");
+
+ assertFalse("Uneditable column should not have an editor widget",
+ getGridElement().getEditor().isEditable(3));
+ }
+
protected WebElement getSaveButton() {
return getEditor().findElement(By.className("v-grid-editor-save"));
}
protected WebElement getCancelButton() {
return getEditor().findElement(By.className("v-grid-editor-cancel"));
}
-
}
selectMenuPath(EDIT_ITEM_100);
List<WebElement> widgets = getEditorWidgets();
- assertEquals("Number of widgets", GridBasicFeatures.COLUMNS,
+ assertEquals("Number of widgets", GridBasicFeatures.EDITABLE_COLUMNS,
widgets.size());
assertEquals("(100, 0)", widgets.get(0).getAttribute("value"));
assertEquals("(100, 1)", widgets.get(1).getAttribute("value"));
assertEquals("(100, 2)", widgets.get(2).getAttribute("value"));
- assertEquals("<b>100</b>", widgets.get(9).getAttribute("value"));
+ assertEquals("<b>100</b>", widgets.get(8).getAttribute("value"));
}
@Test
private void assertEditorOpen() {
assertNotNull("Editor is supposed to be open", getEditor());
- assertEquals("Unexpected number of widgets", GridBasicFeatures.COLUMNS,
- getEditorWidgets().size());
+ assertEquals("Unexpected number of widgets",
+ GridBasicFeatures.EDITABLE_COLUMNS, getEditorWidgets().size());
}
private void assertEditorClosed() {
originalScrollPos, getGridVerticalScrollPos());
}
+ @Test
+ public void testUneditableColumn() {
+ selectMenuPath(EDIT_ITEM_5);
+ assertEditorOpen();
+
+ assertFalse("Uneditable column should not have an editor widget",
+ getGridElement().getEditor().isEditable(3));
+ }
+
private WebElement getSaveButton() {
return getDriver().findElement(By.className("v-grid-editor-save"));
}
column.setHeaderCaption("Header (0," + c + ")");
}
+ grid.getColumn(3).setEditable(false);
+
HeaderRow row = grid.getDefaultHeaderRow();
for (int i = 0; i < col; ++i) {
String caption = "Header (0," + i + ")";