I belive I had "reported" in bugzzila multi row validation problme 2 years ago, as well as posts.
Here is the code I have been shiping for a long time with bP (writen by Jose/Ben):
package com.fX.base;


/*
 * MultiRowValidator.java
 * by Ben Tomasini - original by Jose Quiteriono ?
 * 12/10/2002
 *
 */

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.ValidatorAction;
import org.apache.struts.action.ActionErrors;

/**
* This class contains multi-row validations for a collection
* *** validation.xml
ex: use
<form name="ClosingChecklistForm">
<field property="sortOrder" depends="multiRowRequired,multiRowInteger">
<arg0 key="ClosingChecklistForm.sortOrder.displayname"/>
<var>
<var-name>rowName</var-name>
<var-value>row</var-value>
</var>
</field>
<field property="daysBeforeBenchmark" depends="multiRowInteger">
<arg0 key="ClosingChecklistForm.daysBeforeBenchmark.displayname"/>
<var>
<var-name>rowName</var-name>
<var-value>row</var-value>
</var>
</field>
<field property="description" depends="multiRowRequired">
<arg0 key="ClosingChecklistForm.description.displayname"/>
<var>
<var-name>rowName</var-name>
<var-value>row</var-value>
</var>
</field>
</form>
*
*/
public class MultiRowValidator extends org.apache.struts.validator.FieldChecks
implements Serializable {
//TODO: rename row to index


    /**
     * Commons Logging instance.
     */
    private static Log LOG = LogFactory.getLog(MultiRowValidator.class);

/**
* <p>Checks if the field isn't null and length of the field is greater than zero not
* including whitespace.</p>
*
* @param bean The bean - must implement Collection
* @param va The <code>ValidatorAction</code> that is currently being performed.
* @param field The <code>Field</code> object associated with the current field
* being validated.
* @param errors The <code>ActionErrors</code> object to add errors to if any
* validation errors occur.
* @param request Current request object.
*/
public static boolean validateMultiRowRequired(Object bean,
ValidatorAction va, Field field,
ActionErrors errors,
HttpServletRequest request) {


        boolean valid = true;
        // Need to iterate over a collection
        Collection coll = (Collection) bean;

for (Iterator i = coll.iterator(); i.hasNext();) {

            Object entry = (Object) i.next();
            if (!validateRequired(entry, va, field, errors, request))
                valid = false;

}

return valid;

}


/**
* <p>Checks if the field matches the regular expression in the field's mask attribute.</p>
*
* @param bean The bean - must implement collection
* @param va The <code>ValidatorAction</code> that is currently being performed.
* @param field The <code>Field</code> object associated with the current field
* being validated.
* @param errors The <code>ActionErrors</code> object to add errors to if any
* validation errors occur.
* @param request Current request object.
*/
public static boolean validateMultiRowMask(Object bean,
ValidatorAction va, Field field,
ActionErrors errors,
HttpServletRequest request) {


        boolean valid = true;
        // Need to iterate over a collection
        Collection coll = (Collection) bean;

for (Iterator i = coll.iterator(); i.hasNext();) {

            Object entry = (Object) i.next();
            if (!validateMask(entry, va, field, errors, request))
                valid = false;

}

return valid;

}


/**
* <p>Checks if the field can safely be converted to an int primitive.</p>
*
* @param bean The bean - must implement collection
* @param va The <code>ValidatorAction</code> that is currently being performed.
* @param field The <code>Field</code> object associated with the current field
* being validated.
* @param errors The <code>ActionErrors</code> object to add errors to if any
* validation errors occur.
* @param request Current request object.
*/
public static boolean validateMultiRowInteger(Object bean,
ValidatorAction va, Field field,
ActionErrors errors,
HttpServletRequest request) {


        boolean valid = true;
        // Need to iterate over a collection
        Collection coll = (Collection) bean;

for (Iterator i = coll.iterator(); i.hasNext();) {

            Object entry = (Object) i.next();
            if (validateInteger(entry, va, field, errors, request) != null)
                valid = false;

}

        return valid;
    }

/**
* <p>Checks if the field can safely be converted to a float primitive.</p>
*
* @param bean The bean - must implement collection
* @param va The <code>ValidatorAction</code> that is currently being performed.
* @param field The <code>Field</code> object associated with the current field
* being validated.
* @param errors The <code>ActionErrors</code> object to add errors to if any
* validation errors occur.
* @param request Current request object.
*/
public static boolean validateMultiRowFloat(Object bean,
ValidatorAction va, Field field,
ActionErrors errors,
HttpServletRequest request) {


        boolean valid = true;
        // Need to iterate over a collection
        Collection coll = (Collection) bean;

for (Iterator i = coll.iterator(); i.hasNext();) {

            Object entry = (Object) i.next();
            if (validateFloat(entry, va, field, errors, request) != null)
                valid = false;

}

return valid;

}

/**
* <p>Checks if a fields value is within a range (min &amp; max specified
* in the vars attribute).</p>
*
* @param bean The bean - must implement collection
* @param va The <code>ValidatorAction</code> that is currently being performed.
* @param field The <code>Field</code> object associated with the current field
* being validated.
* @param errors The <code>ActionErrors</code> object to add errors to if any
* validation errors occur.
* @param request Current request object.
*/
public static boolean validateMultiRowRange(Object bean,
ValidatorAction va, Field field,
ActionErrors errors,
HttpServletRequest request) {



boolean valid = true; // Need to iterate over a collection Collection coll = (Collection) bean;

for (Iterator i = coll.iterator(); i.hasNext();) {

            Object entry = (Object) i.next();
            if (!validateIntRange(entry, va, field, errors, request))


valid = false;


}

return valid;

}


/** * <p>Return <code>true</code> if the specified object is a String or * a <code>null</code> value.</p> * * @param o Object to be tested */ protected static boolean isString(Object o) {

        if (o == null) {
            return (true);
        }
        return (String.class.isInstance(o));

}


}



