Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Regular Expression help for limitting ranges

Participant ,
Feb 05, 2016 Feb 05, 2016

Hi, I am working on making a text field limited to dates, this is just a portion of the code. I already have validation of dates, but I am now trying to limit what the user enters by using a regular expression. This code works slightly however, it doesn't limit me for example I can enter in more than 2 digits but then it limits based on the total allowed so for example 8 digits are allowed if I just type. I need it to stop after the first 2 digits then have a - then 2 more digits then a - and then followed by 4 digits. I've tried limited each section and grouping as well. Any help would be greatly appreciated. Thanks.

This is in the format code and I am calling it in Keystroke.

function DateKS (){

var value = AFMergeChange(event);

if (!event.willCommit) {

        // Only allow characters that match the regular expression

        event.rc = /^([0]{0,1}[1-9]{0,1}|[1]{0,1}[012]{0,1})([-]{0,1})([0]{0,1}[1-9]{0,1}|[12]{0,1}[0-9]{0,1}|[3]{0,1}[01]{0,1})([-]{0,1})([0-9]{0,4})$/.test(value);

    }

}

TOPICS
Acrobat SDK and JavaScript
2.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Participant , Feb 09, 2016 Feb 09, 2016

I decided the check for 100 and 400 wasn't needed since that occurance only happens every 400 years. But I did work on it further and modified it even more. Here's my working code.

function isLeapYear(year) {
    return year % 4 === 0;
}

function checkDaysInMonth(month, day, year) {
    var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    if (month === 2) {
        if (isLeapYear(year)) {
            daysInMonth[1] += 1;
        }
    }

    return daysInMonth[month - 1] >= day;
}

function

...
Translate
LEGEND ,
Feb 05, 2016 Feb 05, 2016

I see nothing you code that inserting the separation character into the data being entered.

Life is much simpler and easier if you utilize the built-in features of Acrobat. I would work with setting the field format as needed and then using other built-in features as needed with other actions within the form.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 05, 2016 Feb 05, 2016

can you give an example please. I am choosing to do it this way because I need my date field to be more strict than the standard built in one.

Here is all of my code:

function DateKS (){

var value = AFMergeChange(event);

if (!event.willCommit) {

        // Only allow characters that match the regular expression

        event.rc = /^([0]{0,1}[1-9]{0,1}|[1]{0,1}[012]{0,1})([-]{0,1})([0]{0,1}[1-9]{0,1}|[12]{0,1}[0-9]{0,1}|[3]{0,1}[01]{0,1})([-]{0,1})([0-9]{0,4})$/.test(value);

    }

}

function checkDate() {

    var minYear = 2015;

    var maxYear = (new Date()).getFullYear();

    var value = AFMergeChange(event);

    var errorMsg = "";

    // regular expression to match required date format

    var re = /^(\d{2})-(\d{2})-(\d{4})$/;

    if (value != '') {

      if (regs = value.match(re)) {

        if(regs[2] < 1 || regs[2] > 31) {

          errorMsg = "Invalid value for day: " + regs[2];

        } else if(regs[1] < 1 || regs[1] > 12) {

          errorMsg = "Invalid value for month: " + regs[1];

        } else if(regs[3] < minYear || regs[3] > maxYear) {

          errorMsg = "Invalid value for year: " + regs[3] + " - must be between " + minYear + " and " + maxYear;

        }

      } else {

        errorMsg = "Invalid date format: " + value + "\r\n" + "Please use format: mm-dd-yyyy";

      }

    }

    if(event.willCommit && errorMsg != "") {

      app.alert(errorMsg, 0, 0, "Error");

      this.getField('Received_Date').setFocus();

event.value = "";

      return false;

    }

    return true;

  }

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

Okay so I got it working correctly now. But does anyone know how I can add leap year validation into my code? This would be a great addition to what I've already have. Thanks.

