These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

How to validate that 2 of a set of 40 form fields are filled in?

johnsonweb
Registered: Jan 21 2008
Posts: 20
Answered

Hi -

I'm new to Acrobat Forms but have created my first form with a submit (to email) and reset button.

It's a 3-page form. The third page contains 40 text boxes where users can fill in their name next to volunteer activities they are willing to do.

I'd like the form to validate that the user has added his/her name to at least 2 of those 40 volunteer text boxes before I accept them submitting the form to email.

How is this done?

Thanks!

Jeff

My Product Information:
Acrobat Pro 8.1.2, Windows
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
You need to write a script that walks through all 40 fields and counts the number of non-null, or non-empty entries. The important thing here is that the fields are named in such a way that they are easy to access.

For example: Activity1, Activity2, Activity3, etc.

Then you can write a loop like this

var nActivityCount = 0;
for(var i=1;i<41;i++)
{
var fld = this.getField("Activity" + i);
if( (fld != null) && (fld.value != null) && (fld.value.length > 0) )
nActivityCount++;
}

if(nActivityCount > 1)
this.mailForm(...);
else
app.alert("Not enough Activities");


To use this script you'll also need to submit using JavaScript, as shown in the last bit of the script. Place this code in the button Down event of your submit button and delete the current submit action.

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

johnsonweb
Registered: Jan 21 2008
Posts: 20
thomp -

Thanks for the detailed answer. It works great.

I found the documentation for the mailForm() function in the Acrobat JavaScript Scripting Reference manual online at adobe.com. I'd cut/paste the code but the Acrobat javascript editor will not let me cut/paste. :-(

Anyway, not being javascript fluent, I assume (fld != null) checks for a field that does not exist; (fld.value != null) checks for an existing field being null ... but why do a (fld.value.length > 0) ?Again, thanks for the great support.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
You are correct!! Yes, it's important to make sure that the field is there and not empty.

The two field value tests are necessary. First, a field that has never been touched can have a null value. But a field that's been filled in and then deleted can have an empty string in it. So it's not null, but nothing is there. The length check is quick and dirty. A better test would be to use a regular expression like this.

var emptyTest = /^\s*$/;

if(!emptyTest.test(fld.value))
app.alert("This is an empty string");


The regular expression catches a string that's all white space.

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

johnsonweb
Registered: Jan 21 2008
Posts: 20
Thanks, I'll incorporate that.

Meanwhile, I discovered that adding the Javascript to check the 40 volunteer fields caused the form to ignore the "required field" checkbox for the other fields in the form. There are 3 pages of fields on this form.

So, I thought I would take a stab at some Javascript to validate that the required fields are filled in. The goal being that the javascript should find the first empty required field, issue an alert message, focus on the field and terminate further field validation.

The code below works but as you can probably see it will issue a string of alerts if there are multiple empty required fields. There must be a command to exit the entire javascript like a PHP exit() command.

Any ideas?

thanks!

Jeff

===================================
function validate_required(field,alert)
{
var fld = this.getField(field);
if( (fld == null) || (fld.value == null) || (fld.value.length == 0) )
{app.alert(alert); fld.setFocus() ;return false}
else {return true}
}// check that required fields are not empty
validate_required("Name_dir","Please provide a Directory Name");
validate_required("Address_dir","Please provide a Directory Address");
validate_required("City_dir","Please provide a Directory City");



// check that minimum number of volunteer activities are selected
var nActivityCount = 0;
var minActivities = 1;
for (var i=1;i<42;i++)
{
var fld = this.getField("Activity" + i);
if( (fld != null) && (fld.value != null) && (fld.value.length > 0) )
nActivityCount++;
}if(nActivityCount >= minActivities)
{
this.mailForm(true, "me [at] mydomain [dot] com", "", "", "Associate Membership Application", "See attached file.");
}
else
app.alert("You need to select at least 1 volunteer activity.");
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
There are a couple of solutions.

1. Drop out on the first validation failure. Have the "validate_required" function return true or false, then only check the other fields when a true is returned.

2. Do not display the alert in "validate_required". Instead, use this function to build the final alert message. Check the length of this message at the end of the code. If it's empty, send the data, if it's not empty you have a violation and can display the alert. Similar to what you are doing for the "Activity" fields, which should be incorporated into this scheme.

There is no way to exit a top level event script at a random point. This is one of those opportunaties to practice good coding. Design your code so that it always flows through to the end. If you can do it without using a "goto", you're an expert;)

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

johnsonweb
Registered: Jan 21 2008
Posts: 20
In case this helps someone else, here's the code I ended up with. It may not be pretty but it works!

Thanks for your help Thom P.

Jeff

