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