<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stefan Cameron on Forms &#187; AcroForm Objects</title>
	<atom:link href="http://forms.stefcameron.com/category/acroform-objects/feed/" rel="self" type="application/rss+xml" />
	<link>http://forms.stefcameron.com</link>
	<description>Building intelligent forms using Adobe LiveCycle Designer</description>
	<lastBuildDate>Wed, 16 Feb 2011 22:56:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>XFA and AcroForm Event Object Access</title>
		<link>http://forms.stefcameron.com/2009/01/14/xfa-and-acroform-event-object-access/</link>
		<comments>http://forms.stefcameron.com/2009/01/14/xfa-and-acroform-event-object-access/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 23:08:29 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/2009/01/14/xfa-and-acroform-event-object-access/</guid>
		<description><![CDATA[XFA forms are event-driven. Pretty much every action triggers an event and in that event (e.g. Initialize, Change, Click, etc.), you always have access to an xfa.event object (see the &#8220;eventPseudoModel&#8221; topic on page 63 of the Designer 8.2 Scripting Reference) and, depending on whether your form is running in Acrobat/Reader, you will also have [...]]]></description>
			<content:encoded><![CDATA[<p>XFA forms are event-driven. Pretty much every action triggers an event and in that event (e.g. Initialize, Change, Click, etc.), you always have access to an xfa.event object (see the &#8220;eventPseudoModel&#8221; topic on page 63 of the <a href="http://www.adobe.com/go/learn_lc_scriptingReference_82">Designer 8.2 Scripting Reference</a>) and, depending on whether your form is running in Acrobat/Reader, you will also have access to an <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm</a>&nbsp;<a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/JS_API_AcroJS.88.560.html">event</a> object.</p>
<p>I have discovered that <em>in that event</em> isn&#8217;t quite accurate. It should rather be stated as <em>within the context of that event.</em> That&#8217;s because any function calls that you make from the event handler (for instance, into a script object that contains other functions &#8212; maybe your event handler simply passes execution to a re-usable event handler function that you have defined in this script object) will have access to these very useful objects.</p>
<p>In essence, xfa.event and event (if defined) are, for lack of a better term, <em>contextual</em> objects that exist &#8212; and are valid &#8212; as long as you are within the context (where <em>context</em> is different from usual definition of <em>scope</em>) of an event handler.</p>
<p>I had a case, just recently, where I needed to access the event.target property (that is, the AcroForm <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/JS_API_AcroJS.88.374.html">Doc</a> object provided by Acrobat when it&#8217;s the host) in a function located inside a script object which I was calling from a subform&#8217;s Initialize event. At first, I thought I needed to pass it in as a parameter:</p>
<pre><code>// Subform Initialize Event handler code
utils.InitSubform(this, xfa.host.name == "Acrobat" ? event : null);

-----
utils Script Object
-----

function InitSubform(sf, hostEvent)
{
    ...
    if (hostEvent != null)
    {
        // access AcroForm Doc object from parameter
        var pdfDoc = hostEvent.target;
        ...
    }
    ...
}</code></pre>
<p>Unfortunately, this would&#8217;ve required updates to many forms since the script object was being used as a script object fragment and many forms were already using that function with only the first parameter.</p>
<p>Since the event object is actually available at that point in time, given that the handler is executing in the context of the subform&#8217;s Initialize event, I didn&#8217;t have to pass it in as a parameter and so I didn&#8217;t have to update a bunch of forms:</p>
<pre><code>// Subform Initialize Event handler code
utils.InitSubform(this);

-----
utils Script Object
-----

function InitSubform(sf)
{
    ...
    if (xfa.host.name == "Acrobat")
    {
        // access AcroForm Doc object from in-context event object
        var pdfDoc = event.target
        ...
    }
    ...
}</code></pre>
<p>Just remember that the xfa.event and event objects are only valid for the duration of the event which was triggered (so you shouldn&#8217;t hold on to them for future use) and that the event object is only available to you if the host is Acrobat/Reader (testing for xfa.host.name == &#8220;Acrobat&#8221; works for both Acrobat and Reader).</p>
<p>Tested with Adobe Acrobat and Reader 9.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2009/01/14/xfa-and-acroform-event-object-access/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Call Script Object Functions Later</title>
		<link>http://forms.stefcameron.com/2009/01/05/call-script-object-functions-later/</link>
		<comments>http://forms.stefcameron.com/2009/01/05/call-script-object-functions-later/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 18:41:09 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/2009/01/05/call-script-object-functions-later/</guid>
		<description><![CDATA[I hope you all had a great holiday! There&#8217;s suddenly lots of activity on my blog today so I assume most of you are back at it too. To kick things off in 2009, I thought I would start with a short but significant post on calling script object functions at a later time using [...]]]></description>
			<content:encoded><![CDATA[<p>I hope you all had a great holiday! There&#8217;s suddenly lots of activity on my blog today so I assume most of you are back at it too.</p>
<p>To kick things off in 2009, I thought I would start with a short but significant post on calling script object functions at a later time using Acrobat&#8217;s <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/JS_API_AcroJS.88.166.html">app.setTimeOut</a> JavaScript API. (<a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/JS_API_AcroJS.88.165.html">app.setInterval</a> is similar but requires a little more handling, to ensure you don&#8217;t leave the timer running when the form is closed, so I won&#8217;t cover that here. Check-out this <a href="http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/">sample</a> if you&#8217;re curious.)</p>
<p>I had long thought this wasn&#8217;t possible but recently <a href="http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/comment-page-1/#comment-36235">discovered</a> that it was, while helping-out one of my readers, in <strong>Acrobat/Reader 9</strong>.</p>
<h2>Theory</h2>
<p>The app.setTimeOut API requires that the first parameter be a string which is the script to be evaluated and executed when the timer expires. The second parameter is the number of milliseconds the host application (Acrobat) should wait before interpreting the script <strong>in the context of the document which set the timer</strong>. This means that the &#8220;this&#8221; object is an AcroForm <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/JS_API_AcroJS.88.374.html">Doc object</a>.</p>
<p>Given that an <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm</a> Doc object has an <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/JS_API_AcroJS.88.429.html">xfa</a> property (&#8220;defined only if the document is an XML form, that is, if the document was created in <a href="http://www.adobe.com/products/livecycle/designer/">LiveCycle Designer</a>&#8220;) which is &#8220;the root node of the underlying XFA model,&#8221; it follows that you can access properties of the XFA form contained within the PDF document from the AcroForm API. After all, that&#8217;s how I managed to get <a href="http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/">invalid fields to flash red</a> in a previous sample.</p>
<blockquote><p>By the way, if you&#8217;re writing AcroForm scripts and you want to verify whether the current document is an XFA-PDF (a PDF that contains an XFA form) or just a straight PDF document, you can simply test for <em>(typeof pdfDoc.xfa == &#8220;undefined&#8221;)</em>. If it&#8217;s true, it means you just have a plain PDF.</p></blockquote>
<p>When you put all of this together, it follows that you can effectively execute a script object function &#8220;later&#8221; as long as you address it properly using normal SOM expression rules. Since script objects are loaded into the Form DOM at runtime, you can access them via the <strong>xfa.form</strong> property. Once you&#8217;ve accessed the Form DOM, the first object you&#8217;ll need to reference is your root subform (the object at the very top of the tree, usually named &#8220;form1&#8243;, in Designer&#8217;s Hierarchy palette) and from there, your script object.</p>
<blockquote><p>Note that the AcroForm app object is only available when the host application running the PDF is Acrobat/Reader so this won&#8217;t work if you render your form as HTML using <a href="http://www.adobe.com/products/livecycle/forms/">LiveCycle Forms ES</a>, for example.</p></blockquote>
<h2>Sample</h2>
<p>If you had a function foo() in a script object &#8220;MyScripts&#8221; defined on the root subform &#8220;form1&#8243;, you would access it like this:</p>
<pre><code>xfa.form.form1.MyScripts.foo();</code></pre>
<p>If you didn&#8217;t know (or didn&#8217;t want to know) the name of the root subform ahead of time (say this function is accessed from a <a href="http://forms.stefcameron.com/category/form-fragments/">fragment</a> which is used in many different forms), you could refer to it like this:</p>
<pre><code>xfa.form.resolveNode("#subform[0]").MyScripts.foo();</code></pre>
<p>Finally, to call it 1 second later, you would simply do this:</p>
<pre><code>app.setTimeOut('xfa.form.resolveNode("#subform[0]").MyScripts.foo();', 1000);</code></pre>
<p><strong>Minimum Requirements:</strong> I’ve only tried this with Acrobat/Reader 9 however the JavaScript for Acrobat 9 Reference <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/JS_API_AcroJS.88.429.html">claims</a> that the xfa property is available since Acrobat/Reader 6.0.2. I&#8217;ll leave it up to you to try it out in previous versions. Please report back if you find that it works prior to Acrobat/Reader 9.</p>
<p class="postUpdate"><strong>Updated:</strong> January 5, 2009</p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2009/01/05/call-script-object-functions-later/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>No JavaScript for Acrobat 9 PDF Document</title>
		<link>http://forms.stefcameron.com/2008/12/08/no-javascript-for-acrobat-9-pdf-document/</link>
		<comments>http://forms.stefcameron.com/2008/12/08/no-javascript-for-acrobat-9-pdf-document/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 16:53:53 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/2008/12/08/no-javascript-for-acrobat-9-pdf-document/</guid>
		<description><![CDATA[For those of you still waiting for a PDF version of the JavaScript for Acrobat 9 API documentation, I have some unfortunate news: I have learned that there will be no PDF version issued. The only documentation available will be the LiveDocs version which I reported on earlier. I think that&#8217;s really unfortunate since PDFs [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you still waiting for a PDF version of the JavaScript for Acrobat 9 API documentation, I have some unfortunate news: I have learned that there will be no PDF version issued. The only documentation available will be the <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/wwhelp/wwhimpl/js/html/wwhelp.htm?&amp;accessible=true">LiveDocs version</a> which I <a href="http://forms.stefcameron.com/2008/09/29/livedocs-javascript-api-for-acrobat-9/">reported on earlier</a>.</p>
<p>I think that&#8217;s really unfortunate since PDFs (and CHMs) tend to be faster (no need to wait for page loads every time you select a topic), better indexed, easier to search and available offline. What&#8217;s your preference?</p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2008/12/08/no-javascript-for-acrobat-9-pdf-document/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>LiveDocs JavaScript API for Acrobat 9</title>
		<link>http://forms.stefcameron.com/2008/09/29/livedocs-javascript-api-for-acrobat-9/</link>
		<comments>http://forms.stefcameron.com/2008/09/29/livedocs-javascript-api-for-acrobat-9/#comments</comments>
		<pubDate>Mon, 29 Sep 2008 13:53:24 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/?p=204</guid>
		<description><![CDATA[If you&#8217;re like me, you&#8217;re still waiting for the PDF version to be posted since Acrobat 9 shipped last Summer (seems strange to say &#8220;last Summer&#8221; already!). In the mean time, I found the LiveDocs version online (once the page loads, click on &#8220;JavaScript &#62; JavaScript for Acrobat API Reference &#62; JavaScript API&#8221; in the [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me, you&#8217;re <a href="http://www.adobe.com/devnet/acrobat/javascript.html">still waiting</a> for the PDF version to be posted since Acrobat 9 shipped last Summer (seems strange to say &#8220;last Summer&#8221; already!). In the mean time, I found the <a href="http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/">LiveDocs version</a> online (once the page loads, click on &#8220;JavaScript &gt; JavaScript for Acrobat API Reference &gt; JavaScript API&#8221; in the table of contents on the left hand side). It&#8217;s not as &#8220;rich&#8221; as the PDF version but it&#8217;ll do for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2008/09/29/livedocs-javascript-api-for-acrobat-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using URL Requests in PDF Forms</title>
		<link>http://forms.stefcameron.com/2006/10/20/using-url-requests-in-pdf-forms/</link>
		<comments>http://forms.stefcameron.com/2006/10/20/using-url-requests-in-pdf-forms/#comments</comments>
		<pubDate>Fri, 20 Oct 2006 19:07:10 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/blog/?p=49</guid>
		<description><![CDATA[Here&#8217;s a sample in response to Ernest&#8217;s question on passing values to PDF forms via URL. His intent is to use it to provide a key to a PDF form such that it can be used to filter records from an ODBC Data Connection in order to pre-populate the form with data. I love these [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a sample in response to <a href="http://forms.stefcameron.com/2006/09/29/selecting-specific-database-records/#comment-335">Ernest&#8217;s question</a> on passing values to <span class="caps">PDF </span>forms via <span class="caps">URL.</span> His intent is to use it to provide a key to a <span class="caps">PDF </span>form such that it can be used to filter records from an <a href="http://forms.stefcameron.com/2006/09/18/connecting-a-form-to-a-database/"><span class="caps">ODBC</span> Data Connection</a> in order to pre-populate the form with data.</p>
<p>I love these kinds of questions because they challenge me to find answers!</p>
<p>Of course, this is quite specific but there are many other uses for this. In fact, you could have a whole lot of fun with it too! You could even use this to alter the appearance of your form: Say you had one form that you were using for multiple departments in your company and every department had its own header. You could place each header in a subform, make them all hidden and then, based on the <span class="caps">URL </span>request which would include a department code, decide which one to show &#8212; no <span class="caps">XML</span> Data file, database connection or web service needed!</p>
<p>Beware, however, that <span class="caps">URL </span>request strings are <strong>not secure</strong> because they get posted in plain text for anyone to read so be careful of the information you pass-in to your form this way.</p>
<p>This sample form looks for a &#8220;message&#8221; and a &#8220;color&#8221; key in the <span class="caps">URL </span>request in order to show a message in a text field and change the text field content area&#8217;s color (an <span class="caps">RGB </span>value). For example:</p>
<ul>
<li> <a href="http://forms.stefcameron.com/samples/URLRequests.pdf?message=Isn't%20this%20cool?">//URLRequests.pdf?message=Isn&#8217;t%20this%20cool%3F</a>  &#8212; Shows the message &#8220;Isn&#8217;t this cool?&#8221; in the text field.</li>
<li><a href="http://forms.stefcameron.com/samples/URLRequests.pdf?message=Think%20of%20the%20possibilities...&amp;color=0%2C255%2C0">//URLRequests.pdf?message=Think%20of%20the%20possibilities&#8230;&amp;color=0%2C255%2C0</a> &#8212; Shows the message &#8220;Think of the possibilities&#8230;&#8221; in the text field and makes the text field green.</li>
</ul>
<p><a href="http://forms.stefcameron.com/samples/URLRequests.pdf">Download Sample [pdf]</a></p>
<p><strong>Minimum Requirements:</strong> Designer 7.0, Acrobat 7.0.</p>
<p>The trick to all this is obtaining the <span class="caps">URL </span>that was used to access the <span class="caps">PDF </span>form. This can easily be achieved by accessing the <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">Acrobat Document Object</a> associated with the form and then obtaining the value of its <em><span class="caps">URL</span></em> property. This is done in JavaScript via the &#8220;Message&#8221; text field&#8217;s Initialize event:</p>
<pre><code>event.target.URL</code></pre>
<p>This property will give you the following string (from the second sample <span class="caps">URL</span> I provided earlier):</p>
<pre><code>//URLRequests.pdf?message=Think%20of%20the%20possibilities...&amp;color=0%2C255%2C0 </code></pre>
<p>From there, it&#8217;s just simple JavaScript code to extract the request</p>
<pre><code>?message=Think%20of%20the%20possibilities...&amp;color=0%2C255%2C0</code></pre>
<p>and then parse the key/value pairs</p>
<pre><code>message=Think%20of%20the%20possibilities...
color=0%2C255%2C0</code></pre>
<p>Finally, since we&#8217;re passing-in a string that may contain spaces which will have been <span class="caps">URI</span>-encoded (that&#8217;s use of &#8220;%20&#8221; instead of spaces and &#8220;%2C&#8221; instead of commas in the request string), we need to decode it back to a normal string using JavaScript&#8217;s built-in &#8220;decodeURI&#8221; and &#8220;decodeURIComponent&#8221; functions:</p>
<pre><code>decodeURI(decodeURIComponent(string))</code></pre>
<p>If you want to have fun submitting different strings to show in the message box, I found a little tool online which <a href="http://www.blooberry.com/indexdot/html/topics/urlencoding.htm">converts regular strings into <span class="caps">URI</span>-encoded strings</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2006/10/20/using-url-requests-in-pdf-forms/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Invalid Flashing Fields 2.0</title>
		<link>http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/</link>
		<comments>http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/#comments</comments>
		<pubDate>Tue, 15 Aug 2006 21:18:30 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/blog/?p=33</guid>
		<description><![CDATA[A colleague of mine here at Adobe pointed-out today that the use of the AcroForm Document object&#8217;s getField method wasn&#8217;t necessary in the script I used for my original Invalid Flashing Fields sample. There&#8217;s an alternative which uses xfa.form.resolveNode in the app.setInterval script. xfa.form.resolveNode takes a SOM Expression and returns a reference to an XFA [...]]]></description>
			<content:encoded><![CDATA[<p>A colleague of mine here at Adobe pointed-out today that the use of the AcroForm Document object&#8217;s <em>getField</em> method wasn&#8217;t necessary in the script I used for my original <a href="http://forms.stefcameron.com/2006/06/18/invalid-flashing-fields/">Invalid Flashing Fields</a> sample.</p>
<p>There&#8217;s an alternative which uses <em>xfa.form.resolveNode</em> in the <em>app.setInterval</em> script. <em>xfa.form.resolveNode</em> takes a <span class="caps">SOM</span> Expression and returns a reference to an <span class="caps">XFA </span>node. What&#8217;s more is that this <span class="caps">API </span>call can be made from within the context of the <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm</a> Scripting Object Model.</p>
<p>The <em>app.setInterval</em> script therefore changes from this:</p>
<pre><code>moFlashTimerID = app.setInterval(
  &quot;var f = <b> this.getField('&quot; +
    GetAcroFormFieldName(oField) + &quot;'); </b> &quot; +
  &quot;if (color.equal(f.fillColor, color.red))&quot; +
    &quot;{ f.fillColor = [&quot; + moAcroFieldFillColor.toString() + &quot;]; }&quot; +
  &quot;else&quot; +
    &quot;{ f.fillColor = color.red; }&quot;,
500);</code></pre>
<p>to this:</p>
<pre><code>moFlashTimerID = app.setInterval(
  &quot;var f = <b> xfa.form.resolveNode('&quot; +
    oField.somExpression + &quot;'); </b> &quot; +
  &quot;if (f.ui.oneOfChild.border.fill.color.value == '255,0,0')&quot; +
    &quot;{ f.ui.oneOfChild.border.fill.color.value = '232,232,232'; }&quot; +
  &quot;else&quot; +
    &quot;{ f.ui.oneOfChild.border.fill.color.value = '255,0,0'; }&quot;,
500);</code></pre>
<p>Also note the changes in the way the color values are compared and assigned (whereby the newer version uses more familiar XFA script rather than the AcroForm script from the first version).</p>
<p>Since the use of the <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm</a> Scripting Object Model should <strong>always</strong> be secondary to using the <span class="caps">XFA</span> Scripting Object Model (because AcroForm objects are, after all, in a separate Object Model which may change separately from the <span class="caps">XFA</span> Scripting Object Model), I wanted to highlight this alternative which makes more extensive use of the <span class="caps">XFA</span> Scripting Object Model than the first version did.</p>
<p><a href="http://forms.stefcameron.com/samples/acroform/InvalidFlashingFields-WithoutAFGetField.pdf">Download Sample [pdf]</a></p>
<p><strong>Minimum Requirements:</strong> Designer 7.1, Acrobat 7.0.5.</p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Tracking Mouse Clicks</title>
		<link>http://forms.stefcameron.com/2006/08/04/tracking-mouse-clicks/</link>
		<comments>http://forms.stefcameron.com/2006/08/04/tracking-mouse-clicks/#comments</comments>
		<pubDate>Sat, 05 Aug 2006 03:54:38 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/blog/?p=31</guid>
		<description><![CDATA[I just recently received another comment from Zack. This time, he was wondering about how one would go about tracking mouse clicks on an image field. I had never attempted to do that so I took it on as a challenge and thought I would share the results in this post. I knew from the [...]]]></description>
			<content:encoded><![CDATA[<p>I just recently received another <a href="http://forms.stefcameron.com/2006/08/02/auto-localizing-your-forms/#comment-161">comment from Zack</a>. This time, he was wondering about how one would go about tracking mouse clicks on an image field.</p>
<p>I had never attempted to do that so I took it on as a challenge and thought I would share the results in this post.</p>
<p>I knew from the start that <span class="caps">XFA </span>alone wasn&#8217;t going to be able to handle this simply because (to my knowledge) it doesn&#8217;t provide any information as to the position of the mouse pointer when an event occurs. The most logical place I thought would&#8217;ve provided the information &#8212; the <em>Event Pseudo Model</em> (the xfa.event object available in all <span class="caps">XFA </span>events) &#8212; didn&#8217;t live up to my expectations. Thankfully, <span class="caps">XFA </span>at least provides a Click event so that I could know when the image got clicked.</p>
<p>The next logical place to look was in Acrobat&#8217;s Scripting Object Model (in the <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm Objects</a>). In the Acrobat Document object, I found  what I was looking for: the <em>mouseX</em> and <em>mouseY</em> properties which provided the location of the mouse with respect to the document window.</p>
<p>The last thing I needed was information about the dimensions and location (within the Acrobat Document Object&#8217;s coordinate space) of the image field and the Acrobat Field object&#8217;s <em>rect</em> property would give me just that.</p>
<p>The combination of the <span class="caps">XFA</span> Click event, the Acrobat Document object&#8217;s mouseX and mouseY properties and the Field object&#8217;s rect property was just what I needed to get this to work.</p>
<p>Of course, I soon discovered that I had another problem to figure-out: The behaviour of an image field in a <span class="caps">PDF </span>form running in Acrobat is that when clicked, it opens a browse dialog that lets you pick the content for the field. Unfortunately, there isn&#8217;t any way to suppress that dialog other than making the image field read-only or by using a static image object but then both alternatives prevent the Click event from firing. So I needed some clever way to capture a mouse click over an image (whether it was a field or a static object) and I decided to use a button with a transparent fill and no border (so it was essentially transparent). Since buttons are fields just like image fields, the mouseX, mouseY and rect properties would still be available for the button and if I sized the button to fit the image and placed it over-top, I would essentially end-up with an <span class="caps">HTML </span>&lt;map&gt;.</p>
<p><a href="http://forms.stefcameron.com/samples/acroform/TrackingMouseClicks.pdf">Download Sample [pdf]</a></p>
<p><strong>Minimum Requirements:</strong> Designer 7.1, Acrobat 7.0.5.</p>
<p>The first challenge was getting an instance of the Acrobat Field object which represents the button using the</p>
<pre><code>event.target.getField</code></pre>
<p>method. That was easily accomplished by using the script I provided on my <a href="http://forms.stefcameron.com/2006/06/14/acroform-field-name-generator/">AcroForm Field Name Generator</a> article.</p>
<p>The next problem to be solved was the fact that the default behaviour, in Acrobat, for a button when it&#8217;s clicked is to invert its content area. Since I was trying to hide the button, I needed a way to suppress the inversion so that clicking on the button would give no visual feedback to the user. That way, it would give the impression that the user was actually clicking on some sort of hyperlink on the image itself. That was easily solved by using the <em>highlight</em> property of the Acrobat Field object representing the <span class="caps">XFA </span>button in its Enter event (had to be Enter and not Initialize because Initialize is too early in the form&#8217;s initialization process for the association between the <span class="caps">XFA </span>button and it&#8217;s Acrobat Field counterpart to be established):</p>
<pre><code>event.target.getField(ScriptObject.GetFQSOMExp(this)).highlight =
  highlight.n;</code></pre>
<p>The last problem was with respect to calculating the coordinates of the hot spots on the button that would trigger a reaction (in this sample, I was just going to set the value of a text field somewhere else on the form to reflect the area that was clicked). The problem there was that while I had the mouse location and the button&#8217;s dimensions all in the same coordinate space (Acrobat Document), the coordinates were specified with (0,0) set to the document&#8217;s <strong>lower</strong> left corner.</p>
<p>While this may not seem like a big deal to some of you, it really messes me up when (0,0) isn&#8217;t at the <strong>top</strong> left corner (with the maximum (x,y) set to the bottom right corner). I guess that&#8217;s a result of years of writing code for Windows where an <span class="caps">MFC</span> CWnd&#8217;s coordinate space places (0,0) at the top left corner. Anyway, after lots of hair pulling, I finally figured-out how to properly calculate the hot spots in this strange &#8212; no, alien &#8212; coordinate system.</p>
<p>Zack, if you have any other questions, please post a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2006/08/04/tracking-mouse-clicks/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Invalid Flashing Fields</title>
		<link>http://forms.stefcameron.com/2006/06/18/invalid-flashing-fields/</link>
		<comments>http://forms.stefcameron.com/2006/06/18/invalid-flashing-fields/#comments</comments>
		<pubDate>Sun, 18 Jun 2006 04:14:45 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/blog/?p=21</guid>
		<description><![CDATA[So what&#8217;s the use of learning about new toys like AcroForm Objects and AcroForm Field Name Generators if you don&#8217;t take the time to play with them? Today felt like the right day to do just that and I came-up with a sample form where invalid fields flash red until the user has entered valid [...]]]></description>
			<content:encoded><![CDATA[<p>So what&#8217;s the use of learning about new toys like <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm Objects</a> and <a href="http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/">AcroForm Field Name Generators</a> if you don&#8217;t take the time to play with them? Today felt like the right day to do just that and I came-up with a sample form where invalid fields flash red until the user has entered valid values into them. Only once all fields are valid can the form be submitted.</p>
<p><span style="color:red"><strong>Update:</strong> Check-out the newer version on the new <a href="http://forms.stefcameron.com/2006/08/15/invalid-flashing-fields-20/">Invalid Flashing Fields 2.0</a> post. </span></p>
<p><a href="http://forms.stefcameron.com/samples/acroform/InvalidFlashingFields.pdf">Download Sample [pdf]</a></p>
<p><strong>Minimum Requirements:</strong> Designer 7.1, Acrobat 7.0.5.</p>
<p><strong>Note:</strong> A basic understanding of <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm Objects</a> is required for this sample.</p>
<p>The sample form works like this: When the user clicks on the Submit button, there&#8217;s a script which looks at all fields on the form and validates them for valid content. In this particular form, the only requirement is for the fields to be filled (i.e. have non-null values). If all fields are filled, the form is them submitted however, if there&#8217;s at least one field which isn&#8217;t filled, the first-found non-filled field is set to flash red until the user has filled it.</p>
<p>Since <span class="caps">XFA </span>doesn&#8217;t natively support flashing fields, this is all done using the Acrobat <em>app</em>, <em>Document</em> and <em>Field</em> objects, discussed in greater detail in my previous post on <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm Objects</a>, as well as my <a href="http://forms.stefcameron.com/2006/06/14/acroform-field-name-generator/">AcroForm Field Name Generator</a> code.</p>
<p>When a non-filled field is found, the Submit button&#8217;s script will get the AcroForm Field object name for the invalid field and use it to generate a small script which will run every time an Acrobat Timer object expires. This timer is created in the following block of code:</p>
<pre><code>moFlashTimerID = app.setInterval(
    &quot;var f = this.getField('GetAcroFormFieldName(oField)');&quot; +
    &quot;if (color.equal(f.fillColor, color.red))&quot; +
    &quot;{ f.fillColor = [&quot; + moAcroFieldFillColor.toString() + &quot;]; }&quot;

    &quot;else&quot; +
    &quot;{ f.fillColor = color.red; }&quot;,
  500);</code></pre>
<p>In this block of code, the Acrobat app object&#8217;s <em>setInterval</em> method is used to create a timer which will continously expire at a specific interval (in this case, every 500 milliseconds, or 0.5 seconds) and every time it expires, it&#8217;ll execute the code specified in the first parameter. Since the timer&#8217;s code will execute within the context of the document from which the <em>setInterval</em> method was called, the <em>this</em> keyword will represent Acrobat Document object pertaining to the form. The <em>GetAcroFormFieldName</em> method can then be used to get the AcroForm Field object name pertaining to the invalid field (<em>oField</em>) which is then passed to the Acrobat Document object&#8217;s <em>getField</em> method. From there, the AcroForm Field&#8217;s fill color is compared to red: If it&#8217;s already red, it&#8217;s set to a light gray color; otherwise, it&#8217;s set to red.</p>
<p>It&#8217;s important to note that the <em>setInterval</em> method returns an Acrobat Interval object which can subsequently be used to cancel the interval timer in order to get the field to stop flashing red once the user has filled it with a value. This object is also required in order to <strong>ensure the timer is stopped when the form is closed</strong> if the user ever decides to close the form while an invalid field is flashing (see the code in the root subform&#8217;s (form1) DocClose event).</p>
<p><sub class="postUpdate"><strong>Updated:</strong> August 15, 2006</sub></p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2006/06/18/invalid-flashing-fields/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>AcroForm Field Name Generator</title>
		<link>http://forms.stefcameron.com/2006/06/14/acroform-field-name-generator/</link>
		<comments>http://forms.stefcameron.com/2006/06/14/acroform-field-name-generator/#comments</comments>
		<pubDate>Wed, 14 Jun 2006 16:54:21 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/blog/?p=20</guid>
		<description><![CDATA[So you&#8217;ve read my previous post about AcroForm Objects and now you&#8217;re wondering what you do with that stuff. Those more adventurous might even have tried to use the event.target.getField method to do something cool. If you&#8217;re going to do things on the application or the document without attempting to affect a specific field, it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>So you&#8217;ve read my previous post about <a href="http://forms.stefcameron.com/2006/06/10/acroform-objects/">AcroForm Objects</a> and now you&#8217;re wondering what you do with that stuff. Those more adventurous might even have tried to use the <em>event.target.getField</em> method to do something cool.</p>
<p>If you&#8217;re going to do things on the application or the document without attempting to affect a specific field, it&#8217;s pretty straight-forward: You just call methods on the <em>app</em> (Acrobat Application) or <em>event.target</em> (Acrobat Document) objects. Getting an AcroForm Field object, however, isn&#8217;t as simple as you may think because of the naming conventions used when the Acrobat Form objects are created, based on the <span class="caps">XFA</span> Form objects.</p>
<p>Let&#8217;s say you have a field, named &#8220;MyField&#8221;, parented to the second page, named &#8220;Page2&#8221;, of your form, named &#8220;form1&#8221;. For some reason, you need to access that field&#8217;s pertaining AcroForm Field object. If you tried</p>
<pre><code>event.target.getField(&quot;MyField&quot;)</code></pre>
<p>you wouldn&#8217;t get very far because the actual name of the field is:</p>
<pre><code>form1[0].Page2[0].MyField[0]</code></pre>
<p>Basically, each AcroForm Field object is named with a <em>verbose</em> form of the <a href="http://forms.stefcameron.com/2006/06/05/xfa-som-expression-generator/">XFA SOM Expression</a> of its pertaining <span class="caps">XFA</span> Form object (also known as a <strong>Fully-Qualified <span class="caps">SOM</span> Expression</strong>).</p>
<p>To help with generating the correct AcroForm Field name for a given <span class="caps">XFA</span> Form object, I thought I would write a little bit of script which outputs the Fully-Qualified <span class="caps">SOM</span> Expression (which is the AcroForm Field name) for a given <span class="caps">XFA</span> Form object:</p>
<pre><code>// Returns the fully-qualified name for the specified object.
//  This means the name always specifies the index.
//  Therefore, if the name is specified, it's &quot;name[index]&quot;.
//  If the name isn't specified, it's &quot;#className[index]&quot;.
function GetVerboseFieldName(oNode)
{
  // Unnamed nodes have default names which their class name
  //  (&quot;subform&quot;, &quot;field&quot;, etc.) with a &quot;#&quot; prefix.
  //  Unfortunately, oNode.name won't return this if the node
  //  doesn't have a specific name. It'll just return an empty
  //  string. Also, oNode.index will be undefined. If it weren't
  //  for oNode.index being undefined in this case, we could've
  //  done something like
  //  SOM = &quot;#&quot; + oNode.className + &quot;[&quot; + oNode.index + &quot;]&quot;

  //  but we'll have to use the somExpression property instead
  //  and extract the name out of it because this will return
  //  the &quot;#&quot; name with the correct index.
  // Since somExpression returns the name and index for the
  //  object in all cases (whether the name is specified or
  //  not), we can use the following syntax in all cases:

  var nPos = oNode.somExpression.lastIndexOf(&quot;.&quot;);

  // If the field has a name, check to see if it has any periods in its name.
  // If that's the case, they'll be escaped with backslashes and we need to
  //  look for another period.
  if (oNode.name != null &amp;&amp; oNode.name.length &gt; 0)
  {
    while (nPos &gt; 0)
    {
      if (oNode.somExpression.charAt(nPos - 1) == &quot;\\\\&quot;)
      {
        // we found an escaped period, keep looking
        nPos = oNode.somExpression.lastIndexOf(&quot;.&quot;, nPos - 1);
      }
      else
      {
        // stop looking since we have an unescaped period
        break;
      }
    }
  }

  if (nPos &gt;= 0)
  {
    // get everything after the last &quot;.&quot; to the end
    return oNode.somExpression.substr(nPos + 1);
  }
  else
  {
    // in this case, the SOM expression is a single name (unlikely
    //  but theoretically possible)
    return oNode.somExpression;
  }
}

// Returns the Fully-Qualified SOM Expression for the specified field.
function GetFQSOMExp(oField)
{
  var sFQFieldName = GetVerboseFieldName(oField);
  var oParentNode = oField.parent;

  // The absolute root of the XFA Object Model is the xfa object
  //  which contains a single form object, which then contains
  //  what the Hierarchy palette shows as being the &quot;root
  //  subform&quot; (&quot;form1&quot; by default). So we stop when we reach
  //  xfa.form.
  while (oParentNode != xfa.form)
  {
    sFQFieldName = GetVerboseFieldName(oParentNode) +
      &quot;.&quot; + sFQFieldName;
    oParentNode = oParentNode.parent;
  }

  return sFQFieldName;
}</code></pre>
<p>You can now take this code and either place it directly inside the event in which you need an <span class="caps">XFA</span> Form object&#8217;s pertaining AcroForm Field name and call it directly or you can place it in a form-wide Script Object where you can access the code from anywhere.</p>
<p>With this code, changing an <span class="caps">XFA</span> Button object&#8217;s <em>highlight</em> property such that it gets an outline rectangle when clicked (as opposed to the default which is an inverted fill color) is as easy as this (in JavaScript in the button&#8217;s Enter event, assuming you&#8217;ve placed the above code directly inside the Enter event):</p>
<pre><code>event.target.getField(GetFQSOMExp(this)).highlight =
  highlight.o;</code></pre>
<p>Beautiful? I think so. Get the <a href="http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html#js">Acrobat JavaScript Scripting Reference</a> and go crazy! Just remember: This functionality is <strong>only available when your form is loaded in Acrobat</strong>.</p>
<p><sub class="postUpdate"><strong>Updated:</strong> February 14, 2007 &#8212; Added support for <a href="http://forms.stefcameron.com/2007/02/14/accessing-objects-with-periods-in-their-names/">objects with periods in their names</a>.</sub></p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2006/06/14/acroform-field-name-generator/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>AcroForm Objects</title>
		<link>http://forms.stefcameron.com/2006/06/10/acroform-objects/</link>
		<comments>http://forms.stefcameron.com/2006/06/10/acroform-objects/#comments</comments>
		<pubDate>Sun, 11 Jun 2006 03:53:37 +0000</pubDate>
		<dc:creator>Stefan Cameron</dc:creator>
				<category><![CDATA[AcroForm Objects]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://forms.stefcameron.com/blog/?p=18</guid>
		<description><![CDATA[Today I thought I would tackle the subject of AcroForm Objects &#8212; objects available via scripting in the Acrobat Form Object Model &#8212; because they offer unique possibilities for your forms when they&#8217;re running in Acrobat in the PDF format. Just to be clear, AcroForms are specific to Acrobat and therefore this functionality doesn&#8217;t apply [...]]]></description>
			<content:encoded><![CDATA[<p>Today I thought I would tackle the subject of AcroForm Objects &#8212; objects available via scripting in the Acrobat Form Object Model &#8212; because they offer unique possibilities for your forms <strong>when they&#8217;re running in Acrobat in the <span class="caps">PDF </span>format</strong>.</p>
<p>Just to be clear, AcroForms are <strong>specific to Acrobat</strong> and therefore this functionality doesn&#8217;t apply when rendering your forms to a target other than <span class="caps">PDF </span>(e.g. when using <a href="http://www.adobe.com/products/server/formserver">LiveCycle Forms</a> to render your <span class="caps">XFA</span> Forms as <span class="caps">HTML</span>).</p>
<p>First, let&#8217;s explain what <span class="caps">XFA </span>(XML Forms Architecture &#8212; a <a href="http://www.w3.org/1999/05/XFA/xfa-template"><span class="caps">W3C</span> Submission</a>) does: It lets you describe a form, using a defined set of rules that govern an <span class="caps">XML </span>structure, which can target many different clients (e.g. <span class="caps">PDF, HTML, </span>etc.) &#8212; as long these clients support the <span class="caps">XFA </span>format. Today, the Adobe LiveCycle Designer targets <span class="caps">PDF </span>out-of-the-box and, along with <a href="http://www.adobe.com/products/server/formserver">LiveCycle Forms</a>, targets <span class="caps">HTML.</span></p>
<p>The fact that <span class="caps">XFA </span>is always translated into a format which can be understood by a client with which a user interacts in order to fill a form and possibly submit its data to a receiver means that the scripts you write in your <span class="caps">XFA </span>forms get executed in the target client application (such as Acrobat or a web browser). If the target client also contains a Scripting Object Model &#8212; like Acrobat does &#8212; there may be ways that you can take advantage of specific functionality exposed by the client which is hosting your <span class="caps">XFA </span>forms.</p>
<p>This brings us to the topic at hand: <a href="http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html#js">Acrobat&#8217;s Form (AcroForm) Object Scripting Model</a>. If you&#8217;re designing your form only to target <span class="caps">PDF </span>(or you add code to your form to detect when your form is being hosted by Acrobat using xfa.host.name, for example), you can get access to the Acrobat <em>app</em>, <em>Document</em> and <em>Field</em> objects, amongst others, and do some really cool things like have a <a href="http://forms.stefcameron.com/2006/06/18/invalid-flashing-fields/">field with invalid data start flashing red</a> when the user attempts to submit the form&#8217;s data.</p>
<h2>xfa.host</h2>
<p>When writing scripts in an <span class="caps">XFA </span>form, you have access to the special <em>xfa.host</em> object. This object gives you access to methods which are <strong>specific to the application hosting your form</strong> (such as Acrobat, a form server or a web browser). For example, the</p>
<pre><code>xfa.host.name</code></pre>
<p>property tells you the name of the application hosting your form at the time the script is interpreted. If your form is being viewed/hosted in Acrobat, this property will return &#8220;Acrobat&#8221; while it&#8217;ll return the name of the browser if it has been served to a web browser. Furthermore, it&#8217;ll return &#8220;Presentation Agent&#8221; if the script was flagged to run on the server and the server application serving the form to <span class="caps">PDF </span>or <span class="caps">HTML </span>is Adobe&#8217;s <a href="http://www.adobe.com/products/server/formserver">LiveCycle Forms</a> product.</p>
<p>xfa.host also gives you access to other properties and functions such as</p>
<pre><code>xfa.host.messageBox // displays a dialog box on the screen
xfa.host.validationsEnabled // turns the form's validations on/off with a single call</code></pre>
<p>but take note that not all functions and properties are available on all hosts (e.g. since a server host can&#8217;t display a dialog which requires user input, the xfa.host.messageBox function is only supported on <em>client</em> hosts like Acrobat and web browsers).</p>
<p>You can obtain more information on xfa.host on page 185 of the <a href="http://www.adobe.com/devnet/livecycle/designing_forms.html">Adobe <span class="caps">XML</span> Form Object Model Reference</a>.</p>
<h2>Acrobat app Object</h2>
<p>Since the scripts you write in functions and events within an <span class="caps">XFA </span>form are interpreted by and executed within the context of Acrobat&#8217;s Scripting Engine, you have access to a special object called <em>app</em>. This object gives you access to the collection of active documents and plugins, amongst other things, and lets you display alert messages</p>
<pre><code>app.alert(&quot;Hello world!&quot;);</code></pre>
<p>and even set Acrobat into full screen mode with a red background!</p>
<pre><code>app.fs.backgroundColor = color.red;
app.fs.isFullScreen = true;</code></pre>
<p>Note that while <em>color.red</em> isn&#8217;t an object provided by the <span class="caps">XFA</span> Scripting Object Model, it still exists within the context of your scripts because the scripts are ultimately interpreted and executed within Acrobat. You can get more information on the <em>app</em> object in the <a href="http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html#js">Acrobat JavaScript Scripting Reference</a>.</p>
<h2>xfa.event</h2>
<p>This is a special object which exists only via the <span class="caps">XFA</span> Plugin which executes <span class="caps">XFA </span>scripts on <span class="caps">XFA </span>object events inside Acrobat. Whenever an event occurs (such as the click of a button or a field gaining input focus), your script has access to the <em>xfa.event</em> object which gives lots of important information about the event.</p>
<p>For example, if you want to know the value that was selected in a list box or a drop down list in order to change the state of another object on your form, you would script against the list box&#8217;s or drop down list&#8217;s Change event. If you used the following code to get the value of the item that the user selected:</p>
<pre><code>this.rawValue</code></pre>
<p>you would get the previously-selected value because the object&#8217;s rawValue property isn&#8217;t updated until after the Change event has occurred. In order to get the information you need, you must use the following code:</p>
<pre><code>xfa.event.newText</code></pre>
<p>which will give you the value of the item the user just selected.</p>
<p><em>xfa.event</em> also gives you access to a very useful property called <em>target</em>: In Acrobat, this property specifies the Acrobat <em>Document</em> object (which contains the Acrobat <em>Field</em> object which wraps the <span class="caps">XFA </span>object whose event is being scripted). This means that you can get at the Acrobat <em>Document</em> object for the &#8220;active document&#8221; just by using:</p>
<pre><code>event.target</code></pre>
<p>(Note that you don&#8217;t need &#8212; and shouldn&#8217;t use &#8212; the &#8220;xfa&#8221; prefix when accessing the &#8220;event.target&#8221; property &#8212; I don&#8217;t know why yet but you&#8217;ll have trouble using it if you use the &#8220;xfa.event.target&#8221; syntax.)</p>
<p>Using this information, you can:</p>
<pre><code>event.target.zoom *= 2; // increase the zoom level two-fold
event.target.zoomType = zoomtype.fitW; // zoom to page-width level
event.target.zoomType = zoomtype.fitH; // zoom to page-height level</code></pre>
<p>or you can use the <em>getField</em> method to get an Acrobat <em>Field</em> object and do some more interesting things.</p>
<p>You can get more information on the <em>Document</em> and <em>Field</em> objects in the <a href="http://partners.adobe.com/public/developer/acrobat/sdk/index_doc.html#js">Acrobat JavaScript Scripting Reference</a>.</p>
<h2>Putting it all Into Perspective</h2>
<p>To tie this all together, I&#8217;ve drawn-up a <strong>simplified</strong> version of the Scripting Object Model the way I picture it in my head:</p>
<p><img alt="Scripting Object Model (simplified)" src="http://forms.stefcameron.com/images/AcrobatSOM.gif" width="400" height="305"/></p>
<p>This image illustrates how things work from the perspective of a script running within an <span class="caps">XFA</span> Event or an <span class="caps">XFA</span> Script Object Function (note that you don&#8217;t have access to the xfa.event object there unless you pass it into the function by calling it from an <span class="caps">XFA</span> Event). You can see how, from the <span class="caps">XFA </span>object, you can get to the:</p>
<ul>
<li>Acrobat app object (directly);</li>
<li>Acrobat Document object (via event.target or the app object);</li>
<li>Acrobat Field object (via the Document object);</li>
<li>xfa.host object (directly).</li>
</ul>
<p>Hopefully this post will have given you a general idea of the <strong>Acrobat-specific</strong> tools at your disposal when you&#8217;re writing <span class="caps">XFA </span>scripts using the JavaScript language. Please note, however, that changes may occur to the way <span class="caps">XFA</span> Form Objects are hosted within Acrobat in future releases and therefore using the AcroForm Object Model should be a <strong>last resort</strong> if an <span class="caps">XFA </span>equivalent simply isn&#8217;t available.</p>
<p><sub class="postUpdate"><strong>Updated:</strong> August 30, 2006</sub></p>
]]></content:encoded>
			<wfw:commentRss>http://forms.stefcameron.com/2006/06/10/acroform-objects/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
	</channel>
</rss>

