Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
How to validate fields in a Table
I am creating a table that has two columns. The first column is not editable. The second column is editable. The second column contains TextFields and ComboBoxs (I have set the table to be in edit mode and I created a TableFieldFactory for the second column). All of the fields in the second column are set to be required and validation visible. I am not seeing the red Asterisk as I should for any of the TextFields or the ComboBoxes but I am able to see the required message when I have the mouse over the TextFields. How do I get an individual fields errors to display correctly in a table?
Here is my createField method:
public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
Field field = null;
if(propertyId != null && propertyId instanceof String) {
Attribute attribute = getAttribute(itemId);
if(propertyId.equals("attributeValue")) {
List<AttributeValue> values = AttributeManager.getInstance().getAttributeValues(attribute.getAttribute());
if(values.size() > 0) {
ComboBox options = new ComboBox();
options.setImmediate(true);
options.setRequired(true);
options.setRequiredError("This field is required!");
options.setValidationVisible(true);
for(AttributeValue value : values) {
options.addItem(new AttributeValueNode(value));
}
field = options;
} else {
TextField textField = new TextField();
textField.setImmediate(true);
textField.setRequired(true);
textField.setRequiredError("This field is required!");
textField.setValidationVisible(true);
field = textField;
}
field.setWidth("100%");
}
}
return field;
This might go to the "you just have to know" file. In Vaadin, the caption and error markers are not rendered by components themselves. Instead, they are rendered by the containing layout (if any). In this case, you need to somehow wrap the fields in a layout and use that as a cell in the table. One solution might be to build a custom proxy that extends a layout, implements Field and delegates all field methods to the underlying field component.
Risto Yrjänä: This might go to the "you just have to know" file. In Vaadin, the caption and error markers are not rendered by components themselves. Instead, they are rendered by the containing layout (if any). In this case, you need to somehow wrap the fields in a layout and use that as a cell in the table. One solution might be to build a custom proxy that extends a layout, implements Field and delegates all field methods to the underlying field component.
I have created the proxy class that you suggested and now the error messages are displayed correctly.
Thank you
Douglas Thomsen:
Risto Yrjänä: This might go to the "you just have to know" file. In Vaadin, the caption and error markers are not rendered by components themselves. Instead, they are rendered by the containing layout (if any). In this case, you need to somehow wrap the fields in a layout and use that as a cell in the table. One solution might be to build a custom proxy that extends a layout, implements Field and delegates all field methods to the underlying field component.
I have created the proxy class that you suggested and now the error messages are displayed correctly.
Thank you
hi Douglas Thomsen
i had done follow direction of you ,but when build class proxy implement Field,
I know Field has AbstracField implement it directly
and when i implement it has error The inherited method AbstractComponent.focus() cannot hide the public abstract method in Component.Focusable
can you explain why
thank you
le thi phuong: i had done follow direction of you ,but when build class proxy implement Field,
I know Field has AbstracField implement it directly
and when i implement it has error The inherited method AbstractComponent.focus() cannot hide the public abstract method in Component.Focusable
can you explain why
This is really an Eclipse issue: when adding "implements MyInterface" and then doing "implement missing methods", Eclipse does not override protected methods with public ones even if the implemented interface requires such a public method.
Just add the method
public void focus() {
super.focus();
}
Hi all
i have buld proxy class and write table field factory but table not edit
private HashMap<Object, HashSet<Field>> markedRows =
new HashMap<Object, HashSet<Field>>();
Table table=new Table()
table.addContainerProperty("name",ShowResultAndError.class,null);
table.addContainerProperty("edit",Button.class,null);
table.setTableFieldFactory(new TableFieldFactor(public Field createField(
Container container, Object itemId, Object propertyId,
Component uiContext) {
Field field=null;
if (markedRows.containsKey(itemId)) {
System.out.println("co chua itemid");
HashSet<Field> cells = markedRows.get(itemId);
}
if(propertyId.toString().equals("name")){
System.out.println("create cell name");
field = new TextField((String) propertyId);
field.setData(propertyId);
//field.setReadOnly(false);
ShowResultAndError show=new ShowResultAndError(field);
field=show;
cells.add(field);
markedRows.put(itemId, cells);
}
return field;
)
my proxy class extend layout and implement Field it contain a TextField;
i try my best to find reason but now not yet
thanks for all direction
hey !
I've read the answers but I can not do. Anyone can give me a sample ?
Thank!
I've created a new class with a validateFields method that changes the styleName when the field isn't valid:
public class Table2 extends Table {
private ArrayList<Field> fields;
public Table2() {
fields = new ArrayList<Field>();
}
public void registerFieldToValidate(Field field) {
fields.add(field);
}
public void validateFields() {
for (Field field: fields) {
try {
field.validate();
field.removeStyleName("err");
}
catch (Validator.InvalidValueException ex) {
field.addStyleName("err");
}
}
}
}
When you create the fields with the table field factory, call the registerFieldToValidate method to save a reference:
table.setTableFieldFactory(new TableFieldFactory() {
@Override
public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
TextField tf = new TextField();
[b] table.registerFieldToValidate(tf);[/b]
tf.setNullRepresentation("");
tf.setNullSettingAllowed(true);
tf.addValidator(new DoubleValidator("Incorrect number"));
return tf;
}
}
Miguel Angel: When you create the fields with the table field factory, call the registerFieldToValidate method to save a reference:
If you do this, don't forget to unregister the fields when they go out of the view, especially if the table is very big with lazy loading in use.
Hello,
I am searching for a solution for the discussed problem, too.
I have a table with three columns and only the third column is supposed to be editable.
I have set the table to be editable (setEditable(true)) and set a TableFieldFactory. When I let the createField method return a normal TextField for the relevant column the column is editable, but when I let the createField method return my proxy class the column is not editable.
Proxy class:
package (...)
import java.util.Collection;
import com.vaadin.data.Property;
import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.ui.Field;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
public class Test extends HorizontalLayout implements Field {
/**************************************************************************/
private static final long serialVersionUID = 1L;
/**************************************************************************/
private TextField field;
/**************************************************************************/
public Test() {
super();
}
public Test(final TextField field) {
super();
this.field = field;
}
/**************************************************************************/
@Override
public boolean isInvalidCommitted() {
return this.field.isInvalidCommitted();
}
@Override
public void setInvalidCommitted(final boolean isCommitted) {
this.field.setInvalidCommitted(isCommitted);
}
@Override
public void commit() throws SourceException, InvalidValueException {
this.field.commit();
}
@Override
public void discard() throws SourceException {
this.field.discard();
}
@Override
public boolean isWriteThrough() {
return this.field.isWriteThrough();
}
@Override
public void setWriteThrough(final boolean writeThrough) throws SourceException, InvalidValueException {
this.field.setWriteThrough(writeThrough);
}
@Override
public boolean isReadThrough() {
return this.field.isReadThrough();
}
@Override
public void setReadThrough(final boolean readThrough) throws SourceException {
this.field.setReadThrough(readThrough);
}
@Override
public boolean isModified() {
return this.field.isModified();
}
@Override
public void addValidator(final Validator validator) {
this.field.addValidator(validator);
}
@Override
public void removeValidator(final Validator validator) {
this.field.removeValidator(validator);
}
@Override
public Collection<Validator> getValidators() {
return this.field.getValidators();
}
@Override
public boolean isValid() {
return this.field.isValid();
}
@Override
public void validate() throws InvalidValueException {
this.field.validate();
}
@Override
public boolean isInvalidAllowed() {
return this.field.isInvalidAllowed();
}
@Override
public void setInvalidAllowed(final boolean invalidValueAllowed) throws UnsupportedOperationException {
this.field.setInvalidAllowed(invalidValueAllowed);
}
@Override
public Object getValue() {
return this.field.getValue();
}
@Override
public void setValue(final Object newValue) throws ReadOnlyException, ConversionException {
this.field.setValue(newValue);
}
@Override
public Class<?> getType() {
return this.field.getType();
}
@Override
public void addListener(final ValueChangeListener listener) {
this.field.addListener(listener);
}
@Override
public void removeListener(final ValueChangeListener listener) {
this.field.removeListener(listener);
}
@Override
public void valueChange(final com.vaadin.data.Property.ValueChangeEvent event) {
this.field.valueChange(event);
}
@Override
public void setPropertyDataSource(final Property newDataSource) {
this.field.setPropertyDataSource(newDataSource);
}
@Override
public Property getPropertyDataSource() {
return this.field.getPropertyDataSource();
}
@Override
public int getTabIndex() {
return this.field.getTabIndex();
}
@Override
public void setTabIndex(final int tabIndex) {
this.field.setTabIndex(tabIndex);
}
@Override
public boolean isRequired() {
return this.field.isRequired();
}
@Override
public void setRequired(final boolean required) {
this.field.setRequired(required);
}
@Override
public void setRequiredError(final String requiredMessage) {
this.field.setRequiredError(requiredMessage);
}
@Override
public String getRequiredError() {
return this.field.getRequiredError();
}
@Override
public void focus() {
super.focus();
}
/**************************************************************************/
public TextField getField() {
return this.field;
}
public void setNullableTextField(final TextField field) {
this.field = field;
}
/**************************************************************************/
}
Usage of the proxy class:
this.table.setEditable(true);
this.table.setTableFieldFactory(new TableFieldFactory() {
private static final long serialVersionUID = 1L;
@Override
public Field createField(final Container container, final Object itemId, final Object propertyId,
final Component uiContext) {
final TextField textField = new TextField();
textField.setImmediate(true);
textField.addValidator(new RegexpValidator("(...)", "(...)"));
final Test test = new Test(textField);
return "[columnId]".equals(propertyId.toString()) ? test : null;
}
});
What am I doing wrong?
Regards
Meik B.
Hello,
when I change the constructor of the proxy class from
public Test(final TextField field) {
super();
this.field = field;
}
to
public Test(final TextField field) {
super();
this.field = field;
[b]addComponent(field);[/b]
}
the column is editable. :)
Unfortunately there is no red exclamation mark when the validation fails. :(
Regards
Meik B.
Meik B.: Proxy class:
public class Test extends HorizontalLayout implements Field {
The CustomField add-on and the class FieldWrapper in it would let you avoid implementing and forwarding all methods of Field yourself - it takes care of it and you can still construct the layout yourself and override only what you need.
Hello Henri,
thanks for the hint. Maybe the add-on can simplify the solution, but does my approach include an obvious mistake or should it work this way, too?
Regards
Meik B.