You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

Sometimes a field cannot be validated in isolation, but instead two or more fields must be validated together. In this case validation takes place at the form level. Subclass AbstractFormValidator, using a constructor that takes as parameters the form components to be validated. When instances of the form are created, add an instance of the validator to the form instance.

Here's an example (cortesy of Ivailo Bardarov) that validates that two given fields in the form are not both empty.

First, the form validator class:


import java.util.Collections;

import wicket.markup.html.form.Form;
import wicket.markup.html.form.FormComponent;
import wicket.markup.html.form.validation.AbstractFormValidator;
import wicket.util.lang.Objects;

/**
 * Validates that one of the input of two form components is not empty. Errors
 * are reported on the second form component with key 'OrInputValidator' and the
 * variables:
 * <ul>
 * <li>${input(n)}: the user's input</li>
 * <li>${name}: the name of the component</li>
 * <li>${label(n)}: the label of the component - either comes from
 * FormComponent.labelModel or resource key [form-id].[form-component-id] in
 * that order</li>
 * </ul>
 * 
 * @author Ivailo Bardarov
 * @see wicket.markup.html.form.validation.EqualInputValidator by Igor Vaynberg
 * 
 */
public class OrInputValidator extends AbstractFormValidator {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/** form components to be checked. */
	private final FormComponent[] components;

	/**
	 * Construct.
	 * 
	 * @param formComponent1
	 *            a form component
	 * @param formComponent2
	 *            a form component
	 */
	public OrInputValidator(FormComponent formComponent1,
			FormComponent formComponent2) {
		if (formComponent1 == null) {
			throw new IllegalArgumentException(
					"argument formComponent1 cannot be null");
		}
		if (formComponent2 == null) {
			throw new IllegalArgumentException(
					"argument formComponent2 cannot be null");
		}
		components = new FormComponent[] { formComponent1, formComponent2 };
	}

	/**
	 * @see wicket.markup.html.form.validation.IFormValidator#getDependentFormComponents()
	 */
	public FormComponent[] getDependentFormComponents() {
		return components;
	}

	/**
	 * @see wicket.markup.html.form.validation.IFormValidator#validate(wicket.markup.html.form.Form)
	 */
	public void validate(Form form) {
		// we have a choice to validate the type converted values or the raw
		// input values, we validate the raw input
		final FormComponent formComponent1 = components[0];
		final FormComponent formComponent2 = components[1];

		if (
			"".equals(Objects.stringValue(formComponent1.getInput(), true)) &&
			"".equals(Objects.stringValue(formComponent2.getInput(), true))
		   ) {
			final String key = resourceKey(components);
			formComponent2.error(Collections.singletonList(key), messageModel());
		}
	}
}

Note that the validate method calls FormComponent.getInput to get the values to be validated, rather than getting the associated models. This is because the models are not updated until after validation.

And here's the use of validator (with irrelevant details of the form creation omitted here):

Form myForm = new Form("aForm");

FormComponent f1 = new TextField("f1");
myForm.add(f1);
FormComponent f2 = new TextField("f2");
myForm.add(f2);

myForm.add(new OrInputValidator(f1, f2));

Finally, define a property for the error message:

OrInputValidator=One of '${input0}' from ${label0} or '${input1}' from ${label1} must have a non-empty value 
  • No labels