// These are the required fields on the form.// Populate array with their names.var requiredFields = new Array(14);requiredFields[0]  = "Name_dir";requiredFields[1]  = "Address_dir";requiredFields[2]  = "City_dir";requiredFields[3]  = "Zip_dir";requiredFields[4]  = "Phone_dir";requiredFields[5]  = "Date_emer";requiredFields[6]  = "Last_emer";requiredFields[7]  = "Address_emer";requiredFields[8]  = "Home_Number_emer";requiredFields[9]  = "Name_2_emer";requiredFields[10] = "Relation_emer";requiredFields[11] = "Phone_Number_2_emer";requiredFields[12] = "Phone_Number_3";requiredFields[13] = "Email";  // These are the alert messages shown when a required field is empty.// Populate array with messages.// Make sure there's one message for each required field.var alertMsg = new Array(14);alertMsg[0]  = "Please enter a Directory Name.";alertMsg[1]  = "Please enter a Directory Address.";alertMsg[2]  = "Please enter a Directory City.";alertMsg[3]  = "Please enter a Directory Zip Code.";alertMsg[4]  = "Please enter a Directory Phone Number.";alertMsg[5]  = "Please enter an Emergency Form Date.";alertMsg[6]  = "Please enter an Emergency Form Last Name.";alertMsg[7]  = "Please enter an Emergency Form Address.";alertMsg[8]  = "Please enter an Emergency Form Home Phone Number.";alertMsg[9]  = "Please enter an Emergency Form Contact Name.";alertMsg[10] = "Please enter an Emergency Form Contact Relationship.";alertMsg[11] = "Please enter an Emergency Form Contact Phone Number.";alertMsg[12] = "Please enter a Volunteer Form Phone Number.";alertMsg[13] = "Please enter a Volunteer Form Email Address.";  // Regular expression. It means start at beginning of string, look for any single// white space char, one or more times, to the end of the string.var emptyTest = /^\s*$/; var fieldCount = requiredFields.lengthvar fld = 0; for (var i=0; i < fieldCount; i++){fld = this.getField(requiredFields[i]);if( emptyTest.test(fld.value) )             // if required field is empty{app.alert(alertMsg[i]);fld.setFocus();break;}}  // Verify that at least 1 volunteer activity has been selected.// Don't check volunteer activities until all required fields above have been tested.if (i == fieldCount){var nActivityCount = 0;var minActivities = 1;for (var i=1; i < 42; i++){fld = this.getField("Activity" + i);if( !emptyTest.test(fld.value) )        // if Activity field is not emptynActivityCount++;} if(nActivityCount >= minActivities){this.mailDoc(false, "<span class="spamspan"><span class="u">me</span> [at] <span class="d">mydomain [dot] com</span></span>", "", "", "Associate Membership Application", "See attached file.");}else{app.alert("You must select at least 1 volunteer activity.");fld = this.getField("Activity1");fld.setFocus();}}
Worsty
Registered: Nov 8 2007
Posts: 7
I'm a novice at this so please be patient. I have a similar situation where I want to check multiple checkboxes. There are 14 checkboxes and at least one must be checked or value of "1". They all have different names like chbWC, chbAuto, chbCrop, etc.

Could you help me adapt your code below to fit my needs? Thanks,

You need to write a script that walks through all 40 fields and counts the number of non-null, or non-empty entries. The important thing here is that the fields are named in such a way that they are easy to access.

For example: Activity1, Activity2, Activity3, etc.

Then you can write a loop like this

var nActivityCount = 0;
for(var i=1;i<41;i++)
{
var fld = this.getField("Activity" + i);
if( (fld != null) && (fld.value != null) && (fld.value.length > 0) )
nActivityCount++;
}

if(nActivityCount > 1)
this.mailForm(...);
else
app.alert("Not enough Activities");


To use this script you'll also need to submit using JavaScript, as shown in the last bit of the script. Place this code in the button Down event of your submit button and delete the current submit action.

Offline
gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307
Check boxes and radio button have a ".value" property of "Off" when not selected. Also if one uses hierarchical fields, "Activity.#", one can create an array of the fields below a given level and use that array to control the program flow.

For example:
var nActivityCount = 0; // clear countvar oActivity = this.getField("Activity"); // get activity field objectvar aActivity = oActivity.getArray(); // convert object to an array// loop through array of fields using the field array for controlfor(i = 0; i < aActivity.length; i++)  {// count if check box is not unchecked or "Off"if(aActivity[i].value != "Off") nActivityCount++;} if(nActivityCount > 1)this.mailForm(...);elseapp.alert("Not enough Activities");

George Kaiser

Worsty
Registered: Nov 8 2007
Posts: 7
Thanks for your reply but I guess I still don't understand how it loops through 14 checkboxes with different names. All of my checkboxes are named differently, for example: They all have different names like chbWC, chbAuto, chbCrop, etc.

In the example above you have an array called Activity. Could you use the field names that Ihave given to clarify the code for me a bit better. Thanks,
gkaiseril
Online
Expert
Registered: Feb 23 2006
Posts: 4307
It loops through any number of fields with the given naming structure:


Activity
Activity.0
Activity.1
Activity.2
Activity.3
Activity.4
Activity.5
Activity.6
Activity.7
Activity.8
Activity.9
Activity.10
Activity.11
Activity.12
Activity.13

"Activity" is a JavaScript field object with 14 field objects within it. The "Activity" object can be converted to an arry with the ".getArray()" method and that array contains the 14 fields of the "Activity" object. The created array "aActivity" has a length of the number of elements, fields, within the array. Each element of the array is uniquely named and has an element value.

Since you have named your fields differently, you need to create an array of field names and then use that array in your script. I modified the sample code you posted to show how with a different naming technique one could have code that is independent of the expected number of fields. Your code also was not testing the value of the check box that would work since a check box never has a null value nor a length of "0".

For your example:
// define array of required field namesvar aReqFields = new Array("Activity1","Activity2", "Activity3", "Activity4"); var fld; // some debugging informationconsole.show();console.clear();console.println("Number of required fields: " + aReqFields.length); var nActivityCount = 0; // clear count// loop through the required field arrayfor(var i = 0;i < aReqFields.length; i++) { fld = this.getField(aReqFields[i]); // get field name for i element of array console.println (i + ": " + fld.value); // more debugging info if(fld.value != "Off"  )nActivityCount++;} console.println('Activity count: ' +  nActivityCount); // more debugging info if(nActivityCount > 1)this.mailForm(...);elseapp.alert("Not enough Activities");

George Kaiser