Cannot discard changes made in fields in TableFieldFactory

Hi all!

I have a simple Table where I present some data using an IndexedContainer as data source.
I want my users to be able to edit
some of
this data, so I’m using a TableFieldFactory (DefaultFieldFactory) to generate these columns (properties) editable.

Now, if a user is in editing mode (table.setEditable(true)) and have been changing some fields, he or she should be able to discard those changes - for this purpose, I have a “Cancel” button. This “Cancel” button is supposed to discard all changes made in the Table generated fields since the user entered editing mode and then setEditable(false) - now everything should be the way it was before setEditable(true) was called.

This didn’t sound very hard, until I tried implementing it.

If I understand the functionality of the Table vs. Container vs. TableFieldFactory correctly, the following happens: [list=1]
Properties are added to the Container
[]
The Container is set as the Table data source
[
]
The User clicks the “Edit Table” button (table.setEditable(true))
[]
The Table calls the TableFieldFactory’s overridden createField() method
[
]
The createField() method creates the editable fields
[]
The user edits the fields and at the same time the Container gets updated ← not 100% sure about this one
[
]
The user clicks the “Cancel” button ← HERE is my problem
[/list]


What should I do discard() on?
I can’t do table.discard(), because the changes has already taken place. I can’t do container.discard() becase, yeah, the Container interface doesn’t inherit that method. I can’t do field.discard(), because I cannot reach the fields from outside the createField() method.

I have tried different variations of setBuffered, markAsDirty, refreshRowCache and setImmediate without success.

Here’s (hopefully all) relevant code:

The table, container and the “Cancel” button (roughly):


Table table = new Table();
Container container = new IndexedContainer();

container.addContainerProperty("Foo" String.class, null);
container.addContainerProperty("Bar", String.class, null);

//... adding some stuff to the container...

table.setContainerDataSource(container);

Button cancel = new Button("Cancel", new Button.ClickListener() {
	private static final long serialVersionUID = 1L;

	@Override
	public void buttonClick(ClickEvent event) {
		// table.setImmediate(false); //tried variations of this
		// table.refreshRowCache(); //tried variations of this
		// table.markAsDirty(); //tried variations of this
		// table.setBuffered(true); //tried variations of this
		// table.discard(); //tried this, but here it's too late
		table.setEditable(false);
	}
});

The TableFieldFactory


table.setTableFieldFactory(new DefaultFieldFactory() {
	private static final long serialVersionUID = 1L;

	@Override
	public Field<?> createField(Container container, Object itemId, Object propertyId, com.vaadin.ui.Component uiContext) {

		TextField tField = (TextField) DefaultFieldFactory.get().createField(container, itemId, propertyId, uiContext);
		tField.setImmediate(true);

		if (propertyId.equals("Foo")) {
			// field.setImmediate(true); //tried variations of this
			// field.setBuffered(false); //tried variations of this
			return tField;
		}
		else {
			tField.setReadOnly(true);
		}
		return tField;
	}
});

Thank you!

//Roger

I’ve answered this
over on StackOverflow
, but for other-forum user’s sakes, I’ll mention it here, too.

If you keep hold of the fields generated in your Factory, you can then invoke commit/discard as you please.

I’ve not used editable tables before - not 100% convinced that my users would like the UI, and I would rather do a master-detail table/form approach, as most of our data is more complicated that a simple spreadsheet approach would support

However, I’ve knocked together a standalone example as a
Gist over on GitHub
, and I think it’s a fairly clear approach.

Select a row and click Edit button (or double click row) to allow editing of a row. Save (Enter) will commit any edits, and Cancel (Escape) will discard any edits.

HTH,

Cheers,

Charles.

Thanks for your efforts, Charles! Works like a charm!