function checkReceivedDate() {
    var minYear = (new Date()).getFullYear() - 1;
    var maxYear = (new Date()).getFullYear();
    var value = AFMergeChange(event);
    var errorMsg = "";

    // regular expression to match required date format
    var re = /^(\d{2})-(\d{2})-(\d{4})$/;

    // skip check if value is empty, since this field is not required
    if (!value) {
        return;
    }

    if (event.willCommit) {
        if (regs = value.match(re)) {
            if (regs[1] < 1 || regs[1] > 12) {
                errorMsg = "Invalid value for month: " + regs[1];
            } else if (regs[2] < 1 || regs[2] > 31) {
                errorMsg = "Invalid value for day: " + regs[2];
            } else if (regs[3] < minYear || regs[3] > maxYear) {
                errorMsg = "Invalid value for year: " + regs[3] + " - must be between " + minYear + " and " + maxYear;
            }
        } else {
            errorMsg = "Invalid date format: " + value + "\r\n" + "Please use format: mm-dd-yyyy";
        }

        if (errorMsg) {
            app.alert(errorMsg, 0, 0, "Error");
            event.value = "";

            return false;
        }
    } else {
        // Only allow characters that match the regular expression
        //event.rc = /^(?:0[1-9]?|1[012]?)?-?(?:0[1-9]?|[12][0-9]?|3[01]?)?-?2?0?[0-9]{0,2}$/.test(value);
        event.rc = /^\d{0,2}-?\d{0,2}-?\d{0,4}$/.test(value);
    }

    return true;
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

I've added this to the code for leap year, but does this account for all leap years or will it still be missing some?

var February = "29";


            } else if ((regs[3]%100)&&(regs[1] == "02") && (regs[2] > February)){

                errorMsg = "Invalid value for day: " + regs[2] + "\r\n" + "This year is a leap year, February has 29 days.";

            } else if ((regs[1] == "02") && (regs[2] > February-1)){

                errorMsg = "Invalid value for day: " + regs[2] + "\r\n" + "February only has 28 days.";

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

I think you need to re-think your approach to this. When dealing with dates you should be using the Date objects. Trying to validate dates based just on their numbers is very tricky (as you've seen) and complex. Why re-invent the wheel when you already have a mechanism that allows you to easily verify the validity of a date string?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

This is for work and the generic date validation breaks since it is too flexible. This form I am making correspondes with an automated program. Dates need to be strict and ridged not flexible. The generic allows users to enter dates like this 010-10-2016 and it accepts it. I can not have that.

My date validation works, I am just trying to add leap year in to the mix. If you could help instead of harp on using the generic one that would be great. Thanks.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

Here's the logic behind it. You just need to convert it to a simple function and you're done: Leap year - Wikipedia, the free encyclopedia

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

Am I doing this incorrectly? I keep getting an syntax error "missing ) in parenthetical

if ((regs[3]%100 && regs[3]!/400) && (regs[1] == "02" && regs[2] > February)){

                errorMsg = "Invalid value for day: " + regs[2] + "\r\n" + "This is a leap year. February has 29 days.";

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

This is not a valid statement: regs[2] > February

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016


I have a var statement for February.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

But it's a string, not a number. You can't use the ">" on it.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

so even if I set the var like this

var February = "29";

that method of using > wouldn't work? I thought it would since I set it to a number. I don't seem to have an issue with my other code that follows.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

If it has quotes around it, it's a string.

If you want it to be a number remove the quotes.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

I figured out the issue with this portion of code

if ((regs[3]%100 && regs[3]!/400) && (regs[1] == "02" && regs[2] > February)){

                errorMsg = "Invalid value for day: " + regs[2] + "\r\n" + "This is a leap year. February has 29 days.";

it is the !/ that is causing an issue. How do I put into javascript that regs[3] is not divisible by 400?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

Just like you did with 100... If the result of X mod 400 is zero then X is divisible by 400.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

So write it like this then? since I don't want that to be divisible it would be ==1 correct?

if ((regs[3]%100 && regs[3]%400==1) && (regs[1] == "02" && regs[2] > February)){

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

No, it could be anything between 1 and 399... So just compare it to zero instead.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

Anyway, unless this form is going to be used for past dates, or up until the year 2400, this isn't really an issue...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

You can probably also skip the test for years divisible by 100 using the same logic...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

Can you give an example of what you mean by compare to 0?

Yes, I know, but I always like to make my code as solid as possible.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

var x = 1000;

if (x%100==0) app.alert("X is divisible by 100.");

else app.alert("X is NOT divisible by 100.");

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

I see, but is there no way I can do that without using a var? I want to do it directly in the if statement saying if regs[3] is divisible from 100 and if regs[3] is not divisible by 400

if ((regs[3]%100 && regs[3]%400) && (regs[1] == "02" && regs[2] > February)){

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2016 Feb 08, 2016

Of course you can do it without using a declared variable. However, you might need to convert the items in your array to Numbers first. And it's also a good idea to explicitly add the comparison, like this:

if (((Number(regs[3])%100)==0 && ((Number(regs[3])%400))==0 && regs[1] == "02" && regs[2] > February){

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2016 Feb 08, 2016

I worked around the issue and modified the code. Seems to be working now. Thanks for all the help.

function checkReceivedDate() {
    var minYear = (new Date()).getFullYear() - 30;
    var maxYear = (new Date()).getFullYear();
    var value = AFMergeChange(event);
    var errorMsg = "";
    var February = 29;

    // regular expression to match required date format
    var re = /^(\d{2})-(\d{2})-(\d{4})$/;

    // skip check if value is empty, since this field is not required
    if (!value) {
        return;
    }

    if (event.willCommit) {
        if (regs = value.match(re)) {
            if ((regs[1] == "02") && (regs[2] > February)&&(regs[3]%4==0)){
                errorMsg = "Invalid value for day: " + regs[2] + "\r\n" + "February only has 29 days since the year" + regs[3] + " is a leap year.";

            } else if ((regs[3]%4)&&(regs[1] == "02") && (regs[2] > February-1)){
                errorMsg = "Invalid value for day: " + regs[2] + "\r\n" + "February only has 28 days in the year " + regs[3];

}
            if (regs[1] < 1 || regs[1] > 12) {
                errorMsg = "Invalid value for month: " + regs[1];
            } else if (regs[2] < 1 || regs[2] > 31) {
                errorMsg = "Invalid value for day: " + regs[2];
            } else if (regs[3] < minYear || regs[3] > maxYear) {
                errorMsg = "Invalid value for year: " + regs[3] + " - must be between " + minYear + " and " + maxYear;
            }
        } else {
            errorMsg = "Invalid date format: " + value + "\r\n" + "Please use format: mm-dd-yyyy";
        }

        if (errorMsg) {
            app.alert(errorMsg, 0, 0, "Error");
            event.value = "";

            return false;
        }
    } else {
        // Only allow characters that match the regular expression
        //event.rc = /^(?:0[1-9]?|1[012]?)?-?(?:0[1-9]?|[12][0-9]?|3[01]?)?-?2?0?[0-9]{0,2}$/.test(value);
        event.rc = /^\d{0,2}-?\d{0,2}-?\d{0,4}$/.test(value);
    }

    return true;
}


Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines