19 Jul Find a Fieldname Prefix on Acroform Pages with JavaScript
When spawning new pages in an Acrobat Acroform, you can choose to rename, or not rename, all the fields on the new page. Obviously, if you don’t rename your field names, you know what the field names on the new pages will be.
But what if your user really needs a lot of continuation pages? Let’s say your user needs to be able to spawn an indefinite (infinite) number of the same continuation page. In that case, you will need each field on each continuation page to have a unique name. If you didn’t rename the fields, and you spawned multiples of the same page, you would have duplicate field names, thus duplicate data on all your continuation pages.
Just to make it interesting, let’s also say that you have several different templates from which to spawn pages. And let’s say that the users are able to add continuation pages in any order they like. How would you be able to address field names on all these new continuation pages?
The Fieldname Prefix Format
When you choose to rename fields on spawned template pages, using the bRename parameter, Acrobat will rename the fields by prefacing every field on the page with the page number and the template name. The format is:
P4.MyTemplateName.myFieldname
P4 is the zero-based number of the page which was added.
MyTemplateName is the literal value of the template names.
myFieldname is the fieldname that you assigned originally.
So for example, the field on a template named Template1, generated on page 4 of the form, and originally named myFieldname, would become:
P3.Template1.myFieldName
How to find the prefix for a page
In the example above, you can end up with a ton of spawned pages from several different templates in a random order. If you want to loop through all your pages extracting information for your database, how could you do it?
All fields on a spawned page share the same prefix. All we need is to be able to find the prefix of each page. To find this prefix, I have written the following functions:
GetPrefix(currentPageNum)
IsContinuationField(currentFieldName)
GetPrefix( )
When you use the GetPrefix() function, you pass a page number value. Most likely, but not always, you will want to pass the value of the current page, and will use the predefined variable pageNum. GetPrefix loops through a list of all the fields in the document, looking for the first occurrence of any field which is prefaced with “P” plus the requested page number. When it finds the first occurrence of the requested number, it returns the prefix. Here is the code:
// Get the prefix of a specific number continuation page. The page number is in the first segment of // all the renamed field names, in the format P#, where # is the number of the page in question. function GetPrefix(currentPageNum) { // Go through the list of all the fields in this document. for (var i = 0 ; i < this.numFields ; i++) { // Get the Nth field name from the list of all field names on the form. var cFieldName = this.getNthFieldName(i); // Test to see if this field is from a continuation page. // See the explanation of IsContinuationField() function. var foundOne = IsContinuationField(cFieldName); // If it is from a continuation page, return the prefix. if (foundOne) { // Create an array of the field name components: // 0 => P# for page number // 1 => T# for template name (number) // 2 => the original field name var aFoundOne = foundOne.split("."); // Get the number after "P", could be more than single digit. var numberComponent = aFoundOne[0].substring(1); if ( numberComponent == currentPageNum ) { return foundOne ; } } } }
IsContinuationField( )
GetPrefix() uses a function called InContinuationField(). Since we are only searching for the prefix of pages spawned with the rename parameter, we want to eliminate any field name that doesn’t start with Pn.TemplateName.
The IsContinuationField() checks to see if the field being tested is from a continuation page. By using the String.split method, it isolates the segments of the fieldname. If the fieldname has at least three segments, and the first segment begins with “P”, a continuation page has been found. In this case, it returns a prefix to be tested by GetPrefix().. Here is the code:
// Determine if a field name came from a spawned template page created using the rename parameter. function IsContinuationField(currentFieldName) { // For the field passed, determine if it came from a continuation page. // If Yes, return the field prefix // If No, return false. var cFieldName = currentFieldName; // convert the full field name to an array var aFieldName = cFieldName.split("."); if (aFieldName.length > 2) { // element 0 of the field name array is P# // element 1 of the field name is the template that created the page // element 2 is the rest of the field name, as it exists in the template page. var firstLetter = aFieldName[0].substring(0,1); // If the first letter of the first segment of the field name is a P, return the prefix. if ( firstLetter == "P" ) { var foundFieldPrefix = aFieldName[0] + "." + aFieldName[1] + "."; //app.alert("The field prefix is " + foundFieldPrefix); return foundFieldPrefix; } else { return false; } } }
Some Other Helpful Code
RenumberPage( )
Here is an example of the use of GetPrefix() and IsContinuationField(). In RenumberPage(), the page total on all the continuation pages is updated after a new page is spawned.
// Renumber pages and page totals after a page has been added. function RenumberPages() { // Adjust the totals on the first three pages, which are static. this.getField("txtPageTotal1").value = numPages; this.getField("txtPageTotal2").value = numPages; this.getField("txtPageTotal3").value = numPages; // Then update the page totals on any continuation pages. // The pages are zero-based. NumPages is 1 based. So start with Page 4, which is number 3. for (var i=3 ; i < numPages ; i++) { var myPrefix = GetPrefix(i); // Create an array of the field name components: // 0 => P# for page number // 1 => T# for template name (number) // 2 => the db_xxxxx field name if (myPrefix) { var aPrefixSegments = myPrefix.split("."); // Isolate the Template Name var templateName = aPrefixSegments[1]; // The two fields,the total number of pages and the current page number, // have the template name appended. var myPageNumName = (myPrefix + "txtCurrentPageNum" + templateName); var myTotalField = (myPrefix + "txtPageTotalContinuation" + templateName); // Correcting page number to be 1 based. this.getField(myPageNumName).value = i + 1; // Assign the current total number of pages. this.getField(myTotalField).value = numPages; } } }
Using the Prefix in the Fieldname
Once you have the prefix, it is easy to then address the fields on the form using the format:
Var myCompleteFieldName = this.getField(GetPrefix(pageNum) + "myTemplateFieldname");
AddPage( )
Finally, here is the code to spawn the template page, using bRename (the field renaming parameter). After the page is spawned, all page number totals are renumbered.
// Add a Continuation page. // // function AddPage(mPage) { // mPage is either template name of the template to be added // nPage - add this page to end of document // bRename - all fields on that page will be prefaced with: // ("P" + newPageNumberBase_0 + . + template name + . ) // bOverlay - don't overwrite an existing page. var contPage = this.getTemplate(mPage); contPage.spawn( { nPage:this.numPages, bRename:true, bOverlay:false }); // After adding the page, renumber all the pages and their totals. RenumberPages(); }