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

Reply via email to