Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

Tab order problem

Avatar

Level 3

Hi,

Can some one please help me in Tab order issue,

Form has designed in following way.

Header and fooetr are designed in master page and Body section is designed on Page(ex:Page1).

The Taborder would be Header, Body and Footer. but  First its going to header section after that footer part and last to Body section.

Any ideas would be great.

Thank you,

Jay

1 Accepted Solution

Avatar

Correct answer by
Level 10

Hi Jay,

The tabbing order is specified by a traversal element when looking at the XML Source of your form, there will be one in the field/subform pointing to the next in the tab sequence.  I sometimes find I get things so mucked up that I am better going though and deleting them all and starting again.  With no traversal elements the tab order defaults to the next field which is usually what I want anyway.  This is a macro that will do just that.

function dbg(msg) {
    designer.println(msg.replace(/[\n]/gm, "\r\n") + "\r\n");
}

function contextString(node) {
    var context = node.somExpression;
    context = context.replace(/xfa\[0\]\.template\[0\]\./, '');
    context = context.replace(/\[0\]/g, '');
    return context;
}

function processTemplate(element) {
    var count = 0;

    var elementNodes = element.nodes;
    for (var i = 0; i < elementNodes.length; i++) {
        var childElement = elementNodes.item(i);
        sClassName = childElement.className;

        //dbg("element " + childElement.name + " " + childElement.className + " isContainer=" + childElement.isContainer);
        if (childElement.className === "traversal") {
            childElement.parent.nodes.remove(childElement);
            count++;
        }
        else {
            if (childElement.isContainer ||
       childElement.className === "calculate" ||
       childElement.className === "validate" ||
       childElement.className === "breakAfter" ||
       childElement.className === "breakBefore" ||
       childElement.className === "event" ||
       childElement.className === "proto" ||
       childElement.className === "script" ||
       childElement.className === "traversal" ||
       childElement.className === "traverse" &&
       childElement.className !== "variables") {
                count += processTemplate(childElement);
            }
        }
    }
    return count;
}

try {
    var nStart = (new Date()).getTime();
    var count = processTemplate(xfa.template);
    var nEnd = (new Date()).getTime();
    dbg("Removed " + count.toString() + " traversal elements");
    dbg("elapsed: " + (nEnd - nStart).toString() + " m/s");
}
catch (e) {
    dbg(e.message + "\nat:" + e.line + "\nsource:" + e.source.split("\n")[e.line - 1]);
}

There is more on macros (including how to run them) here, http://blogs.adobe.com/formfeed/2010/01/designer_es2_macros.html.

Regards

Bruce

View solution in original post

6 Replies

Avatar

Correct answer by
Level 10

Hi Jay,

The tabbing order is specified by a traversal element when looking at the XML Source of your form, there will be one in the field/subform pointing to the next in the tab sequence.  I sometimes find I get things so mucked up that I am better going though and deleting them all and starting again.  With no traversal elements the tab order defaults to the next field which is usually what I want anyway.  This is a macro that will do just that.

function dbg(msg) {
    designer.println(msg.replace(/[\n]/gm, "\r\n") + "\r\n");
}

function contextString(node) {
    var context = node.somExpression;
    context = context.replace(/xfa\[0\]\.template\[0\]\./, '');
    context = context.replace(/\[0\]/g, '');
    return context;
}

function processTemplate(element) {
    var count = 0;

    var elementNodes = element.nodes;
    for (var i = 0; i < elementNodes.length; i++) {
        var childElement = elementNodes.item(i);
        sClassName = childElement.className;

        //dbg("element " + childElement.name + " " + childElement.className + " isContainer=" + childElement.isContainer);
        if (childElement.className === "traversal") {
            childElement.parent.nodes.remove(childElement);
            count++;
        }
        else {
            if (childElement.isContainer ||
       childElement.className === "calculate" ||
       childElement.className === "validate" ||
       childElement.className === "breakAfter" ||
       childElement.className === "breakBefore" ||
       childElement.className === "event" ||
       childElement.className === "proto" ||
       childElement.className === "script" ||
       childElement.className === "traversal" ||
       childElement.className === "traverse" &&
       childElement.className !== "variables") {
                count += processTemplate(childElement);
            }
        }
    }
    return count;
}

try {
    var nStart = (new Date()).getTime();
    var count = processTemplate(xfa.template);
    var nEnd = (new Date()).getTime();
    dbg("Removed " + count.toString() + " traversal elements");
    dbg("elapsed: " + (nEnd - nStart).toString() + " m/s");
}
catch (e) {
    dbg(e.message + "\nat:" + e.line + "\nsource:" + e.source.split("\n")[e.line - 1]);
}

There is more on macros (including how to run them) here, http://blogs.adobe.com/formfeed/2010/01/designer_es2_macros.html.

Regards

Bruce

Avatar

Level 3

Thank you Bruce,

Do you have any sample or example form with implementation of this macro.

Thank you,

Jay

Avatar

Level 10

Hi Jay,  There are better instructions on the link I gave, but basically you create a directory under the Scripts directory of the LiveCycle Designer install, and save the code above as a .js file.  So on my system I have C:\Program Files (x86)\Adobe\Adobe LiveCycle Designer ES2\Scripts\Macros\RemoveTraversals.js.

Once created then restart Designer and you will have a new option under the Tools ... Scripts menu called RemoveTraversals.js.  Click on this option and the code will be executed against the currently loaded form. 

Bruce

Avatar

Level 8

Hey Bruce,

I didn't think you could tab between masterpage objects and page objects. In the tab order pallette the masterpage objects are always stuck together not allowing for page objects in between. Even manually editing the masterpage object's traversal element doesn't seam to help. Any thoughts?

Oh and thanks for the macro.

Kyle

Avatar

Level 3

Thanks a lot Bruce,

It's very helpful...

Regards,

Jay

Avatar

Level 10

Hi Kyle,

I hadn't come across that restriction, the only tabbing I've done with master pages is a field on the footer, outside the master page content area and that just seems to default to the correct order.  I see what you mean now about the way fields are grouped in the tab order pallette, but you might be able to get some tab order working if you can structure your master page so it contains multiple content areas, this example seems to work correctly.  So it seems to default to all the master pages fields before the content area, then all the fields in the content area, then any fields after the content area, then all the fields in the second content area, etc.

Bruce

MasterPageTabOrder.PNG