Form - validator not allowed

Hi,

why are validators not allowed to be used for forms? It might be really useful to validate combinations of item properties before the form can become committed.

Eg,

Item Person
att name
att country
att postalcode

A validator at form level could check whether the country ↔ postalcode combination is valid.

Based on redVoodo.org i have created a ValidatedForm which allows the use of form validator. And it really works pretty good!

Should i open a bug as an enhancement request?

Thanks,
Florian Pirchner

redVoodo.org

Hi,

no suggestions?

Florian Pirchner

I also have a need for this. Are there any plans to implement this soon?

Hi,

i can provide you my implementation.

Cheers,
Florian Pirchner

please do.

Hi,

my solution.

/*******************************************************************************

  • Copyright (c) 2011 Florian Pirchner
  • All rights reserved. This program and the accompanying materials
  • are made available under the terms of the Eclipse Public License v1.0
  • which accompanies this distribution, and is available at
  • http://www.eclipse.org/legal/epl-v10.html
  • Contributors:
  • Florian Pirchner - initial API and implementation
    *******************************************************************************/
    package org.redvoodo.eos.ui.components.form;

import java.util.ArrayList;
import java.util.List;

import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.terminal.CompositeErrorMessage;
import com.vaadin.terminal.ErrorMessage;
import com.vaadin.ui.Form;
import com.vaadin.ui.FormFieldFactory;
import com.vaadin.ui.Layout;

@SuppressWarnings(“serial”)
public class ValidatedForm extends Form {

private ErrorMessage externalMessages;
private List<Validator> validators;
private boolean valid;

public ValidatedForm() {
	super();
}

public ValidatedForm(Layout formLayout, FormFieldFactory fieldFactory) {
	super(formLayout, fieldFactory);
}

public ValidatedForm(Layout formLayout) {
	super(formLayout);
}

@Override
public boolean isValid() {
	externalMessages = null;

	boolean result = super.isValid();
	if (validators != null) {
		valid = true;
		for (Validator validator : validators) {
			valid &= validator.isValid(getItemDataSource());
		}
		result &= valid;
	}
	return result;
}

@Override
public void validate() throws InvalidValueException {
	externalMessages = null;

	super.validate();

	if (validators != null) {
		for (Validator validator : validators) {
			validator.validate(getItemDataSource());
		}
	}
}

@Override
public void addValidator(Validator validator) {
	if (validators == null) {
		validators = new ArrayList<Validator>();
	}
	validators.add(validator);
	requestRepaint();
}

@Override
public void removeValidator(Validator validator) {
	if (validators != null) {
		validators.remove(validator);
	}
}

/**
 * Removes all validators.
 */
public void removeAllValidator() {
	if (validators != null) {
		validators.clear();
	}
}

/**
 * Sets the external messages. External messages are the result of the
 * business logic validation. To visualize them, they are put to this form
 * and painted at it.
 * 
 * @param externalMessages
 *            the externalMessages to set
 */
public void setExternalMessages(List<? extends ErrorMessage> messages) {
	this.externalMessages = messages != null && messages.size() > 0 ? new CompositeErrorMessage(
			messages) : null;
	requestRepaint();
}

@Override
public ErrorMessage getErrorMessage() {
	ErrorMessage superError = super.getErrorMessage();
	ErrorMessage validationError = null;
	if (validators != null && isValidationVisible() && !valid) {
		for (Validator validator : validators) {
			try {
				validator.validate(getItemDataSource());
			} catch (Validator.InvalidValueException e) {
				if (!e.isInvisible()) {
					validationError = e;
				}
			}
		}
	}

	// Return if there are no errors at all
	if (superError == null && validationError == null
			&& externalMessages == null) {
		return null;
	}

	// Throw combination of the error types
	return new CompositeErrorMessage(new ErrorMessage[] { superError,
			validationError, externalMessages });
}

@Override
public void discard() throws SourceException {
	super.discard();

	setExternalMessages(null);
}

}

Thanks,
Florian

Thank you very much Florian. Very helpful!