Also needded is attached valdation XMl that should be used in addition to other valdiation xmls. Let me know if you nned more suggestions, etc. for how we have gotten arround it.


hth,
.V

James Turner wrote:
Hi gang,
   Currently, the html:errors tag doesn't work well with
indexed properties, because it looks for an exact match on
the property name.  So if you have an error in
petFish[3].species, you need to have:
<html:errors property="petFish[3].species">

I'd like to propose (and will implement if people think it's
a good idea) two new things.

First off, doing <html:errors name="petFish"
property="species" indexed="true"> should match errors for
the current iteration values.

Secondly, doing <html:errors name="petFish"
property="species"> should match all errors for any
iteration.

James
<!--
  This file contains the multiRow validation rules.
  These mirror the standard rules located in validator-rules.xml,
  and are preceeded by "multiRow"
-->
<form-validation>
   <global>
      <validator name="multiRowRequired"
            classname="org.apache.scaffoldingXPress.base.MultiRowValidator"
               method="validateMultiRowRequired"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionErrors,
                       javax.servlet.http.HttpServletRequest"
                  msg="errors.required">

         <javascript><![CDATA[
            function validateMultiRowRequired(form) {
                var bValid = true;

                var j = 0;

                var focusField = null;
                var i = 0;
                var fields = new Array();
                oRequired = new multiRowRequired();
                for (x in oRequired) {

                    // MultiRowCode
                    var fieldName = oRequired[x][0];
                    var rowName = oRequired[x][2]("rowName");
                    var el = null;
                    var notNull = true;

                    for (j = 0; notNull && bValid; j++) {

                        el = form[rowName + "[" + j + "]." + fieldName];

                        if (el != null) {
                            if ((el.type == 'text' ||
                                el.type == 'textarea' ||
                                el.type == 'select-one' ||
                                el.type == 'radio' ||
                                el.type == 'password') &&
                                (el.value == '')) {
                                if (i == 0) {
                                    focusField = el;
                                }
                                fields[i++] = oRequired[x][1];
                                bValid = false;
                            }
                        } else {
                            notNull = false;
                        }
                    }
                }
                if (fields.length > 0) {
                   focusField.focus();
                   alert(fields.join('\n'));
                }
                return bValid;
            }]]>
         </javascript>

      </validator>


      <validator name="multiRowMask"
            classname="org.apache.scaffoldingXPress.base.MultiRowValidator"
               method="validateMultiRowMask"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionErrors,
                       javax.servlet.http.HttpServletRequest"
              depends="multiRowRequired"
                  msg="errors.invalid">

         <javascript><![CDATA[
            function validateMultiRowMask(form) {
                var bValid = true;
 
                var j = 0;

                var focusField = null;
                var i = 0;
                var fields = new Array();
                oMasked = new multiRowMask();
                for (x in oMasked) {

                    // MultiRowCode
                    var fieldName = oMasked[x][0];
                    var rowName = oMasked[x][2]("rowName");
                    var el = null;
                    var notNull = true;

                    for (j = 0; notNull && bValid; j++) {

                        el = form[rowName + "[" + j + "]." + fieldName];

                        if (el != null) {

                            if ((el.type == 'text' ||
                                 el.type == 'textarea' ||
                                 el.type == 'password') &&
                                (el.value.length > 0)) {
                                if (!matchPattern(el.value, oMasked[x][2]("mask"))) {
                                    if (i == 0) {
                                        focusField = el;
                                    }
                                    fields[i++] = oMasked[x][1];
                                    bValid = false;
                                }
                            }
                        } else {
                            notNull = false;
                        }
                    }
                }
                if (fields.length > 0) {
                   focusField.focus();
                   alert(fields.join('\n'));
                }
                return bValid;
            }

            function matchPattern(value, mask) {
               var bMatched = mask.exec(value);
               if (!bMatched) {
                   return false;
               }
               return true;
            }]]>
         </javascript>

      </validator>



      <validator name="multiRowInteger"
            classname="org.apache.scaffoldingXPress.base.MultiRowValidator"
               method="validateMultiRowInteger"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionErrors,
                       javax.servlet.http.HttpServletRequest"
              depends="multiRowRequired"
                  msg="errors.integer"
       jsFunctionName="multiRowIntegerValidations">

         <javascript><![CDATA[
            function validateMultiRowInteger(form) {
                var bValid = true;
 
                var j = 0;

                var focusField = null;
                var i = 0;
                var fields = new Array();
                oInteger = new multiRowIntegerValidations();
                for (x in oInteger) {

                    // MultiRowCode
                    var fieldName = oInteger[x][0];
                    var rowName = oInteger[x][2]("rowName");
                    var el = null;
                    var notNull = true;

                    for (j = 0; notNull && bValid; j++) {

                        el = form[rowName + "[" + j + "]." + fieldName];

                        if (el != null) {

                            if ((el.type == 'text' ||
                                 el.type == 'textarea' ||
                                 el.type == 'select-one' ||
                                 el.type == 'radio') &&
                                (el.value.length > 0)) {
                                 var iValue = parseInt(el.value);
                                 if (isNaN(iValue) || !(iValue >= -2147483648 && iValue <= 2147483647)) {
                                     if (i == 0) {
                                         focusField = el;
                                     }
                                     fields[i++] = oInteger[x][1];
                                     bValid = false;
                                 }
                             }
                        } else {
                            notNull = false;
                        }
                    }
                }
                if (fields.length > 0) {
                   focusField.focus();
                   alert(fields.join('\n'));
                }
                return bValid;
            }]]>
         </javascript>

      </validator>


      <validator name="multiRowFloat"
            classname="org.apache.scaffoldingXPress.base.MultiRowValidator"
               method="validateMultiRowFloat"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionErrors,
                       javax.servlet.http.HttpServletRequest"
              depends="multiRowRequired"
                  msg="errors.float"
       jsFunctionName="multiRowFloatValidations">

         <javascript><![CDATA[
            function validateMultiRowFloat(form) {
                var bValid = true;
 
                var j = 0;

                var focusField = null;
                var i = 0;
                var fields = new Array();
                oFloat = new multiRowFloatValidations();
                for (x in oFloat) {

                    // MultiRowCode
                    var fieldName = oFloat[x][0];
                    var rowName = oFloat[x][2]("rowName");
                    var el = null;
                    var notNull = true;

                    for (j = 0; notNull && bValid; j++) {
 
                        el = form[rowName + "[" + j + "]." + fieldName];

                        if (el != null) {

                            if ((el.type == 'text' ||
                                 el.type == 'textarea' ||
                                 el.type == 'select-one' ||
                                 el.type == 'radio') &&
                                (el.value.length > 0)) {
                                 var iValue = parseFloat(el.value);
                                 if (isNaN(iValue)) {
                                     if (i == 0) {
                                         focusField = el;
                                     }
                                     fields[i++] = oFloat[x][1];
                                     bValid = false;
                                 }
                             }
                         } else {
                             notNull = false;
                         }
                    }
                }
                if (fields.length > 0) {
                   focusField.focus();
                   alert(fields.join('\n'));
                }
                return bValid;
            }]]>
         </javascript>

      </validator>



      <validator name="multiRowRange"
            classname="org.apache.scaffoldingXPress.base.MultiRowValidator"
               method="validateMultiRowRange"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionErrors,
                       javax.servlet.http.HttpServletRequest"
              depends="multiRowRequired,multiRowIteger"
                  msg="errors.range">

         <javascript><![CDATA[
            function validateMultiRowRange(form) {
                var bValid = true;
 
                var j = 0;

                var focusField = null;
                var i = 0;
                var fields = new Array();
                oRange = new multiRowRange();
                for (x in oRange) {

                    // MultiRowCode
                    var fieldName = oRange[x][0];
                    var rowName = oRange[x][2]("rowName");
                    var el = null;
                    var notNull = true;

                    for (j = 0; notNull && bValid; j++) {

                        el = form[rowName + "[" + j + "]." + fieldName];

                        if (el != null) {

                            if ((el.type == 'text' ||
                                 el.type == 'textarea') &&
                                (el.value.length > 0)) {
                                var iMin = parseInt(oRange[x][2]("min"));
                                var iMax = parseInt(oRange[x][2]("max"));
                                var iValue = parseInt(el.value);
                                if (!(iValue >= iMin && iValue <= iMax)) {
                                    if (i == 0) {
                                        focusField = el;
                                    }
                                    fields[i++] = oRange[x][1];
                                    bValid = false;
                                }
                            }
                        } else {
                            notNull = false;
                        }             
                    }
                }
                if (fields.length > 0) {
                    focusField.focus();
                    alert(fields.join('\n'));
                }
                return bValid;
            }]]>
         </javascript>
      </validator>
   </global>

</form-validation>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to