Expand my Community achievements bar.

SOLVED

Building and Reading MultiDemensional Array

Avatar

Level 7

I have a form where there are multiple intstances of tableRows inside a Repeating Subform.

Subform[*]

     ..TableRow[*]

I want to devise a way to round up all the information contained in fields in the TableRows and populate other fields with some of that data, in a different subform, in a different part of the form.

I want to populate the fields by clicking on a button and with each click, a different record set populates the fields. So the user is in effect, scrolling through the possibilities, and the user stops clicking when they see the record set they want to use populating the fields. It is very unlikely that there will be more than 5 or 6 records, and more likely it will be 2 or 3 record sets (clicks). This just eliminates the user from having to re-enter data that will be located in a different part of the form.

I have written JavaScript and FormCalc scripts that don't function according to plan. I am getting the following:

Error: missing or illegal parameter(s)

////////////////////////////////////ALL ON THE CLICK EVENT OF A BUTTON'

var RVdetails
var yearTxt       =    ""
var makeTxt    =    ""
var modelTxt    =    ""
var engineTxt   =    ""
var SerNoTxt    =    ""
var k = 0

//with each click of the button

//for each of the subforms
//for each line in each subform

//using the 5 textfields in the

//build a multi-demensional array using k as the 1st index

var IMsubforms    =    SubformPropCoverages.SubformInlandMarine[*]

     for i = 0 upto Count(IMsubforms) step 1 do
          var IMsubFields    =    SubformPropCoverages.SubformInlandMarine[i].SubformRVDesc.TableRVDetails.RowRVDetails[*]   
               for j = 0 upto Count(IMsubFields) step 1 do
                    yearTxt            =    SubformPropCoverages.SubformInlandMarine[i].SubformRVDesc.TableRVDetails.RowRVDetails[j].TxtYear 

                    makeTxt          =    SubformPropCoverages.SubformInlandMarine[i].SubformRVDesc.TableRVDetails.RowRVDetails[j].TxtMake

                    modelTxt         =    SubformPropCoverages.SubformInlandMarine[i].SubformRVDesc.TableRVDetails.RowRVDetails[j].TxtModel

                    engineTxt        =    SubformPropCoverages.SubformInlandMarine[i].SubformRVDesc.TableRVDetails.RowRVDetails[j].TxtEngine

                    SerNoTxt         =    SubformPropCoverages.SubformInlandMarine[i].SubformRVDesc.TableRVDetails.RowRVDetails[j].TxtSerialNum

                    RVdetails[k]    =    Ref(yearTxt,makeTxt,modelTxt,engineTxt,SerNoTxt)                                                 

                    k = k + 1
                    continue

               endfor

               continue 

          endfor

//also  with each click of the button, using the global variable to keep  track of where you're at between clicks,

//step through the array and fill these fields in the same row as the  button

//with values from the array

//the user stops clicking when they see the fields populated with the  values they are looking for

        if    (clickRV.value < k )    then
            TxtYear                 = RVdetails[clickRV.value][0]
            TxtMake                = RVdetails[clickRV.value][1]
            TxtModel               = RVdetails[clickRV.value][2]
            TxtEngine              = RVdetails[clickRV.value][3]
            TxtSerialNum         = RVdetails[clickRV.value][4]
            clickRV.value         = clickRV.value + 1
        else                                           
            clickRV.value         = "0"  //the global resets to 0 when it reaches the max k
            TxtYear                 = ""
            TxtMake               = ""
            TxtModel              = ""
            TxtEngine             = ""
            TxtSerialNum         = ""
        endif

/////////////////////////////////////////////////////////////////////////////////

Any and all advice is very much appreciated!

Thanks,

Stephen

1 Accepted Solution

Avatar

Correct answer by
Former Community Member

Yes that is correct but remember that if you have an expression that has [i] javascript will not resolve the i that is why you need to build it using a string syntax like xfa.resolveNode.

Paul

View solution in original post

8 Replies

Avatar

Former Community Member

You thought process is correct buut your implementation is flawed. When trying to build an expre

