Hi all, i have to make a Validator that is generic in use and can validate more then one field for example a zip-code validator that checks if the zipcode is correct and if the street and housnumber are within the range of the zipcode.
I read about the options there are to validate multiple fields but the problem with the options i found is that your validator must be aware of the id you give your components on the pages, since i have 2 different Adresses on my page with a zipcode validation rule it would(at least i think) not be possible to use one validator. If i'm mistaken please say so. I now made a component that u can put anywhere on your page to have multiple field validations, but i don't know if it is a correct way to do so, so could anyone give me feed back. My component can be put on the form with for example the following tag. <svb:multiplefieldvalidation forComponents="componentId1, componentId2, component3" keys="street, housenumber, zipcode"> <f:validator id="zipcodeValidator"> </svb:multiplefieldvalidation> and now exist (still in development so really stupid code) of this code package nl.svb.faces.component; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import javax.faces.application.FacesMessage; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; /** * @author jgdenoo * */ public class UIMultipleFieldValidation extends UIInput { private String forComponents; private String keys; private Map submittedValues = new HashMap(); public final static String COMPONENT_FAMILY = "svb.MultipleFields"; public final static String COMPONENT_TYPE = "svb.MultipleFields"; public void encodeBegin(FacesContext context) throws IOException { } public void encodeEnd(FacesContext context) throws IOException { } /* (non-Javadoc) * @see javax.faces.component.UIInput#decode(javax.faces.context.FacesContext) */ public void decode(FacesContext arg0) { } /* (non-Javadoc) * @see javax.faces.component.UIInput#validate(javax.faces.context.FacesContext) */ public void validate(FacesContext context) { System.out.println("in validate"); System.out.println("validators" + getValidators()[0]); System.out.println("validator" + getValidator()); parse(forComponents, keys); // TODO Auto-generated method stub System.out.println(isValid()); Validator validator = (Validator) getValidators()[0]; validator.validate(context, this, submittedValues); } /** * @param forComponents * @param keys */ private void parse(String forComponents, String keys) { StringTokenizer forTokenizer = new StringTokenizer(forComponents, ","); StringTokenizer keyTokenizer = new StringTokenizer(keys, ","); if (forTokenizer.countTokens() != keyTokenizer.countTokens()) { //TODO: Message met ongelijke hoeveelheid tokens gooien!. } while (keyTokenizer.hasMoreTokens()) { UIInput component = (UIInput) this.findComponent(forTokenizer.nextToken()); submittedValues.put(keyTokenizer.nextToken(), component.getLocalValue()); } } public void setForComponents(String forValue) { forComponents = forValue; } public Map getSubmittedValues() { return submittedValues; } public Object getSubmittedValue(String key) { return submittedValues.get(key); } /* (non-Javadoc) * @see javax.faces.component.UIInput#saveState(javax.faces.context.FacesContext) */ public Object saveState(FacesContext context) { Object[] values = new Object[5]; values[0] = super.saveState(context); values[1] = submittedValues; values[2] = forComponents; values[3] = keys; return values; } /* (non-Javadoc) * @see javax.faces.component.UIInput#restoreState(javax.faces.context.FacesContext, java.lang.Object) */ public void restoreState(FacesContext context, Object object) { Object[] values = (Object[]) object; super.restoreState(context, values[0]); submittedValues = (Map) values[1]; forComponents = (String) values[2]; keys = (String) values[3]; } public String getFamily() { // we need this because we are subclassing UIComponentBase and not a concrete subclass return COMPONENT_FAMILY; } /** * @return */ public String getKeys() { return keys; } /** * @param string */ public void setKeys(String string) { keys = string; } } The validator then can get the Map with local/submitted values from this component and can so validate the fields. I know this is not really a myfaces issue but more a general JSF issue i think but i wondered if any of u could give me some advise if this is a good way to go, or better do something else. Greetings , Job de Noo