B4J Question Can you loop through a collection of form objects?

TorontoJim

Member
Licensed User
Longtime User
I would like to be able to iterate through a collection of form objects based on their name. Alternatively, can you refer to a form object by a variable name?

For example, instead of:

B4X:
doSomething(txtField1.Text)
doSomething(txtField2.Text)
doSomething(txtField3.Text)
doSomething(txtField4.Text)

Is it possible to do either of these:

B4X:
#Option 1
for i = 1 to 4
    doSomething("txtField" & i & ".Text")
next

#Option 2
Dim txtMap as Map
txtMap.Put("txtField1")
txtMap.Put("txtField2")
txtMap.Put("txtField3")
txtMap.Put("txtField4")
for i = 1 to 4
    doSomething(niftyObjectSyntax(txtMap.Get(i)).Text)
Next

The app I'm working on iterates through the same objects in several different places. I'm just trying to make the code more compact and have less typing.
 

Daestrum

Expert
Licensed User
Longtime User
On your second option it should work if you put the actual object in a list
Then just iterate through the list
B4X:
Dim lis as List
lis.Initialize
...
lis.Add(textfield1)   '  actual object not the string name
...

for each item as Object in lis    '  Object could be TextField if they are all TextFields
    doSomething(item)
next
...
' or as your example
for each item as TextField in lis
   doSomething(item.Text)
next
 
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
If you use the Object version, I don't think I explained clearly.
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim t As TextField
    Dim lis As List
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.SetFormStyle("UNIFIED")
    MainForm.Show
    t.Initialize("")    ' initialize the textfield
    t.Text = "freddy" ' set the text of the textfield
    lis.Initialize ' initialize the list
    lis.Add(t)        ' add the textfield to the list
    For Each item As Object In lis
        doSomething(item) 
    Next
End Sub
Sub doSomething(tt As TextField)  ' the Object will become a TextField here
    Log(tt.Text) 
End Sub

If you use Object be careful to only add TextFields to the list as it will fail when it gets to doSomething sub.

It will be safer to use
B4X:
For Each item As TextField In lis
As this will fail if it encounters anything but a TextField in the list.
 
Last edited:
Upvote 0

TorontoJim

Member
Licensed User
Longtime User
Awesome, works great. One more thing. Do you know how to get the NAME of the object?

I tried tt.Name but that is invalid.

I tried tt.Id, but duhhhh, I never set an Id. I'd prefer not to.

I've tried to find a way to read the object as a string (to get the name) while leaving it as an object. Still can't figure that one out.

The looping part, awesome.
 
Upvote 0

TorontoJim

Member
Licensed User
Longtime User
I came up with a solution for my issue. I create a map with the name of the object as the key, as a string. The value was the object itself. It let me iterate thorugh the list of keys and use Daestrom's example to create read/set subroutines to extract or assign the values to the form text boxes, and to labels (different subs for the labels).
 
Upvote 0
Top