Coverting Disobliging PDFs Into Fillable Forms
A few tips for converting PDFs that were designed for pen and paper into fillable forms.
A lot of institutions seem to want to convert their forms to PDF fillable forms without first redesigning these holdouts from the pre-electronic age of paper. Perhaps a decision maker said "make all our forms fillable" without actually looking at the forms first, and nobody suggested "we should take this opportunity to redesign all our forms before making them fillable". It doesn't really matter how it happens. But it happens. In this article I’ll point out a few recurring themes that make it difficult to work with forms designed for pen and paper, and how to overcome these issues.
The One-Box-Per-Character Theme
We've all seen these forms that attempt to make handwriting (or printing) more legible by forcing the user to enter characters that are evenly spaced, by having one box for each character.
As a form developer, if you want to torture yourself, and the end user of this form, you can make one field for each box and set a limit of one character for each field. Fast-typing end users will lose it when they realize they have to hit the tab key after each letter (there's actually an automated solution to avoid the tab trap that I describe later in the article, but it's not the best solution for the image above).
The solution to a form with the image above is as follows:
Count the number of boxes in the layout for the field.
Create a text field and size it so it's positioned directly over all the boxes.
Open the Options tab of the field properties, select Comb of, and enter the number of boxes.
If Comb of is disabled, unselect some of the other check boxes above it until it is enabled. Now when the user types in the field the entry will be perfectly spaced so that there is only character per box, and no more than the number of characters entered will be allowed.
Force Upper Case
Whether the form has the boxes or not, a lot of forms require printing in upper case. There's a simple way to force upper case by simply adding the following script to each text field as a custom validation script:
event.value=event.value.toUpperCase();
The One-Box-Per-Character With Hyphens Theme
This theme is the same as the previous one, with added twist of hyphens. It's usually for a field with some type of number, like a credit card number, and the form's owner wants separators in the number.
The easiest solution is exactly the same as the previous one. However, some users might not be able to figure out that they need to enter a space after every fourth number so it will skip the underlying hyphen. As a form developer it's good practice to anticipate what the end user might do to make a mess and program the form to avoid it.
In the example above you could make four fields, each with a Comb of of four characters. The end user will still have to tab from one field to the next.
NOTE: It’s crucial to have the correct tab order so the tab key does not bounce the user all over the form.
The Arbitrary Mask Solution
Arbitrary Mask formatting allows you to set a pattern for what is entered into a form field, and it is enforced with every keystroke. It's found in the Format tab of the field properties under the Special category. For any number in the pattern enter the number 9. For any letter in the pattern enter the capital letter A. Any other digits or letters entered into the pattern will be taken literally as the actual digits and letters.
To use the arbitrary mask solution for the image above, create one field and enter Comb of 19 in the options tab (16 empty boxes plus 3 that contain hyphens). Then enter the following in the arbitrary mask format field:
In this example, not only will the user be prevented from entering anything except numbers, the spaces will automatically be inserted as the user types the number with or without spaces. It will also allow the user to paste a 16-digit number into the field, again with or without the spaces. If the user attempts to enter a letter, the following warning will pop up and the letter will not be accepted:
The Auto-Tab Solution
If a form field has a maximum character capacity, either by using Comb of or Limit of in the options tab of the field properties, a custom keystroke script can be used to automatically tab to another field when the final character is entered. Enter the following as a document level script:
function tab_next(nextField)
{
if (event.willCommit || AFMergeChange(event).length === event.target.charLimit)
{
this.getField(nextField).setFocus();
}
}
Call the function in a custom keystroke script like this (nextField is replace with actual field name in quotes):
tab_next("Text1");
If the field containing the custom keystroke script above has a limit of four characters, the focus will go to the field called "Text1" when the fourth character is entered, or when the user exits the field.
Circle-The-Answer Theme
When the form asks you to circle something, it's a holdout from the paper and pen era that should definitely be redesigned, especially to avoid this mess:
I've seen it too many times. There's a way to allow the user to actually draw a circle around the words by clicking them, and then remove the circle by clicking the word again. This is possible by using a combination of markup annotations and invisible button fields.
Note: A message to click the words to circle them should be added to the form to provide guidance to the user.
First, use the Circle comment tool to draw circles around each word:
Next, change the name property of each circle to something relevant that can be used in a script. In this example, the names will be changed to the words they circle. Also make each circle "read-only". This will prevent end users from interacting with the circles (moving, removing, resizing, deleting, etc.). Finally, hide the circles. All three property changes can be done at once by first selecting the circle, then running the following script in the console:
var anot=this.selectedAnnots[0];
anot.name="Apples";
anot.readOnly=true;
anot.hidden=true;
Repeat for each circle after changing the word "Apples" in the script to the word inside the selected circle.
Create Transparent Button Fields
The next step is to create a transparent button field for each circle and lay it over the words (Apples, Bananas, etc).
I will name my button fields the exact same names I gave to the circles (Apples, Bananas, etc.) so I can use the same script for each button. I'll create the first button, add the script, copy and paste the button once for each word, then rename the button fields to match the words, so I don’t have to copy and paste my script to each button.
Add the following script as Mouse Up action in the actions tab of the button field:
var anot=this.getAnnot(this.pageNum, event.target.name);
if(anot.hidden==true)
{anot.hidden=false}
else
{anot.hidden=true}
The document method getAnnot takes two input parameters:
The page number of the annotation. this.pageNum is used so the script can be used in the button field on any page without have to change the page number in the script.
The name of the annotation. event.target.name is the name of the button field. Since the annotation has the same name as the button field, the script will work for all the buttons for which there is an annotation with a matching name.
The script says:
If the annotation is hidden, show it, and if the annotation is not hidden, hide it.
Now the user can hide or show the circles by clicking the words.
Making The Circles Mutually Exclusive
Suppose there's only one possible answer, or word, that should be circled. You can modify the script so that the circles act like radio buttons or mutually exclusive check boxes.
The trick here is to hide all circles except the one for which the button is clicked. This one will still toggle between show and hide in case the user wants to hide all choices after selecting one. For this example, the naming will be different to make it easier to hide all the circles without naming them all in the script, and also because there will probably be several similar questions.
TIP: Because the words are 1-digit numbers, the circles can be all the same size, and they can be perfect circles. To draw a perfect circle with the circle comment tool, hold down the Shift key while dragging the mouse. Once you have one circle that is the right size, you can copy and paste it four times so they are all the same size.
In this example the circles will be named Q1.1, Q1.2, Q1.3, Q1.4, and Q1.5. Q1 is the question number and the number after the decimal is the answer (the "word"). Select the circles one at a time and run the following script in the console, changing Q1.1 to the corresponding name for each selection.
var anot=this.selectedAnnots[0];
anot.name="Q1.1";
anot.readOnly=true;
anot.hidden=true;
Next create the transparent button fields. Create the first button field, enter the following Mouse Up action script, then follow the tip below to create the remaining fields.
//Part 1
var anot=this.getAnnot(this.pageNum, event.target.name);
if(anot.hidden==true)
{anot.hidden=false}
else
{anot.hidden=true}
//Part 2
for(var i=1;i<6;i++)
{
if(event.target.name!="Q1."+i)
{
this.getAnnot(this.pageNum, "Q1."+i).hidden=true;
}
}
The first part of the script is exactly the same as the previous example where the circles weren't mutually exclusive. The second part of the script hides all circles in the question except the one connected to the button that is clicked.
TIP: Create the first button, add the script above, and name the button Q1. Right-click the button, select Create multiple copies, then enter 6 down and 1 across. You will end up with six fields named Q1.0 through Q1.5. Delete Q1.0 and move the fields into place.
Repeat this for all additional questions while change the Q1's to Q2's, Q3's etc.
Hugely helpful — thank you!
This was very helpful information, thank you. Is there a place where users can ask you random questions?