Copy link to clipboard
Copied
I have a pretty large document that has over 200 text/check boxes. What I want to do is create a button that makes a pop-up warning for any blank fields in the entire document.
Right now the only way I've seen to do this is using javascript using an array of every field and checking them 1 by 1 in a for-loop. I would like to avoid this as the array requires you to type the title of each field so with 200+ fields it becomes quite tedious typing them all in.
Using Acrobat XI Pro, thanks.
You can use something like this:
var emptyFields = [];
for (var i=0; i<this.numFields; i++) {
var f= this.getField(this.getNthFieldName(i));
if (f.type!="button" && f.required ) {
if ((f.type=="text" && f.value=="") || (f.type=="checkbox" && f.value=="Off")) emptyFields.push(f.name);
}
}
if (emptyFields.length>0) {
app.alert("Error! You must fill in the following fields:\n" + emptyFields.join("\n"));
}
Copy link to clipboard
Copied
put the document level script on "Page Open":
app.runtimeHighlight = false;
Then put Try67's script with Submit:
var emptyFields = [];
for (var i=0; i<this.numFields; i++) {
var f= this.getField(this.getNthFieldName(i));
if (f.type!="button" && f.required && f.display==display.visible) {
if ((f.type=="text" && f.value=="") || (f.type=="checkbox" && f.value=="Off")) emptyFields.push(f.name);
}
}
if (emptyFields.length>0) {
app.alert("You must fill in the following fields:\n" + emptyFields.join("\n"));
}
else
{
// This is the form return email. It's hardcoded
// so that the form is always returned to the same address.
var cToAddr = "email@domain.com"
// Set the subject and body text for the email message
var cSubLine = "Form Submission"
// Send the entire PDF as a file attachment on an email
this.mailDoc({bUI: true, cTo: cToAddr, cSubject: cSubLine});
}
Copy link to clipboard
Copied
I am using the below to print only the page that has been filled out to send in. Right now if it finds errors it does pop up a window that shows what needs to be filled out. However after clicking okay it still prints the document. What am i missing to not print if error is reported.
var emptyFields = [];
for (var i=0; i<this.numFields; i++) {
var f= this.getField(this.getNthFieldName(i));
if (f.type!="button" && f.required ) {
if ((f.type=="text" && f.value=="") || (f.type=="checkbox" && f.value=="Off")) emptyFields.push(f.name);
}
}
if (emptyFields.length>0) {
app.alert("Error! You must fill in the following fields:\n" + emptyFields.join("\n"));
};
this. print({bUI: false, nStart: pageNum, nEnd: pageNum, bSilent: true, bShrinkToFit: true});
Copy link to clipboard
Copied
Remove any print command you added, ad well as the semi-colon at the end of
the code and add this line as the last line:
else this.print();
Copy link to clipboard
Copied
Script works great - thank you. However if one of my fields equals zero (e.g. I have a box for carriage costs which can be zero if customer is collecting), script doesn't recognise this as completed and assumes zero means empty and so error dialog pops up.
Can you help, please?
Copy link to clipboard
Copied
Change this part of the code:
(f.type=="text" && f.value=="")
To this:
(f.type=="text" && f.valueAsString==f.defaultValue)
Copy link to clipboard
Copied
Perfect - thanks very much!
Copy link to clipboard
Copied
Hi Gilad D,
I hope you're still seeing this thread. I have been trying to find what I need to do to make your script work for my situation.
I'm using Adobe Acrobat Pro DC. I have a number of radio buttons that enter a value when selected. The totals are used to add up to a final score / grade. When I run your script, I always get the alert on required buttons even when one of the selections is made, so technically, that/those button(s) are complete.
What am I doing wrong? (I began with your standard script at the beginning of this multi-year thread, and I have tried some of the variations suggested by others. Below is the last version I tried based on a recent script where you changed the check value from value to valueAsString.
Any help is appreciated! Thanks,
George
My current code status:
var emptyFields = [];
for (var i=0; i<this.numFields; i++) {
var f= this.getField(this.getNthFieldName(i));
if (f.type!="button" && f.required ) {
if ((f.type=="text" && f.value=="") || (f.type=="checkbox" && f.valueAsString==f.defaultValue))
f.strokeColor = color.red; //Highlights the required fields in red
emptyFields.push(f.name);
}
}
if (emptyFields.length>0) {
app.alert("Error! You must fill in the following fields:\n" + emptyFields.join("\n"));
}
Copy link to clipboard
Copied
Hi George,
If you add additional commands then you have to make sure that the curly brackets used are still correct, and they are not in the code you posted. Replace the middle part of it with this:
if (f.type!="button" && f.required) {
if (f.valueAsString==f.defaultValue) {
f.strokeColor = color.red; //Highlights the required fields in red
emptyFields.push(f.name);
}
}
Are you sure you want to change the fields' border color to red, though? If so, where are you changing it back?
Copy link to clipboard
Copied
Thanks Gilad D for the direction. And also for the thoughtfulness: how will I be able to change the color back (because it's changed and once they answer the question, I won't be able to find it)? It's getting more complex than this needs to be.
Do you have any suggestions? Basically, I need the script to recognize these radio buttons as being completed (I guess that is taken care of by the if statement checking if they have a default value or not) and to alert the form user to the missing information. I imagine it might take a user several iterations to get multiple buttons completed before the form can be completed.
I'm also thinking that the mechanism for controlling this is to add something with a function to check the form is ready, and when the check script is run, it resets the signature fields to visible. Does that sound like a simple, straight-forward solution?
Thanks again for taking the time to reply.
Best,
George
Copy link to clipboard
Copied
I would get rid of the command to change the fields border color. Instead you can display a list with the names of the fields that are still missing, and/or set the focus to the first field in that list, so it's more clear to the user which ones they need to fill in.
Regarding the signature fields: Yes, that will work. You can hide them and only display them when all the required fields are filled-in.
Copy link to clipboard
Copied
Hello,
This thread has helped me exponentially but, and forgive me if this is mentioned somewhere previously, I'm trying to take it one step further.
The code that I've taken from this thread:
var emptyFields = [];
for (var i=0; i<this.numFields; i++) {
var f= this.getField(this.getNthFieldName(i));
if (f.type!="button" && f.required && f.display==display.visible) {
if (f.valueAsString==f.defaultValue) {
f.strokeColor = color.red;
emptyFields.push(f.name);
} else {
f.strokeColor = color.transparent;
}
}
}
if (emptyFields.length>0) {
app.alert("YOU MUST COMPLETE THE FOLLOWING FIELDS:\n" + emptyFields.join("\n"));
}
works perfectly! However, I'm trying to add in a print prevention, where the fields will print or save as empty if all the required fields are not filled in properly.
I tried to build a Franken-code with the above and this:
(function () {
var i, val, bNotComplete = false;
var aFields = ["Text 1", "Text 2", Text 3"];
for (i = 0; i < aFields.length; i += 1) {
val = getField(aFields).valueAsString;
if (!val) {
bNotComplete = true;
app.alert("Not all required fields are complete, so the form will print blank.", 3);
break;
}
}
for (i = 0; i < numFields; i += 1) {
getField(getNthFieldName(i)).display = bNotComplete ? display.noPrint : display.visible;
}
})();
The problem that I'm running into is that the second code does not discriminate between visible or hidden fields. I'm under the impression that these codes are approaching the same tasks differently, but I don't know what I'm doing and I don't know how to make what was built with this thread work with the print restriction in the second code above.
Any help that can be provided would be greatly appreciated!
Copy link to clipboard
Copied
try67,
This code works great for me but the button I'm using to check if all fields have been completed is a signature box. When I click on it with missing fields, it definitely pops up what fields are missing but the signature window pops up after I click ok. I'm trying to prevent the user from signing the document until all fields have been filled in.
Copy link to clipboard
Copied
You can't do that. The only way is to hide the signature field and attach the code to a button field. If the validation is successful, show the signature field so the user can sign it. Otherwise, keep it hidden.
Copy link to clipboard
Copied
Darn...ok, thanks for the heads up.
Copy link to clipboard
Copied
I found this post and your code, I added it to my silent save button using mouse enter and it works perfectly! Except it doesn't pop up with an error when the signature field is blank, also how do you enable the code for check boxes and radio buttons, I couldn't quite figure that out.
Thanks
Copy link to clipboard
Copied
What version of the code are you using? Can you post it?
Copy link to clipboard
Copied
I'm using the correct answer from the start of the thread
var emptyFields = [];
for (var i=0; i<this.numFields; i++) {
var f= this.getField(this.getNthFieldName(i));
if (f.type!="button" && f.required ) {
if ((f.type=="text" && f.value=="") || (f.type=="checkbox" && f.value=="Off")) emptyFields.push(f.name);
}
}
if (emptyFields.length>0) {
app.alert("Error! You must fill in the following fields:\n" + emptyFields.join("\n"));
}
Copy link to clipboard
Copied
Bump
Copy link to clipboard
Copied
Sorry, thought I replied... Change this line:
if ((f.type=="text" && f.value=="") || (f.type=="checkbox" && f.value=="Off")) emptyFields.push(f.name);
To:
if (f.type!="button" && f.valueAsString==f.defaultValue) emptyFields.push(f.name);
Copy link to clipboard
Copied
try67,
I've got a form which is split into 3 parts for the 3 different departments to complete.
At the end of each part I have a submit button and I would like the use the below code but to make it specific to the fields in each part, if that makes sense?
var emptyFields = [];
for (var i=0; i<this.numFields; i++) {
var f= this.getField(this.getNthFieldName(i));
if (f.type!="button" && f.required ) {
if ((f.type=="text" && f.value=="") || (f.type=="checkbox" && f.value=="Off")) emptyFields.push(f.name);
}
}
if (emptyFields.length>0) {
app.alert("Error! You must fill in the following fields:\n" + emptyFields.join("\n"));
}
Copy link to clipboard
Copied
You can change the page value of each form and see it if falls within a certain range. However, if the sections are not whole pages, that won't work. In that case you'll need to rely on the field names.
Copy link to clipboard
Copied
I’m happy to rely on field names but I’m unsure on how I can incorporate this in the above code?
I appreciate the help!
Copy link to clipboard
Copied
Use this code, then:
var fieldsToCheck = ["Field1", "Field2", "Field3"];
var emptyFields = [];
for (var i=0; i<fieldsToCheck.length; i++) {
var f = this.getField(fieldsToCheck);
if (f.type!="button" && f.required && f.valueAsString==f.defaultValue)
emptyFields.push(f.name);
}
if (emptyFields.length>0) {
app.alert("Error! You must fill in the following fields:\n" + emptyFields.join("\n"));
} else app.alert("This section is fine!",3);
Adjust the field names in the first line to match those of the fields belonging to that section.
Copy link to clipboard
Copied
Hi Try67,
Good day to you.
I have the similar problem when creating the required form fields and your recommendation has worked out. However the only problem was that the script recognize the numeric 0 as empty field when there are some input which might be 0:
How can I write the script that it won't recognize 0 as an empty field? It because there is indeed cc named 0.
My current script is:
Thank you! I look forward to hearing from you soon!
Copy link to clipboard
Copied
Change the sixth line to:
if (f.valueAsString==f.defaultValue) emptyFields.push(f.name);
PS. In the future, please post the code as text, not as an image.