Search This Blog

Friday, 11 July 2014

Yet another way of looping though a list of form nodes

SpiderMonkey JavaScript 1.7 (the JavaScript engine used in Firefox and Adobe Reader) introduced an Iterator extension.  This is not available in other browsers but we don't need to worry about that.  With a custom Iterator we can loop though form nodes using for ... in statement;


for (var field in XFAUtil.NodeIterator(NumericField))
{
    console.println(field.somExpression + " has a value of " + field.rawValue);
}

An iterator is used by assigning a generator function to the __iterator__ method, so the NodeIterator object used above looks like;

function NodeIterator(node)
{
    var nodeList = node.parent.resolveNodes(node.name + "[*]");
    var limit = nodeList.length;
    var current = 0;
    return {
        __iterator__ : function ()
        {
            return {
                next : function ()
                {
                    if (current >= limit) throw StopIteration;
                    return nodeList.item(current++);
                }
            }
        }
    }
}

The problem with this is the StopIteration exception gets thrown when we get to the end of the list. This probably won't be a problem for the end user but is a pain for the developers who will typically have the "When exception thrown" option set to break.

We can hide this by adding a forEach method similar to the one available for an array.  For example to sum the values of an array we can do;

var total = 0;
[1,2,3,4].forEach(function(v) { total += v; });
console.println(total); // prints 10 

Similarly we can now sum up all the values of all the numeric fields called NumericField using;

var total = 0;
XFAUtil.NodeIterator(NumericField).forEach(function(v) { total += v.rawValue; });
total;


Or process all the fields of the same type using the NodeClassIterator

var total = 0;
XFAUtil.NodeClassIterator(CheckBox1).forEach(function(v) { if (v.rawValue === 1) total++; });
MessageText.presence = (total >= 2) ? "hidden" : "visible"

It may still be better to use the good old for loop, the main advantage of using this technic is it hide some of the XFA stuff.  But maybe if you have some rule regarding all rows with a a quantity value greater than 100 then it would be good to put this logic in the one place.

Here's a sample form using the approach, CustomIterator.pdf.

Thursday, 3 July 2014

Adobe LiveCycle Designer Tip #5 - Palette Control

Designer has 16 different palettes, a design surface and a script editor window.  In an ideal world we would have two screens so we can spread them all out.

For those of us with only one screen moving from palette to palette can be a pain.  If you have them docked at the sides then you'll need to click the 'thumb' controls to expand, which I find a bit of a small target to click on.


What I find easier is to have the palettes in one palette window.  I have the Hierarchy, Data View, Style Catalog, Info, Font, Paragraph, Drawing Aids, Style Catalog on the left and Object, Layout, Border, Accessibility, Object Library, Fragment Library on the right.

To drag a palette onto another palette window drag the palette tab (not the palette title bar) on top of the target palette.


You can then end up with a layout looking like;



Which gives me a bigger target to click on.