Daniel Warren Daniel is a Java Developer at IDRsolutions and the product manager for FormVu. He enjoys experimenting with different computer systems, D&D, and a variety of PC games.

Do you need to display PDF Forms in a Browser?

Find out how FormVu can convert PDF Forms into HTML5

How PDF forms use JavaScript for validation

4 min read

A screenshot of a XFA PDF form

This blog post assumes you are aware of PDF forms. If this is a new topic for you, check out our introductory blog post.

PDF forms are able to utilize JavaScript as a dynamic way to get the form to include actions and perform calculations. Need to make sure a field only allows the user to input a number? You can do that. Want the next field to pre-populate depending on what option the user selected? You can do that too. In this post, I want to discuss how PDF forms can use JavaScript for validation.

AcroForms

To start with, I’ll discuss the different ways that an AcroForms file might allow for validation of the PDF. The main method that an AcroForms file will validate fields is defined in the fields’ additional-actions (AA) entry. This is a dictionary where you can define behaviour to happen at specific triggers/events. For form validation, the most relevant of these events are:

  • Bl
  • K
  • V

Bl (Uppercase B, Lowercase L)

The Bl event is triggered when an annotation loses the input focus. This is something that only works for Widget annotations, which form fields happen to be. Can be any action, including JavaScript.

K

The K event is triggered when the field is modified. This can be a character change in a text field, changing an option in a combo box, etc. It is an action that is only available for form fields and is limited to only JavaScript actions.

V

The V event is triggered when the value of a field is changed. It is different to the K event as it does not happen live as the changes are made, but once they are going to be set. V is considered the validation action and has the option to check the new value for validity (and reject it if it doesn’t meet the defined criteria). This is an action that is only available for form fields and is limited to only JavaScript actions.

An example of this could look like so:

Example 1
<<
  /Subtype /Widget
  /Type /Annot
  /AA
    <<
      /K 
        <<
          /S /JavaScript
          /JS (doSomething();)
        >>
    >>
>>

Which for the annotation in question, each time the field is modified, it will run the doSomething() function. This value can be a text string or a text stream, and allows you to write the JavaScript you want. The JavaScript has access to the Adobe JavaScript API, which can be used to influence other form fields, get info about the PDF, etc. When the events are called, they’re provided an event object. The object can contain the field value, the target object that triggered the event, the name of the event, etc.

Say, for example, you’re using the V event to refuse any value that doesn’t start with an ‘A’ character? You could use something along the lines of:

Example 2
if (event.target.value.charAt(0) !== 'A') {
  // Returning false on V events rejects the change and leaves the field unchanged
  return false;
}

For knowing all the possible events/actions, I recommend checking the API specification. But thanks to being able to use custom JavaScript and Adobe’s API, you are able to do a LOT for custom validation behaviour.

XFA

So what about XFA documents? Similar to AcroForms files, XFA does also have different events that can trigger on certain points. However, it also adds a validation element that you can attach to your fields.

Rather than Dictionary entries, the way the XFA implementation works is with either the <event> tag or the <validate> tag. Both tags implement things in a slightly different way.

<event> tags

Though there are many events, the most relevant for validation would be:

  • change
    • When the content changes by the user, such as a character change in a text field, pasting of content, etc.
  • exit
    • When the user exits the field, and is most comparable to the losing of focus for the field.
  • full
    • When the field reaches the character limit set (only if a character limit is set)

These events are set with the activity attribute, for example activity="change" and will affect what different event properties are available. All these events are not limited to script actions, but they are the most versatile option.

One thing to note is that XFA does also allow for FormCalc (another scripting language), but our focus is JavaScript. Make sure that any scripts are using the "application/x-javascript" contentType, otherwise they may default to FormCalc instead.

An example of using JavaScript in a change event in a text field could be:

Example 3
<field name="text" ...>
  <ui>
    <textEdit/>
  </ui>
  <event activity="change" name="event__change">
    <script contentType="application/x-javascript">
    doSomething();
    </script>
  </event>
</field>

This matches the behaviour of the prior AcroForms example. Each time the field is modified, it runs the doSomething() function. This JavaScript does not use the Adobe JavaScript API, and instead makes use of something called the Scripting Object Model (SOM). The SOM can be used to access all fields/behaviour in the PDF. With the XFA specification, the event objects will change depending on the event. Different properties get added in some circumstances and not others. For the change event, there are values like change (the change being made), prevText (the previous field value), & newText (the new full field value with the change added).

Using the SOM, you could also prevent any changes from the change event. For example, the JavaScript for stopping changes unless the first character of the field is an ‘A’ could be:

Example 4
if (xfa.event.newText.charAt(0) !== 'A') {
  // The change value is live, so can be set to do nothing
  xfa.event.change = "";
}

This works because the change value can be edited with the event. So you could also make use of it to change the characters to uppercase, lowercase, or anything else required.

<validate> tags

The other option XFA files have for validation are the <validate> tags. This tag contains options like nullTest, datatype, formatTest and our focus, the scriptTest. They offer the ability to output custom error messages, have better support for rejecting changes & will trigger at different events, such as at initialization and when the field has lost focus.

For a validate scriptTest, the JavaScript must return a value that is true in order to pass validation. And example of this would be:

Example 5
<field name="text" ...>
  <ui>
    <textEdit/>
  </ui>
  <validate>
    <script contentType="application/x-javascript">
    // Make sure to use rawValue to see the actual value of the field
    this.rawValue.chatAt(0) == 'A';
    </script>
  </validate>
</field>

Note that this will be a reference to the current element, so if you want to grab the value, you want to use the rawValue property.

Closing Thoughts

I hope that the above has explained how different PDFs can implement JavaScript and demonstrated different use cases. JavaScript is a very versatile tool and with the API’s provided (Adobe’s JavaScript API for AcroForms and the SOM for XFA) you can change just about any part of the PDF in a way that suits you. If you want to learn about every possibility, I’d highly suggest checking out their specification documents (which are freely available) and taking a look yourself.

Our team have been working hard on getting the AcroForms JavaScript working with our FormVu product. If you want to give it a test, you sign up for the trial and enable running with JavaScript.



FormVu allows you to

Use PDF Forms in the Web Browser
Integrate PDF Forms into Web Apps
Parse PDF forms as HTML5
Daniel Warren Daniel is a Java Developer at IDRsolutions and the product manager for FormVu. He enjoys experimenting with different computer systems, D&D, and a variety of PC games.

How to insert an image into a PDF

Recently, we released JPedal 2023.07 which contains the ability to insert images into PDF files. All you need is a copy of JPedal, a...
Jacob Collins
18 sec read