ssion to represent the objects in the table you cannot use an instance like [i] as the expre

ssion will not get resolved before the command is executed hence the object will not exist. If you have a definiative instance like

[2] then it wil work fine. To get around this you can use the xfa.resolveNode syntax to pass a string that represents the object then it will be able to find it. So to access one of those objects the command woudl be:

xfa.resolveNode("SubformPropCoverages.SubformInlandMarine[" + i " ].SubformRVDesc.TableRVDetails.RowRVD etails[" + j + "]").TxtYear.rawValue

Also note that the * will not work in javascript. You will have to get a length then put it in a for loop to get all instances.

Hope that helps

Paul

Avatar

Level 7

Thank you, Paul.

I first started using JavaScript and the resolveNodes method with .length, and made several attempts without success (likely for the reasons you cite here). I then rewrote the script in formCalc with and without resolveNodes to see if I would have any better luck (especially since formCalc allows [*]).

I will utilize your very much appreciated suggestions and construct a new script and report back the results.

Just one more thing:

I struggle with understanding [" + n " ] and [" + n + "]

I had received some very helpful advice here last Fall, where [" + n + "] was part of the solution to my problem, not unlike the problem now. I implemented the suggestion and it worked perfectly, however, I don't understand it. And, searching here, Google, references, etc. yields nothing informative. Are you able to explain this expression or point me to a reference where it is explained? If I had a clear understanding of what  [" + n + "] represents, it will help me moving forward.

Thank you, again, Paul, for your help,

Best,

Stephen

Avatar

Former Community Member

The xfa.resolveNode accepts a string that represents the objects Som Expression. So we are simply building a string to represent

that expression. Ultimately we want an expression in the form objectname[occurancenumber].rawValue So the expression "...[" + i + "]......" is simply building the string to fit the expression.

Make sense?

Paul

Avatar

Level 7

Paul,

I think I might understand. Is this correct?

  • What is needed is a string
  • The way to build strings in javascript, uses the + operator
  • Surrounding the i with + operator and putting it in quotes, converts i to a string?

If my understanding is correct, then (and this is just me being curious) does [String(i)] also work?

I think this will help me with another part of this button problem that I have put aside. Ultimately, I want to also show the value k + 1 as the caption on the button, so the button caption changes with each click. If my understanding is correct. I should be able to implement that part, now, as well.

Please advise if I understand the problem correctly,

Thanks,

Stephen

Avatar

Former Community Member

Not quite  ....the way to concatinate strings is with the + ....you do not have to turn the i into a string as variables are represented as strings unless otherwise specified.

Yes the k+1 will work ...I do that all of the time.

Paul

Avatar

Level 7

OK, Paul

I really want to understand this--and I very, very much appreciate your help. Do I understand this correctly?:

[" + i + "]

It is just a way to express [i] that is  compatible with resolveNode().

In other scenerios, like referencing an element of an array, [i] or [i + 1] works just fine, right?

Thanks again,

Stephen

Avatar

Correct answer by
Former Community Member

Yes that is correct but remember that if you have an expression that has [i] javascript will not resolve the i that is why you need to build it using a string syntax like xfa.resolveNode.

Paul

Avatar

Former Community Member

Also try all.item(i) instead of all that string referencing.

For instance:

xfa.resolveNode("SubformPropCoverages.SubformInlandMarine[" + i + "].SubformRVDesc.TableRVDetails.RowRVD etails[" + j + "]").TxtYear.rawValue

can be

SubformPropCoverages.SubformInlandMarine.all.item(i).SubformRVDesc.TableRVDetails.RowRVD etails.all.item(j).TxtYear.rawValue;

Never tried it multi-dimensionally like that but just thought I'd put it out there.

Kyle

The following has evaluated to null or missing: ==> liqladmin("SELECT id, value FROM metrics WHERE id = 'net_accepted_solutions' and user.id = '${acceptedAnswer.author.id}'").data.items [in template "analytics-container" at line 83, column 41] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign answerAuthorNetSolutions = li... [in template "analytics-container" at line 83, column 5] ----