Archive for March, 2007

Where did that border come from?

Have you ever wondered to yourself, "where did that border come from?", when you simply wanted to set a field’s fill color? I know I did for a while until I learned about how the quirkiness of borders in XFA.

For example, if I wanted to set a field’s background (fill) color to green in a button’s Click event, the first thing I would do is:

this.fillColor = "0,255,0";

or

this.border.fill.color.value = "0,255,0";

Both methods amount to the same result which is the following:

Notice the black edge that appears around the perimeter of the field. What is that doing there? All I wanted to do was set the background color to highlight the field!

What I really wanted was this:

Is that too much to ask? All I did was set the fill color; I never messed with the edge, honestly!

In order to understand where that black edge came from and how to make it go away, we’ll need a better understanding of how borders are specified in XFA.

XFA Borders

First of all, the term "border" signifies all elements that compose the rectangular area that surrounds the entire field or the field’s value (two distinct borders). That means it’s made-up of corner, edge and fill properties, amongst others. In Designer, the field’s border is edited via the Border palette and the field value’s border is edited via the Appearance property on the Object palette’s Field tab.

Next is the fact that unlike most other XFA elements, the mere presence of the <border> element, and of some of its child elements such a <fill>, determine what the field’s border will look like. For instance, if no <border> element is specified, the field does not have a border even if the <border> element has a presence attribute with a default value of "visible". Likewise, if the <fill> element isn’t specified, the border has a transparent fill (i.e. no fill) even though it, too, has a presence attribute with a default value of "visible".

For example, the following field definition has no border:

<field></field>

If the <border> element is specified, then you also get the default <edge> element which is a thin black line and since specifying only a single <edge> element affects all sides of the border, you end-up with a black edge surrounding the border — just like in the first image above (without the green fill).

In this case, the field’s definition is simply this:

<field><border/></field>

When you use the script I proposed earlier for setting a field’s background (fill) color to green, this is what you get in the XFA syntax which describes the field:

<field>
    <border>
        <fill>
            <color value="0,255,0"/>
        </fill>
    </border>
</field>

As you can see, the <border> element has been specified and therefore the border gets the default thin black edge (even though an <edge> element wasn’t explicitly specified since an edge is implied when not explicitly specified).

Finally, edges and corners are a little tricky because there can be as little as none or as many as 4 <edge> and <corner> elements specified. What you need to remember is that they’re defined in clockwise order:

  • No <edge> element is the same as a single <edge> element which defines all edges at once (all 4 edges are identical).
  • Two <edge> elements define the top/bottom (edge 0) and left/right (edge 1) edges.
  • Three <edge> elements define the top (edge 0), left/right (edge 1) and bottom (edge 2) edges.
  • Four <edge> elements define the top (edge 0), right (edge 1), bottom (edge 2) and left (edge 3) edges.

The same goes for the <corner> element.

The Solution

So just how is it that we get rid of that edge? Well, given that the edge is implied (as mentioned earlier), all we have to do is hide it! It’s quite simple, in the end, yet quite frustrating if you don’t understand how borders work in XFA.

The <edge> element has a presence property which you can set to "hidden" in order to hide it. Therefore, the following script would set the field’s background (fill) color to green and ensure that the default black edge doesn’t appear along with it:

this.fillColor = "0,255,0";
border.edge.presence = "hidden";

That JavaScript, on a button’s Click event, will yield the border as I intended it to be (in the second image mentioned earlier).

Fun With Borders

In order to demonstrate a few things that can be done with borders using script (you may use similar scripts to show/hide borders on fields or field values for all kinds of purposes), I’ve provided this sample form. I encourage you to open it up in Designer and look at the script in order to get an idea for how you might implement your own border solution.

Download Sample [pdf]

Minimum Requirements: Designer 7.1, Acrobat 7.0.5.

ADBC Now Disabled by Default

Ever since the release of Acrobat 8.0 last November and, more recently, the Acrobat 7.0.9 update (for those still using Acrobat 7.x), I’ve had a few inquires about forms using ADBC (Acrobat DataBase Connectivity) that suddenly stop working.

The source of the problem is likely the fact that Acrobat 7.0.9 and 8.0 now disable ADBC by default, regardless of whether you were using it prior to the update or not. The reason behind this change is that ADBC poses a sizeable security risk as it doesn’t provide any mechanism to protect the databases it accesses from malicious use.

Although I wish the installation programs for Acrobat 7.0.9 and 8.0 would’ve warned users that ADBC was being disabled and provided them with information on re-enabling it rather than silently disabling it and causing people a lot of grief, I think disabling ADBC when it isn’t needed is much safer than leaving it enabled in case you ever need it.

Alternatively, you may choose to migrate to ODBC data connections in XFA forms (which you can save as PDF files for use in Acrobat). Since these are still enabled in Acrobat 7.0.9/8.0 and also make use of DSNs to locate and access databases, the migration should be relatively seamless to the people using your forms. Please note, however, that exposing a database to any type of audience always creates a certain security risk which should be assessed and addressed accordingly. You might consider creating a web service to act as the bridge between the database and your form (where your form retrieves data from and pushes data into a database via methods provided by a web service), thereby restricting access to your database’s structure and data.

For those needing to (re-)enable ADBC, the Acrobat 8 SDK Readme contains information on how to do that.
For your convenience, here is the excerpt which contains the instructions (as they were stated on December 13, 2006):

ADBC Support

Acrobat Database Connectivity (ADBC) can now be turned on and off via a registry setting. To activate ADBC, create a registry key of type DWORD with the name “bJSEnable” and a value of “true” (1) in the following location:

HKEY_CURRENT_USER\SOFTWARE\Adobe\Adobe Acrobat\8.0\ADBC

This activates ADBC in Acrobat 8.0. In previous releases of Acrobat, ADBC was active by default. In Acrobat 8.0, this setting has been changed to require user intervention to activate ADBC because most users do not want to have ADBC accessible from PDF.

Windows shell command to activate ADBC:

reg add “HKEY_CURRENT_USER\SOFTWARE\Adobe\Adobe Acrobat\8.0\ADBC” /v bJSEnable /t REG_DWORD /d 1

For Acrobat 7.0.9 users, simply change all instances of "8.0" to "7.0" in the above instructions.

Please note that since ADBC poses a security risk (as outlined earlier), Adobe does not recommend modifying the registry to re-enable this feature. Also note that ADBC is still only available via Acrobat Standard or Professional and on Windows only. The Adobe Reader does not have the ability to use ADBC.