Binder and Validation Issues

I am trying to use a Binder to map my UI to my Bean. I am new to Vaadin and very new to Binders. I have some sample code that works in another application that I am trying to use here and keep getting validation errors. I’ll paste the code below.

I have removed all the validation code from my binder yet when I call binder.isValid() it fails. If instead I comment out the isValid the writeBean does work. However, if I do have any validator and call writeBean, it fails with validation errors.

Not sure where to go with this. Any thoughts?

Binder<BroadcastMessage> dataBinder = new Binder<>( BroadcastMessage.class ); // field binder

//  Setup Data Binding
dataBinder.forField( comboBoxCategories ).bind( BroadcastMessage::getDocCat, BroadcastMessage::setDocCat );
dataBinder.forField( comboBoxBroadcastType ).bind( BroadcastMessage::getBroadcastMessage, BroadcastMessage::setBroadcastMessage );
dataBinder.forField( txtDocTitle ).bind( BroadcastMessage::getDocTitle, BroadcastMessage::setDocTitle );
//  this fails when I try to write the bean
//  dataBinder.forField( txtDocTitle ).withValidator( strTitle -> strTitle.length() >= 3, "Please enter a title" ).bind( BroadcastMessage::getDocTitle, BroadcastMessage::setDocTitle );
dataBinder.forField( txtAreaBody ).bind( BroadcastMessage::getBroadcastMessage, BroadcastMessage::setBroadcastMessage );
dataBinder.forField( comboBoxMailWho ).bind( BroadcastMessage::getMailWho, BroadcastMessage::setMailWho );
dataBinder.forField( txtAdditionalDestinations ).bind( BroadcastMessage::getAddEmails, BroadcastMessage::setAddEmails );
dataBinder.forField( txtAdditionalDestinations ).bind( BroadcastMessage::getAddPhoneNumbers, BroadcastMessage::setAddPhoneNumbers );
dataBinder.forField( txtBroadcastMessagCallerID ).bind( BroadcastMessage::getBroadcastMessageCallerID, BroadcastMessage::setBroadcastMessageCallerID );

// Submit button event listener(Save document)
btnSubmit.addClickListener( e ->
{
	if( dataBinder.isValid() )
	{
		try
		{
			dataBinder.writeBean( gBroadcastMessageObject ); // Write values to bean model
		} catch ( ValidationException e1 )
		{
			e1.printStackTrace();
		}
	}
	else
	{
		dataBinder.validate();
	}

What validation errors are you getting? Are any other fields required?

If I put validation on just one field, and call isValid or writeBean it fails saying the field didn’t pass the validation.

For example: dataBinder.forField( txtDocTitle ).withValidator( strTitle → strTitle.length() >= 3, “Please enter a title” ).bind( BroadcastMessage::getDocTitle, BroadcastMessage::setDocTitle )

When I type in more than 3 characters in that field then call the isValid it fails.  Likewise if I don't call isValid but try to writeBean I get the same error.

I just ran into a very interesting issue. I noticed on one of my combo boxes, an error showed up when it was blank even though I do not have any validation on it. It turns out that I have a valueChangeListener on the comboBox. Just for grins I removed the valueChangeListener and now the error goes away.

I already removed all the binder code and don’t want to put it back at the moment due to time constraints. Is that a known issue perhaps with binders and comboBoxes with valueChangeListeners causing the binder to fail?

I tried an example that does what you say and it seems to work fine for me. I am using Vaadin 8.6.3
Here is the example.

@SpringUI(path = "binding")
public class BindingUI extends UI {
    @Override
    protected void init(VaadinRequest request) {
        HorizontalLayout layout = new HorizontalLayout();
        CheckBox checkBox = new CheckBox();
        checkBox.addValueChangeListener(e -> {
            String message = String.format("Changed from %s to %s", e.getOldValue(), e.getValue());
            System.out.println(message);
        });
        Binder<Mamal> binder = new Binder<>();
        binder.bind(checkBox, Mamal::isHuman, Mamal::setHuman);
        binder.readBean(new Mamal());
        layout.addComponent(checkBox);
        layout.addComponent(new Button("Save", event -> {
            if (binder.isValid()) {
                System.out.println("Valid");
            } else {
                System.out.println("Invalid");
            }
        }));
        setContent(layout);
    }

    public static class Mamal {
        private boolean human = true;

        public boolean isHuman() {
            return human;
        }

        public void setHuman(boolean human) {
            this.human = human;
        }
    }
}