How to make only some columns editable in a Vaadin

2019-04-26 17:59发布

问题:

Vaadin Grid allows to be defined as editable with

grid.setEditorEnabled(true);

This makes all visible columns editable. However I don't want the user to edit an specific column, but seems like the editable is an all or nothing.

The next best solution I have found is to define an editor field with a disabled editor, which almost does the trick but the user is still able to select the text and move the cursor (but the field is not editable anymore).

Grid.Column nameColumn = grid.getColumn("fullName");
nameColumn.setHeaderCaption("Full Name");
nameColumn.setEditorField(getNoEditableTextField());

...

private Field<?> getNoEditableTextField() {
    TextField noEditableTextFiled = new TextField();
    noEditableTextFiled.setEnabled(false);
    return noEditableTextFiled;
}

I believe Label cannot be used because it's not a Field.

Is there a better option to achieve this?

edit: as aakath said, there is a way of achieving this not enabling the column to be edited, but in doing so the cell value disappears when you edit the row, which is not desirable.

回答1:

my solution is below. i have just finished. it was not tested too much. but it may give you some ideas.

ati

  getColumn(columnName).setEditable(true).setEditorField(getNoEditableField(columnName));

...

private Field<?> getNoEditableField(final String columnName) {
    CustomField<Label> result = new CustomField() {
        @Override
        protected Component getContent() {
            Label result = (Label) super.getContent();
            Object editedItemId = getEditedItemId();
            String value = DEFAULT_VALUE;
            if (editedItemId != null) {
                value = CustomizableGrid.this.toString(getContainerDataSource().getItem(editedItemId).getItemProperty(columnName).getValue());
            }
            result.setValue(value);
            return result;
        }

        @Override
        protected Component initContent() {
            Label result = new Label(DEFAULT_VALUE, ContentMode.HTML);
            result.setDescription(getColumnDescription(columnName));
            result.setStyleName("immutablegridcellstyle");
            return result;
        }

        @Override
        public Class getType() {
            return Label.class;
        }
    };
    result.setConverter(new Converter<Label, Object>() {
    //converter for your data
    });

    return result;
}


回答2:

Did you try calling setEditable(false) method on the column? I believe it should make the field non-editable when the item editor is active.

grid.getColumn("fullName").setEditable(false);


回答3:

I had the same problem and didn't want that clicking on id column opens editor. I solved it with adding an ItemClickListener as below. It works fine for me.

grid.addItemClickListener((ItemClickListener<GridBean>) event -> grid.getEditor().setEnabled(!event.getColumn().getCaption().equals("Id")));

Also byc clicking on specific columns Grid is not editable any more.



回答4:

There is one tricky way to do it! I've just found out it. So, first of all you need to use grid with container, instead of direct rows adding:

BeanItemContainer<MyBean> container = new BeanItemContainer<>(MyBean.class);
setContainerDataSource(container);

Then remove fields setters from MyBean, except setters for fields what you have to edit.



回答5:

I think the same can be achieved by making the grid an editable one by grid.setEditorEnabled(true); and disabling editing option for other columns like grid.getColumn(columnName).setEditable(false);. But I am not sure of any demerits of this method. Any suggestion is always appreciated.



回答6:

Its simple just go to Vaadin Documentation what did from it is below: you can see here I gave a specified column Name

grid = new Grid<>();
    lst = new ArrayList<>();
    provider = new ListDataProvider<>(lst);
    lst.add(new Company(1, "Java"));
    grid.setDataProvider(provider);
    grid.addColumn(Company::getSerialNo).setCaption("Sr.no");
    TextField tf = new TextField();

    grid.getEditor().setEnabled(true);

    HorizontalLayout hlyt = new HorizontalLayout();
    grid.addColumn(Company::getName).setEditorComponent(tf, Company::setName).setCaption("Name").setExpandRatio(2);

    hlyt.addComponent(grid);


回答7:

I use the following approach to get a read-only field, the trick is override the setEnabled method to get a disabled textfield. If you trace the source code in Vaadin Grid, no matter what field you pass to a Grid, it will always call the field.setEnabled(true).

myGrid.getColumn(propertyId).setEditorField(new ReadOnlyField());

And

public class ReadOnlyField extends TextField
{
    public ReadOnlyField()
    {
        super();
        this.setReadOnly(true);
    }

    @Override
    public void setEnabled(boolean enabled)
    {
        // always set to disabled state
        super.setEnabled(false);
    }
}