Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events

Help with instancemanager.count to reference last field of repeated, nested subform?

Avatar

Level 2

I'm attempting to use instanceManager.count to get livecycle to tell me the last instance of a particular field inside of the last instance of a particular recurring subform.

hierarchy:
Table 1 (Tbl1SF)
-subform (Tbl1SSF)  This subform is a repeatable row inside of Tbl1SF.  When a new instance of Tbl1SSF is created, a second instance of another entity,
Table 2 (Table2SF) is created.  In this form, another row is repeatable,
-subform (Table2SF2)  In this row, exists a field that I want to run some code once the user has entered data in the final instance of it.  This field is called engArch.


I've tried writing and debugging the code in a lot of different ways, but I can't seem to figure out the syntax for referencing this.  I also haven't been able to find any sample code that will do this.

What's the correct JavaScript syntax?

form1.Table2SF[ + form1.Table2SF.instanceManager.count + ].Table2SF2[ + form1.Table2SF2.instanceManager.count + ].engArch

9 Replies

Avatar

Level 10

Hi,

It is a bit difficult to see what is going on without the form. If you can post it onto a file sharing site, it would help.

For something like this I would recommend setting a variable to the instance count and then using  that variable in the script. Also you can use a debug line and the Javascript Console (Control + J when previewing) to check that the variable is correct:

var vTable2SF = form1.Table2SF.instanceManager.count;

var vTable2SF2 = form1.Table2SF2.instanceManager.count;

console.println("Table2SF: " + vTable2SF);

Once you have the instance count, you can then reference that instance. However you have to resolve the node first:

var part1 = xfa.resolveNode("form1.Table2SF[" + vTable2SF "]");

var part2 = xfa.resolveNode("form1.Table2SF2[" + vTable2SF2 "]");

... part1.part2.engArch;

You may need to resolve the node when combining part1.part2.engArch.

Hopefully that will get you started,

Niall

Avatar

Former Community Member

Also remember that the count is giving you back a 1 based value but the instance index is 0 based.

Paul

Avatar

Level 2

Thanks for getting me started - I was wondering if I needed to start declaring variables to get this working.

The code you wrote has me thinking this needs to go in the event I'm scripting rather than using the UI to declare variables in the hierarchy (I tried that first and was unable to set the variables)

So here's what I have so far for the Exit event for the field engArch - my variable is coming back undefined and I'm having trouble seeing why:

form1.Table2SF.Table2SF2.engArch::exit - (JavaScript, client)

var vTable2SF = form1.Table2SF.instanceManager.count;

xfa.host.messageBox("vTable2SF: " + vTable2SF.value, "Debugging", 3);

The messagebox comes back with: vTable2SF: undefined

Avatar

Level 10

Hi,

The "vTable2SF" variable you are declaring is a script variable, so you don't need the .value after the variable name.

So just drop the .value and it should work.

Bear in mind Paul's catch on the zero based instances of the subform.

N.

Avatar

Level 2

I have more questions.. I'm really wanting to find a good resource to learn how the instanceManager works and how resolveNode works.  I've read all the help files I can find in LiveCycle, I've been googling and reading as much as I can, and I've logged into safaribooks and flipped through a couple of the books on there - nothing seems to explain how to use these in the way I need to use them.

I'm tackling a different piece of my project (I solved the question I had above in a different, easier way) but I need to use the same concepts suggested to achieve the desired result.  Here's what I'm dealing with now:

Tbl1 is a subform which contains the repeatable row, Tbl1SSF. A field in the repeatable row, Tbl1Sites, is a numeric user-entered field which determines the number of times a different page in the form repeats. I'm setting variables, but I don't understand the type of data that resolveNode returns.  I don't know how to use it correctly - I had it in a debug messageBox and it was returning "xfaObject" instead of a value.

Here's the code I have so far for the "exit" event of the Tbl1Sites field.  I've been unable to find anything that explains how the setInstances works, but I'm hoping that's what I need to use in order to get the desired subform to repeat the desired number of times.

form1.Table1.Tbl1SF.Tbl1SSF.Tbl1Sites::exit - (JavaScript, client)

var vSites = this.rawValue;

var vThisInstance = this.parent.index;

var part1 = xfa.resolveNode("form1.DescripNeedByPjt["+vThisInstance+"]");

xfa.host.messageBox("Variables: " + vSites + "  " + vThisInstance, "Debugging", 3);

part1.instanceManager.setInstances(vSites);

Once these are added, I'll also need to remove them if the remove button is clicked.

Avatar

Level 10

Hi,

The error is that you are referencing the object and not the value in the object. When you resolve a node, you are just specifically telling Acrobat which instance you are referring to. When you assign the resolved node to a variable, then using that variable is exactly the same as giving the ful SOM of the original object. Using resolveNode is intended to make this easier (and more efficient), because you resolve the particular instance once and then can use that variable several times.

An extract from your script would look like this.

var part1 = xfa.resolveNode("form1.DescripNeedByPjt["+vThisInstance+"]");

I am not sure what 'DescripNeedByPjt' is! If it is a repeating row/subform, then it does not necessarily contain a value (objects within it may contains values). However on the other hand if it is an object, then it can contain a value, so the declaration of the variable could look like this:

var part1 = xfa.resolveNode("form1.DescripNeedByPjt["+vThisInstance+"]").rawValue;

