Copy link to clipboard
Copied
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);
}
}
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
...Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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.";
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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.";
Copy link to clipboard
Copied
This is not a valid statement: regs[2] > February
Copy link to clipboard
Copied
I have a var statement for February.
Copy link to clipboard
Copied
But it's a string, not a number. You can't use the ">" on it.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
If it has quotes around it, it's a string.
If you want it to be a number remove the quotes.
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
Just like you did with 100... If the result of X mod 400 is zero then X is divisible by 400.
Copy link to clipboard
Copied
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)){
Copy link to clipboard
Copied
No, it could be anything between 1 and 399... So just compare it to zero instead.
Copy link to clipboard
Copied
Anyway, unless this form is going to be used for past dates, or up until the year 2400, this isn't really an issue...
Copy link to clipboard
Copied
You can probably also skip the test for years divisible by 100 using the same logic...
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
var x = 1000;
if (x%100==0) app.alert("X is divisible by 100.");
else app.alert("X is NOT divisible by 100.");
Copy link to clipboard
Copied
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)){
Copy link to clipboard
Copied
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){
Copy link to clipboard
Copied
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;
}
Find more inspiration, events, and resources on the new Adobe Community
Explore Now