Author Archive: Mike Bessuille

Script Dependencies and "recalculate()"

For older versions of Acrobat, there were a lot of forms which would call xfa.form.recalculate() in various places.  This was to ensure that fields will get updated which depend on other fields that may have changed.  Newer versions of Acrobat (8.1 and higher) are designed to not require so many calls to recalculate(), because the system is smart enough to evaluate your calculate script and figure out what fields it depends on.  The system puts "listeners" on those other fields so that whenever they change, my calculate script gets called automatically.  I don’t have to declare the dependency.

For example, I have a Total field that calculates its value from several other fields (Field1, Field2, Field3).   Any time Field2 changes (due to either a calculation or to the user typing something in Field2), the Total calculate script will be called automatically.

But now make this dynamic:  add a repeating subform with Add and Remove buttons so the user can create new instances of the subform.  For example, I have a repeating subform containing a Weight field.  Outside the repeating subform, a Total field has a calculate script which sums up all the instances of that Weight field.  Pretty simple.  

clip_image001

But the listeners aren’t correctly added when a new subform instance is created.  My Totals field is listening to the first instance of RepeatingSubform[0].Weight, but when RepeatingSubform [1] is created, Totals isn’t listening to changes to RepeatingSubform [1].Weight.  Stefan Cameron talks about this in an older blog post:  http://forms.stefcameron.com/2006/05/20/add-recalculate/

Interestingly, look at the calculate script on Total:

var sum = 0;

var columnArray = xfa.resolveNodes( "RepeatingSubform1[*].Weight1");

for( var i = 0; i<columnArray.length; i++)

{

    sum += columnArray.item(i).rawValue;

}

this.rawValue = sum;

The call to xfa.resolveNodes() happens to cause the listeners to be updated!  This leads to very odd behavior:  if I change RepeatingSubform [1].Weight, it won’t update Totals, until I change RepeatingSubform[0].Weight.  Then any additional Weight field changes will cause Total to update correctly!

So if I start with one weight field (W0) and add 3 more, I end up with weight fields like this:

                W0 (RepeatingSubform[0].Weight)

                W1

                W2

                W3

                Total

Then changes to the added ones (W1, W2, W3) won’t update the Total – yet.  Changing W0 will update the total, and once you do that, now changes to W1, W2,W3 will work!

Then if I add a W4:

                W0

                W1

                W2

                W3

                W4

                Total

Now changes to W0, W1, W2, W3 will all continue to work but my newly-added W4 won’t work (until I change one of W0-W3).

Workaround:

Add script to the indexChange event of RepeatingSubform, which will take care of all newly-added instances; Totals will be recalculated and will now be "listening to" the new instances.  This is more efficient than calling recalculate() on the entire form – it just recalculates that particular field or subform.

Total.execCalculate();   // Note: you can call this on a subform too:  TotalsSubform.execCalculate();

Add the same script to the delete button click() event so that the Total is recalculated when an instance is deleted.  The important part of that code is:

TotalsSubform.execCalculate();  // this avoids having to call the entire form’s recalculate() method.

oTargetSubform.instanceManager.removeInstance(oTargetSubform.index);

Continue reading…

Welcome to Designer Exposed

Welcome to the LiveCycle Designer Team’s “team blog”. A place where we’ll post useful tips on how to use Designer, in-depth articles about new features, etc. We hope this will enhance the user forums (at www.adobeforums.com) and gives our developers an opportunity to provide “from the trenches” information about the product.

While we plan to post articles here, please continue to use the Forums for questions (and for suggestions about future topics for this blog). When we post an article here, we’ll link to it from any relevant questions in the Forum.

LiveCycle Designer Team