How to List All Field Names in Tab Order in Adobe Acrobat
Creating a field list in tabbing order using outside-the-box thinking
“I need to extract the names of all form fields in their tab order. Is there a way to do this using JavaScript or any built-in functionality?”
The question above was recently asked on the Acrobat Users Forum. As I was testing a solution, I knew somebody would answer that it wasn't possible before I had chance to complete my test. I was correct. It happens a lot - because the answer is not in the Acrobat JavaScript API Reference - at least not directly. I'll provide the answer in a minute, after I discuss the tabbing order of PDF forms.
Default Tabbing Order
When creating a fillable PDF form the default tabbing order is the order in which the fields were created. When adding fields to a PDF form I don't usually prioritize a logical tabbing order at first. Many fields contain calculations and other scripts so my initial priority is on adding fields in a correct calculation order order, then adding the other fields later. Like the calculation order, which matters for correct results, the tabbing order can be fixed after the fact. A lot of thought should go into naming fields to make these and other tasks easier, which is one of the reasons I never use automatic "detect fields" when preparing a form.
Other Tabbing Order Options
Other automatic tabbing order options, which are page-specific, are:
Row Order
Column Order
Document Structure
Row and column order are self-explanatory. Row order goes left to right before moving down, and column order goes top to bottom, starting on the left before moving right. If the form is in a table format, the tabbing is easy to follow with these two options. If not, it can seem to jump all over the place as field positions could have scattered alignments.
The results of Document Structure are not always what you might expect. For example, the following screenshot of fields arranged in a table shows the tabbing numbers as the values when the tabbing order for this page is set to Document Structure.
This field table was created by creating fields 1, 2, and 3, then using right-click > Create multiple copies. The tabbing order lines up more with the default (order in which the fields were created), than document structure.
To set the tabbing order using the above options, simply open the pages panel on left of the screen, right-click a page or range of selected pages, click Page Properties, then select the appropriate option.
To select a range of pages in succession, select the first page and hold down the Shift key while selecting the last page of the range. To select all the pages, select one page, then press Ctrl + a. To select a range of pages not in succession, select a page, then hold down the Ctrl key while selecting the rest of the pages individually.
Setting Tabbing Order Options With A Script
The document setPageTabOrder( ) method can be used to set the tabbing order. It takes two mandatory input parameters:
nPage - The zero-based index of the page number on which the tabbing order will be set.
cOrder - The order to be used. The values are: rows, columns, or structure.
The following script, which can be run in the console, will set the tabbing order of page 1 to Column Order.
this.setPageTabOrder( 0, "columns");
To set all pages at once, loop through all the pages numbers. The following script sets the tabbing order to Row Order for all pages.
for(var i=0; i<this.numPages; i++)
{this.setPageTabOrder(i, "rows");}
Manually Setting Tab Order
In form editing mode (“prepare form”), in the fields panel on the right, ensure the AZ sort is set to Tab Order. Drag the fields up or down to set the tab order with the top field being first tab on the page and bottom field being last. You can also view the tab order numbers by selecting Show Tab Numbers from the More dropdown.
Getting a List of Fields in Tab Order
This solution required some thinking outside-the-box. While it is not fully automated it is pretty close. Here's the process:
Add a script that writes the name of the field to the console when that field receives the focus. Add the script to every field . This is known as an On Focus action. The script to add is as follows:
console.println(event.target.name);
To add this script manually you would add it in the Actions tab of the field properties, but we aren’t going to add it manually because that would take too long. Instead we are going to use the setAction( ) field method that you can read about below, then loop through every field in the document.
Here’s the script to run in the console:
for(var i = 0; i < this.numFields; i++) { var fieldName = this.getNthFieldName(i); var fld=this.getField(fieldName); fld.setAction('OnFocus','console.println(event.target.name);'); }
Open the field properties of the last field in the tab order and add the following On Focus action script after the existing script console.println(event.target.name);
app.alert("List is finished.");
Exit field editing mode and clear the console.
Click inside the first field of the tabbing order.
Hold down the tab key until the alert in step 2 pops up.
Dismiss the alert.
Open the console and copy the list.
Close the PDF without saving the changes.
The reason for step 2 is so you can tab through all the fields in rapid succession by holding down the tab key. Without step 2, it would start again after the last field, making it difficult to stop exactly on the last field.
If you've ever tried to let go of the trigger on the gas pump at a specific dollar amount you know exactly what I'm talking about. The alert is the PDF scripting equivalent of preprogramming the gas pump to only pump a specific dollar amount.
We could run a script in the console to reverse steps 1 and 2, but it's a lot easier to do step 8, and simply close the document without saving the changes.
The tab list will not include hidden fields or fields that are set to Read Only, because tabbing will skip these fields, even though they have a tab number. The result is the true tabbing order list. If you want these fields included simply make them visible and set the readonly property to false before tabbing.