Here are a list of 'things' that can hold values and how to access them:

ThingHow to access the value inside the thing

Object

Textfield/NumericField

Use .rawValue after the SOM reference

Global variable

Specified in the File > Form Properties > Variables

Use .value after the global variable name

Script variable

Declared and assigned a value within the script: var i = 0;

Just use the name of the script variable: i

Script variable for a resolved node

When using a variable to store a repeating object

Use the property of the original object, you want to reference: .rawValue

Another good debugging tool is to use the JavaScript Console (press Control+J when previewing or in Acrobat). Then you can put a line like this into the script:

console.println("vThisInstance: " + vThisInstance); // this will return "vThisInstance: 4" or whatever the index is.

It does this because the variable just contains a number (index).

Lastly, the SOM does not look correct for "form1.DescripNeedByPjt", as your form appears to have multiple subforms. You should give the fully reference.

Here are some resources that you might find helpful:

http://www.adobe.com/go/learn_lc_scriptingBasics

http://www.adobe.com/go/learn_lc_scriptingReference

http://www.adobe.com/go/learn_lc_formCalc

http://www.adobe.com/devnet/livecycle/articles/Adobe_XML_Form_Object_Model_Refer ence.pdf

http://www.adobe.com/devnet/acrobat/pdfs/lc_migrating_acrobat_xmlform.pdf

And a very handy resource (and while it is for version 6 it is still very good because of the way it is laid out):http://partners.adobe.com/public/developer/en/tips/CalcScripts.pdf

Also JP Terry's book on LC Designer Forms is very good.

Good luck,

Niall

Avatar

Level 2

Hi Niall,

Thanks so much for your help so far.  Last night I realized what I need now is a variable that I can set in one field and reference it in another field -I'm pulling a project number, activity code, and a project title from each row in table 1 into a concatenated field in form1.DescripNeedByPjt (it's a subform that spans two pages and repeats based on the value in the Tbl1Sites field.

I tried setting a global variable, gThisInstance, which I set to 0, thinking I could set it to this.parent.index when I want to capture the current instance.  Then I was thinking I could reference it in order to pull the correct fields from table 1 in DescripNeedByPjt.

What's happening is that gThisInstance continues to be 0 even when this.parent.index increments.  How can I assign a value to gThisInstance using scripting?

Code:

form1.Table1.Tbl1SF.Tbl1SSF.Tbl1Sites::exit - (JavaScript, client)
gThisInstance.value = this.parent.index;
var vSites = this.rawValue;
var vThisInstance = this.parent.index;
var part1 = xfa.resolveNode("form1.DescripNeedByPjt["+vThisInstance+"]");

xfa.host.messageBox("The global variable is: " + gThisInstance.value, "Debugging", 3);
xfa.host.messageBox("The local variable is: " + vThisInstance, "Debugging", 3);
//xfa.host.messageBox("This parent is: " + this.parent.name, "Debugging", 3);
//xfa.host.messageBox("Variables: " + vSites + "  " + vThisInstance, "Debugging", 3);
part1.instanceManager.setInstances(vSites);

--

form1.DescripNeedByPjt.TextField32::calculate - (JavaScript, client)
var vSiteInstance = this.parent.index + 1;
var part1 = xfa.resolveNode("form1.DescripNeedByPjt["+vSiteInstance+"]");

// xfa.host.messageBox("vSiteInstance: " + vSiteInstance, "Debugging", 3);
//xfa.host.messageBox("This parent is:" + this.parent.name, "Debugging", 3);
xfa.host.messageBox("The project # is:" + form1.Table1.Tbl1SF.Tbl1SSF[gThisInstance].Tbl1ProjectNum.rawValue, "Debugging", 3);

this.rawValue=(
String.concat("  Site #", vSiteInstance));
// "Project #",
// form1.Table1.Tbl1SF.Tbl1SSF[gThisInstance.value].Tbl1ProjectNum.rawValue,
// "   ",
// form1.Table1.Tbl1SF.Tbl1SSF[gThisInstance.value].Tbl1Title.rawValue,
// "  Activity #",
// form1.Table1.Tbl1SF.Tbl1SSF[gThisInstance.value].Tbl1Activity.rawValue


// use resolveNode to place the correct data from table 1 into each instance of this page.

1) Is this possible?
2) Is this the correct approach?

Thanks again for your help

Avatar

Level 10

Hi,

I am out of the office until later tonight, so won't be able to look at this

until then.

However it would be really helpful if I could see the form, as I am running

a bit blind.

If you send a private message to me, I can give you an email address.

Alternatively you can post on Acrobat.com or another file sharing site.

Thanks,

Niall

Avatar

Level 10

Hi,

When you declare a global variable (from File > Form Properties > Variables) you can access its value and set its value using the ".value" property. So in your case.

gThisInstance.value;

It is important that you have the form set to automatically save script changes (see File > Form properties > Defaults). Although my experience is that global variable tend to default to their original value when the form is reopened.

Now you seem to have the global variable buried deep within your form structure. This can make it difficult to reference. I would recommend that the global variables be off the root node, so that it can be accessed from anywhere within the form.

What you are trying to achieve is, I believe, possible. But it is difficult to work through the involved form structure/script without seeing the form.

Niall