Commons Validator
  1. Commons Validator
  2. VALIDATOR-32

[validator] datePattern not supported by JavaScript

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.1.0 (alpha)
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

      Description

      datePattern and datePatternStrict are picked up by the Java side, but only
      datePatternStrict is picked up by the JavaScript. Entering datePattern as part
      of your validation will result in a JavaScript error on the client.

        Activity

        Hide
        Nick Sydenham added a comment -

        Created an attachment (id=7824)
        Check for null datePatternStrict

        Show
        Nick Sydenham added a comment - Created an attachment (id=7824) Check for null datePatternStrict
        Hide
        derek added a comment -

        This patch fixes it on my stuff:

            • validator-rules.xml.orig 2003-09-26 10:32:05.000000000 -0600
            • validator-rules.xml 2003-09-26 10:32:27.000000000 -0600
              ***************
            • 615,618 ****
            • 615,621 ----
              var value = form[oDate[x][0]].value;
              var datePattern = oDate[x][2]("datePatternStrict");
              + // try loose pattern
              + if (datePattern == null)
              + datePattern = oDate[x][2]("datePattern");
              if ((form[oDate[x][0]].type == 'text' ||
              form[oDate[x][0]].type == 'textarea') &&
        Show
        derek added a comment - This patch fixes it on my stuff: validator-rules.xml.orig 2003-09-26 10:32:05.000000000 -0600 validator-rules.xml 2003-09-26 10:32:27.000000000 -0600 *************** 615,618 **** 615,621 ---- var value = form[oDate [x] [0] ].value; var datePattern = oDate [x] [2] ("datePatternStrict"); + // try loose pattern + if (datePattern == null) + datePattern = oDate [x] [2] ("datePattern"); if ((form[oDate [x] [0] ].type == 'text' || form[oDate [x] [0] ].type == 'textarea') &&
        Hide
        Robert Leland added a comment -

        This should stay opened until it is fixed in the source code.

        Show
        Robert Leland added a comment - This should stay opened until it is fixed in the source code.
        Hide
        Robert Leland added a comment -

        Fixed in the Sept 27 Nightly build.
        Thanks for the patch !

        -Rob

        Show
        Robert Leland added a comment - Fixed in the Sept 27 Nightly build. Thanks for the patch ! -Rob
        Hide
        Hanson Char added a comment -

        The patch only fixed part of the problem. The regular expression used when
        "datePattern" is selected is still incorrect.

        The patch should be something like:
        ...
        var isStrict = true
        var datePattern = oDate[x][2]("datePatternStrict");

        if (datePattern == null)

        { datePattern = oDate[x][2]("datePattern") isStrict = false }
        ...

        dateRegexp = isStrict
        ? new RegExp("^(\\d{2})(
        d{2})(
        d{4})$")
        : new RegExp("^(\\d{1,2})(
        d{1,2})(
        d{4})$")
        ....

        The replacement script for the entire "date" validator is given here:

        <validator name="date"
        classname="org.apache.struts.validator.FieldChecks"
        method="validateDate"
        methodParams="java.lang.Object,
        org.apache.commons.validator.ValidatorAction,
        org.apache.commons.validator.Field,
        org.apache.struts.action.ActionErrors,
        javax.servlet.http.HttpServletRequest"
        depends=""
        msg="errors.date"
        jsFunctionName="DateValidations">

        <javascript><![CDATA[
        function validateDate(form) {
        var bValid = true;
        var focusField = null;
        var i = 0;
        var fields = new Array();
        oDate = new DateValidations();
        for (x in oDate) {
        var value = form[oDate[x][0]].value;
        var isStrict = true
        var datePattern = oDate[x][2]("datePatternStrict");

        if (datePattern == null) { datePattern = oDate[x][2]("datePattern") isStrict = false }

        if ((form[oDate[x][0]].type == 'text' ||
        form[oDate[x][0]].type == 'textarea') &&
        (value.length > 0) &&
        (datePattern.length > 0)) {
        var MONTH = "MM";
        var DAY = "dd";
        var YEAR = "yyyy";
        var orderMonth = datePattern.indexOf(MONTH);
        var orderDay = datePattern.indexOf(DAY);
        var orderYear = datePattern.indexOf(YEAR);
        if ((orderDay < orderYear && orderDay > orderMonth)) {
        var iDelim1 = orderMonth + MONTH.length;
        var iDelim2 = orderDay + DAY.length;
        var delim1 = datePattern.substring(iDelim1, iDelim1 + 1);
        var delim2 = datePattern.substring(iDelim2, iDelim2 + 1);
        if (iDelim1 == orderDay && iDelim2 == orderYear) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})(
        d{2}

        )(
        d

        {4})$")
        : new RegExp("^(\\d{1,2})(
        d{1,2})(
        d{4}

        )$")
        } else if (iDelim1 == orderDay) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})(
        d{2}

        )[" + delim2 +
        "](
        d

        {4})$")
        : new RegExp("^(
        d{1,2})(
        d{1,2})[" + delim2
        + "](
        d{4}

        )$")
        } else if (iDelim2 == orderYear) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})[" + delim1 +
        "](
        d{2}

        )(
        d

        {4})$")
        : new RegExp("^(\\d{1,2})[" + delim1 +
        "](
        d{1,2})(
        d{4}

        )$")

        } else {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})[" + delim1 +
        "](
        d{2}

        )[" + delim2 + "](
        d

        {4})$")
        : new RegExp("^(\\d{1,2})[" + delim1 +
        "](
        d{1,2})[" + delim2 + "](
        d{4}

        )$")
        }
        var matched = dateRegexp.exec(value);
        if(matched != null) {
        if (!isValidDate(matched[2], matched[1], matched[3])) {
        if (i == 0)

        { focusField = form[oDate[x][0]]; }

        fields[i++] = oDate[x][1];
        bValid = false;
        }
        } else {
        if (i == 0)

        { focusField = form[oDate[x][0]]; }

        fields[i++] = oDate[x][1];
        bValid = false;
        }
        } else if ((orderMonth < orderYear && orderMonth > orderDay)) {
        var iDelim1 = orderDay + DAY.length;
        var iDelim2 = orderMonth + MONTH.length;
        var delim1 = datePattern.substring(iDelim1, iDelim1 + 1);
        var delim2 = datePattern.substring(iDelim2, iDelim2 + 1);
        if (iDelim1 == orderMonth && iDelim2 == orderYear) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})(
        d{2}

        )(
        d

        {4})$")
        : new RegExp("^(\\d{1,2})(
        d{1,2})(
        d{4}

        )$")
        } else if (iDelim1 == orderMonth) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})(
        d{2}

        )[" + delim2 +
        "](
        d

        {4})$")
        : new RegExp("^(
        d{1,2})(
        d{1,2})[" + delim2 +
        "](
        d{4}

        )$")
        } else if (iDelim2 == orderYear) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})[" + delim1 +
        "](
        d{2}

        )(
        d

        {4})$")
        : new RegExp("^(\\d{1,2})[" + delim1 +
        "](
        d{1,2})(
        d{4}

        )$")
        } else {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {2})[" + delim1 +
        "](
        d{2}

        )[" + delim2 + "](
        d

        {4})$")
        : new RegExp("^(\\d{1,2})[" + delim1 +
        "](
        d{1,2})[" + delim2 + "](
        d{4}

        )$")
        }
        var matched = dateRegexp.exec(value);
        if(matched != null) {
        if (!isValidDate(matched[1], matched[2], matched[3])) {
        if (i == 0)

        { focusField = form[oDate[x][0]]; }

        fields[i++] = oDate[x][1];
        bValid = false;
        }
        } else {
        if (i == 0)

        { focusField = form[oDate[x][0]]; }

        fields[i++] = oDate[x][1];
        bValid = false;
        }
        } else if ((orderMonth > orderYear && orderMonth < orderDay)) {
        var iDelim1 = orderYear + YEAR.length;
        var iDelim2 = orderMonth + MONTH.length;
        var delim1 = datePattern.substring(iDelim1, iDelim1 + 1);
        var delim2 = datePattern.substring(iDelim2, iDelim2 + 1);
        if (iDelim1 == orderMonth && iDelim2 == orderDay) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {4})(
        d{2})(
        d{2})$")
        : new RegExp("^(
        d{4}

        )(
        d

        {1,2})(
        d{1,2}

        )$")
        } else if (iDelim1 == orderMonth) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {4})(
        d{2})[" + delim2 +
        "](
        d{2})$")
        : new RegExp("^(
        d{4}

        )(
        d

        {1,2})[" + delim2 +
        "](
        d{1,2}

        )$")
        } else if (iDelim2 == orderDay) {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {4})[" + delim1 +
        "](
        d{2})(
        d{2})$")
        : new RegExp("^(
        d{4}

        )[" + delim1 +
        "](
        d

        {1,2})(
        d{1,2}

        )$")
        } else {
        dateRegexp = isStrict
        ? new RegExp("^(
        d

        {4})[" + delim1 +
        "](
        d{2})[" + delim2 + "](
        d{2})$")
        : new RegExp("^(
        d{4}

        )[" + delim1 +
        "](
        d

        {1,2})[" + delim2 + "](
        d{1,2}

        )$")
        }
        var matched = dateRegexp.exec(value);
        if(matched != null) {
        if (!isValidDate(matched[3], matched[2], matched[1])) {
        if (i == 0)

        { focusField = form[oDate[x][0]]; }

        fields[i++] = oDate[x][1];
        bValid = false;
        }
        } else {
        if (i == 0)

        { focusField = form[oDate[x][0]]; }

        fields[i++] = oDate[x][1];
        bValid = false;
        }
        } else {
        if (i == 0)

        { focusField = form[oDate[x][0]]; }

        fields[i++] = oDate[x][1];
        bValid = false;
        }
        }
        }
        if (fields.length > 0)

        { focusField.focus(); alert(fields.join('\n')); }

        return bValid;
        }

        function isValidDate(day, month, year) {
        if (month < 1 || month > 12)

        { return false; }
        if (day < 1 || day > 31) { return false; }

        if ((month == 4 || month == 6 || month == 9 || month == 11) &&
        (day == 31))

        { return false; }

        if (month == 2) {
        var leap = (year % 4 == 0 &&
        (year % 100 != 0 || year % 400 == 0));
        if (day>29 || (day == 29 && !leap))

        { return false; }

        }
        return true;
        }]]>
        </javascript>
        </validator>

        Show
        Hanson Char added a comment - The patch only fixed part of the problem. The regular expression used when "datePattern" is selected is still incorrect. The patch should be something like: ... var isStrict = true var datePattern = oDate [x] [2] ("datePatternStrict"); if (datePattern == null) { datePattern = oDate[x][2]("datePattern") isStrict = false } ... dateRegexp = isStrict ? new RegExp("^(\\d{2})( d{2})( d{4})$") : new RegExp("^(\\d{1,2})( d{1,2})( d{4})$") .... The replacement script for the entire "date" validator is given here: <validator name="date" classname="org.apache.struts.validator.FieldChecks" method="validateDate" methodParams="java.lang.Object, org.apache.commons.validator.ValidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.ActionErrors, javax.servlet.http.HttpServletRequest" depends="" msg="errors.date" jsFunctionName="DateValidations"> <javascript><![CDATA[ function validateDate(form) { var bValid = true; var focusField = null; var i = 0; var fields = new Array(); oDate = new DateValidations(); for (x in oDate) { var value = form[oDate [x] [0] ].value; var isStrict = true var datePattern = oDate [x] [2] ("datePatternStrict"); if (datePattern == null) { datePattern = oDate[x][2]("datePattern") isStrict = false } if ((form[oDate [x] [0] ].type == 'text' || form[oDate [x] [0] ].type == 'textarea') && (value.length > 0) && (datePattern.length > 0)) { var MONTH = "MM"; var DAY = "dd"; var YEAR = "yyyy"; var orderMonth = datePattern.indexOf(MONTH); var orderDay = datePattern.indexOf(DAY); var orderYear = datePattern.indexOf(YEAR); if ((orderDay < orderYear && orderDay > orderMonth)) { var iDelim1 = orderMonth + MONTH.length; var iDelim2 = orderDay + DAY.length; var delim1 = datePattern.substring(iDelim1, iDelim1 + 1); var delim2 = datePattern.substring(iDelim2, iDelim2 + 1); if (iDelim1 == orderDay && iDelim2 == orderYear) { dateRegexp = isStrict ? new RegExp("^( d {2})( d{2} )( d {4})$") : new RegExp("^(\\d{1,2})( d{1,2})( d{4} )$") } else if (iDelim1 == orderDay) { dateRegexp = isStrict ? new RegExp("^( d {2})( d{2} )[" + delim2 + "]( d {4})$") : new RegExp("^( d{1,2})( d{1,2})[" + delim2 + "]( d{4} )$") } else if (iDelim2 == orderYear) { dateRegexp = isStrict ? new RegExp("^( d {2})[" + delim1 + "]( d{2} )( d {4})$") : new RegExp("^(\\d{1,2})[" + delim1 + "]( d{1,2})( d{4} )$") } else { dateRegexp = isStrict ? new RegExp("^( d {2})[" + delim1 + "]( d{2} ) [" + delim2 + "] ( d {4})$") : new RegExp("^(\\d{1,2})[" + delim1 + "]( d{1,2}) [" + delim2 + "] ( d{4} )$") } var matched = dateRegexp.exec(value); if(matched != null) { if (!isValidDate(matched [2] , matched [1] , matched [3] )) { if (i == 0) { focusField = form[oDate[x][0]]; } fields [i++] = oDate [x] [1] ; bValid = false; } } else { if (i == 0) { focusField = form[oDate[x][0]]; } fields [i++] = oDate [x] [1] ; bValid = false; } } else if ((orderMonth < orderYear && orderMonth > orderDay)) { var iDelim1 = orderDay + DAY.length; var iDelim2 = orderMonth + MONTH.length; var delim1 = datePattern.substring(iDelim1, iDelim1 + 1); var delim2 = datePattern.substring(iDelim2, iDelim2 + 1); if (iDelim1 == orderMonth && iDelim2 == orderYear) { dateRegexp = isStrict ? new RegExp("^( d {2})( d{2} )( d {4})$") : new RegExp("^(\\d{1,2})( d{1,2})( d{4} )$") } else if (iDelim1 == orderMonth) { dateRegexp = isStrict ? new RegExp("^( d {2})( d{2} )[" + delim2 + "]( d {4})$") : new RegExp("^( d{1,2})( d{1,2})[" + delim2 + "]( d{4} )$") } else if (iDelim2 == orderYear) { dateRegexp = isStrict ? new RegExp("^( d {2})[" + delim1 + "]( d{2} )( d {4})$") : new RegExp("^(\\d{1,2})[" + delim1 + "]( d{1,2})( d{4} )$") } else { dateRegexp = isStrict ? new RegExp("^( d {2})[" + delim1 + "]( d{2} ) [" + delim2 + "] ( d {4})$") : new RegExp("^(\\d{1,2})[" + delim1 + "]( d{1,2}) [" + delim2 + "] ( d{4} )$") } var matched = dateRegexp.exec(value); if(matched != null) { if (!isValidDate(matched [1] , matched [2] , matched [3] )) { if (i == 0) { focusField = form[oDate[x][0]]; } fields [i++] = oDate [x] [1] ; bValid = false; } } else { if (i == 0) { focusField = form[oDate[x][0]]; } fields [i++] = oDate [x] [1] ; bValid = false; } } else if ((orderMonth > orderYear && orderMonth < orderDay)) { var iDelim1 = orderYear + YEAR.length; var iDelim2 = orderMonth + MONTH.length; var delim1 = datePattern.substring(iDelim1, iDelim1 + 1); var delim2 = datePattern.substring(iDelim2, iDelim2 + 1); if (iDelim1 == orderMonth && iDelim2 == orderDay) { dateRegexp = isStrict ? new RegExp("^( d {4})( d{2})( d{2})$") : new RegExp("^( d{4} )( d {1,2})( d{1,2} )$") } else if (iDelim1 == orderMonth) { dateRegexp = isStrict ? new RegExp("^( d {4})( d{2})[" + delim2 + "]( d{2})$") : new RegExp("^( d{4} )( d {1,2})[" + delim2 + "]( d{1,2} )$") } else if (iDelim2 == orderDay) { dateRegexp = isStrict ? new RegExp("^( d {4})[" + delim1 + "]( d{2})( d{2})$") : new RegExp("^( d{4} )[" + delim1 + "]( d {1,2})( d{1,2} )$") } else { dateRegexp = isStrict ? new RegExp("^( d {4})[" + delim1 + "]( d{2}) [" + delim2 + "] ( d{2})$") : new RegExp("^( d{4} )[" + delim1 + "]( d {1,2}) [" + delim2 + "] ( d{1,2} )$") } var matched = dateRegexp.exec(value); if(matched != null) { if (!isValidDate(matched [3] , matched [2] , matched [1] )) { if (i == 0) { focusField = form[oDate[x][0]]; } fields [i++] = oDate [x] [1] ; bValid = false; } } else { if (i == 0) { focusField = form[oDate[x][0]]; } fields [i++] = oDate [x] [1] ; bValid = false; } } else { if (i == 0) { focusField = form[oDate[x][0]]; } fields [i++] = oDate [x] [1] ; bValid = false; } } } if (fields.length > 0) { focusField.focus(); alert(fields.join('\n')); } return bValid; } function isValidDate(day, month, year) { if (month < 1 || month > 12) { return false; } if (day < 1 || day > 31) { return false; } if ((month == 4 || month == 6 || month == 9 || month == 11) && (day == 31)) { return false; } if (month == 2) { var leap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); if (day>29 || (day == 29 && !leap)) { return false; } } return true; }]]> </javascript> </validator>
        Hide
        Hanson Char added a comment -

        As a general comment, most if not all of the semi-colon's in the javascript are
        unncessary and should be removed to reduce the payload.

        Show
        Hanson Char added a comment - As a general comment, most if not all of the semi-colon's in the javascript are unncessary and should be removed to reduce the payload.
        Hide
        Martin Cooper added a comment -

        The semi-colons should absolutely not be removed. They may "reduce the payload"
        minimally, but if someone uses a whitespace compressor on the code, it would
        completely break it.

        Show
        Martin Cooper added a comment - The semi-colons should absolutely not be removed. They may "reduce the payload" minimally, but if someone uses a whitespace compressor on the code, it would completely break it.
        Hide
        Hanson Char added a comment -

        Which browser currently uses such "whitespace compressor" ? Sound like more a
        compressor problem, which should then add in the necessary semi-colons.

        Show
        Hanson Char added a comment - Which browser currently uses such "whitespace compressor" ? Sound like more a compressor problem, which should then add in the necessary semi-colons.
        Hide
        Martin Cooper added a comment -

        Browsers don't use whitespace compressors. Why would they? The point is to
        reduce the network load in getting the JavaScript to the browser in the first
        place.

        Sure, you could ask all of the whitespace compressor developers to fix their
        code to handle missing semi-colons. But I think we're going to have a much
        easier time fixing the code under our control rather than the code we don't
        have any influence over.

        Show
        Martin Cooper added a comment - Browsers don't use whitespace compressors. Why would they? The point is to reduce the network load in getting the JavaScript to the browser in the first place. Sure, you could ask all of the whitespace compressor developers to fix their code to handle missing semi-colons. But I think we're going to have a much easier time fixing the code under our control rather than the code we don't have any influence over.
        Hide
        Don Brown added a comment -

        Moving to commons-validator

        Show
        Don Brown added a comment - Moving to commons-validator
        Hide
        Don Brown added a comment -

        Moving to commons-validator

        Show
        Don Brown added a comment - Moving to commons-validator
        Hide
        Don Brown added a comment -

        Fixed in revision [239517]. Thanks Hanson for the patch!

        Show
        Don Brown added a comment - Fixed in revision [239517] . Thanks Hanson for the patch!
        Hide
        Don Brown added a comment -
            • COM-1661 has been marked as a duplicate of this bug. ***
        Show
        Don Brown added a comment - COM-1661 has been marked as a duplicate of this bug. ***

          People

          • Assignee:
            Unassigned
            Reporter:
            Nick Sydenham
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development